<?php
/**
 * 考试-试卷分类表
 * @author: houyingcai
 * @email:    594609175@qq.com
 * @date :  2017-05-19 17:45:03
 * @version $Id$
 */

namespace Common\Service;

use Com\Validate;
use Common\Model\CategoryModel;
use Common\Model\PaperModel;

class CategoryService extends AbstractService
{
    /** @var PaperModel */
    protected $_d_paper;

    // 构造方法
    public function __construct()
    {
        $this->_d = new CategoryModel();

        // 初始化试卷表
        $this->_d_paper = new PaperModel();

        parent::__construct();
    }

    /**
     * 【后台】添加分类验证
     *
     * @author: 何岳龙
     * @param array $params POST请求参数
     * @param bool $type true 添加 false 编辑
     * @return array
     */
    public function cate_validation($params = [], $type = true)
    {
        // 组装分类表数据
        $cate_data = [
            'ec_name' => $params['ec_name'],
            'ec_desc' => strval($params['ec_desc']),
            'ec_status' => $params['ec_status'],
            'order_num' => 0
        ];

        // 验证规则
        $rules = [
            'ec_name' => 'require|min:2|max:20',
            'ec_status' => 'require|in:0,1'
        ];

        // 错误提示
        $message = [
            'ec_name' => L('_ERR_CATE_NAME_FONT_LENGTH'),
            'ec_status' => L('_ERR_CATE_STATUS')
        ];

        // 开始验证
        $validate = new Validate($rules, $message);
        if (!$validate->check($params)) {

            E($validate->getError());
        }
        if ($type == true) {
            // 添加验证
            // 如果分类名不能重复
            if (!empty($params['ec_name'])) {
                // 获取当前分类名称个数
                $total = $this->_d->count_by_conds(['ec_name' => $params['ec_name']]);
                // 如果存在相同名称的分类
                if (!empty($total)) {

                    E('_ERR_CATE_NAME_REPEAT');
                }
            }
        } else {
            // 编辑验证
            if (empty($params['ec_id'])) {
                // 验证分类ID是否为空
                E('_EMPTY_CATE_ID');
            }

            // 如果分类名不能重复
            if (!empty($params['ec_name'])) {
                // 获取当前分类名称个数
                $info = $this->_d->get_by_conds(['ec_name' => $params['ec_name']]);
                // 如果存在相同名称的分类
                if (!empty($info['ec_id']) && $info['ec_id'] != $params['ec_id']) {

                    E('_ERR_CATE_NAME_REPEAT');
                }
            }
        }

        return $cate_data;
    }


    /**
     * 分类数据格式化
     * @author: 蔡建华
     *
     * @param array $data
     *
     * @return array
     */
    public function format_category($data = [])
    {
        if ($data) {
            foreach ($data as $key => $value) {
                $value['ec_id'] = intval($value['ec_id']);
                $data[$key] = $value;
            }
        }

        return $data;
    }

    /**
     * 【后台】批量排序分类验证 何岳龙
     *
     * @param array $params POST请求参数
     *
     * @return bool
     */
    public function order_cate_validation($params = [])
    {
        // 参数不能为空
        if (empty($params['list']) || !is_array($params['list'])) {

            E('_EMPTY_CATE_DATA');
        }
        // 遍历验证数据
        foreach ($params['list'] as $key => $v) {

            // 如果ID为空或者不是数据
            if (empty($v['ec_id']) || !is_numeric($v['ec_id'])) {

                E('_ERR_CATE_ORDER_ID');
            }

            // 如果order_num为空或者不是数据
            if (empty($v['order_num']) || !is_numeric($v['order_num'])) {

                E('_ERR_CATE_ORDER_NUM');
            }
        }
        return true;
    }

    /**
     * 【后台】分类批量排序
     *
     * @param array $params POST请求参数
     *
     * @return bool
     */
    public function order_cate($params = [])
    {
        try {
            $this->start_trans();
            // 遍历验证数据
            foreach ($params['list'] as $key => $v) {
                $this->update_by_conds(
                    ['ec_id' => $v['ec_id']],
                    ['order_num' => $v['order_num']]
                );
            }

            $this->commit();
        } catch (\Think\Exception $e) {
            \Think\Log::record($e);
            // 事务回滚
            $this->_set_error($e->getMessage(), $e->getCode());
            $this->rollback();
            return false;
        } catch (\Exception $e) {

            \Think\Log::record($e);
            $this->_set_error($e->getMessage(), $e->getCode());
            // 事务回滚
            $this->rollback();
            return false;
        }

        return true;
    }

    /**
     * 【后台】验证删除分类
     *
     * @author: 何岳龙
     * @param array $params POST请求参数
     *
     * @return bool
     */
    public function delete_cate_validation($params = [])
    {

        // 分类ID不能为空
        if (empty($params['ec_id'])) {
            E('_EMPTY_CATE_ID');
        }

        // 查询条件
        $conditions = [
            'ec_id' => $params['ec_id'],
            'exam_status > ?' => self::STATUS_INIT
        ];

        // 查看当前分类是否使用
        $total = $this->_d_paper->count_by_conds($conditions);

        // 如果有数据
        if (!empty($total)) {

            E('_ERR_CATE_ID_PAPER');
        }

        // 删除分类
        return $this->_d->delete($params['ec_id']);

    }

    /**
     * 【后台】详情验证
     *
     * @author: 何岳龙
     * @param array $params POST 请求参数
     *
     * @return bool
     */
    public function info_cate_validation($params = [])
    {
        // 分类ID不能为空
        if (empty($params['ec_id'])) {
            E('_EMPTY_CATE_ID');
        }

        // 查看当前分类是否使用
        $info = $this->_d->get($params['ec_id']);

        // 如果没有数据
        if (empty($info)) {
            E('_EMPTY_CATE_INFO');
        }

        return true;
    }

    /**
     * 【后台】详情验证
     *
     * @author: 何岳龙
     * @param array $params POST请求参数
     *
     * @return array
     */
    public function get_cate_info($params = [])
    {
        // 获取详情
        $info = $this->_d->get($params['ec_id']);

        // 获取权限信息
        $data = [
            'ec_name' => strval($info['ec_name']),
            'ec_status' => intval($info['ec_status']),
            'ec_desc' => strval($info['ec_desc'])
        ];

        return $data;
    }

    /**
     * 根据层级格式化分类数据
     * @author pw
     * @param array $list 分类数据
     * @param int $parentId 父ID
     * @return array 格式化后的数据
     */
    public function formatClass($list, $parentId = 0)
    {
        $return = [];
        foreach ($list as $class) {

            if ($class['parent_id'] == $parentId) {

                foreach ($list as $child) {

                    if ($child['parent_id'] == $class['ec_id']) {

                        $class['child'] = $this->formatClass($list, $class['ec_id']);
                        break;
                    } else {

                        $class['child'] = [];
                    }
                }

                $return[] = $class;
            }
        }
        return $return;
    }

    /**
     * 分类数据格式化为树状结构
     * @author pw
     * @param array $list 分类数据
     * @return array 格式化后的数据
     */
    public function formatTreeClass($list)
    {
        $tree = [];

        foreach ($list as $class_id => $item) {
            if (isset($list[$item['parent_id']])){
                $list[$item['parent_id']]['child'][] = &$list[$class_id];

            } else {
                $tree[] = &$list[$class_id];
            }
        }

        return $tree;
    }

    /**
     * @desc 获取所有已启用的分类ID(父类禁用子类不显示)
     * @author pw
     */
    public function getOpenClassIds()
    {
        $classServ = new CategoryService();
        $classList = $classServ->list_all();

        $classIds = [];
        $topClassIds = [];// 一级分类ID
        if (!empty($classList)) {

            // 格式化分类
            $classList = array_combine_by_key($classList, 'ec_id');
            foreach ($classList as $k => $v) {

                if ($v['parent_id'] != 0) {

                    $classList[$v['parent_id']]['child'][] = &$classList[$k];
                } else {

                    $topClassIds[] = $v['ec_id'];
                }
            }

            // 取已开启的二级分类以及其子分类
            foreach ($classList as $key => $value) {
                // 父级是否开启
                $parentIsOpen = isset($classList[$value['parent_id']]) ? ($classList[$value['parent_id']]['ec_status'] != Constant::CLASS_CLOSE) : false;
                // 非一级分类 + 当前分类已开启 + 父级分类已开启
                if ($value['parent_id'] != 0 && Constant::CLASS_OPEN == $value['ec_status'] && $parentIsOpen) {

                    $classIds[] = $value['ec_id'];
                }
            }
        }

        return array_merge($classIds, $topClassIds);
    }

    /**
     * 获取顶级分类信息
     * @author pw
     * @param int $classId 子分类ID
     * @return array
     */
    public function getTopClass($classId)
    {
        // 获取分类
        $class_list = $this->list_all();
        $class_list = array_combine_by_key($class_list, 'ec_id');

        // 获取一级分类
        while ($class_list[$classId]['parent_id'] > 0) {

            $classId = $class_list[$classId]['parent_id'];
        }

        return $class_list[$classId];
    }

    /**
     * 以树形结构格式化数据库数据
     * @author pw
     * @return array
     */
    public function formatDB()
    {
        // 所有分类列表
        $tree = $this->list_all();
        if (empty($tree)) {

            return [];
        }

        $tree = array_combine_by_key($tree, 'ec_id');

        foreach ($tree as $k => $v) {

            if ($v['parent_id'] != 0) {

                $tree[$v['parent_id']]['child'][$v['ec_id']] = &$tree[$k];
            }
        }

        return $tree;
    }

    /**
     * 获取当前分类及所有子分类ID
     * @author pw
     * @param int $classId 分类ID
     * @param array $tree 分类树形结构
     * @param array $childIds 收集子分类ID
     * @return array
     */
    public function getChildClassIds($classId, $tree = [], $childIds = [])
    {
        if (empty($tree)) {

            $tree = $this->formatDB();
        }

        $childIds[] = $classId;

        if (isset($tree[$classId]['child'])) {

            foreach ($tree[$classId]['child'] as $v) {

                $childIds = $this->getChildClassIds($v['ec_id'], $tree[$classId]['child'], $childIds);
            }
        }

        return $childIds;
    }


}