<?php
/**
 * @link      http://www.u-bo.com
 * @copyright 南京友博网络科技有限公司 
 * @license   http://www.u-bo.com/license/
 */

namespace common\models;

use Yii;
use yii\base\Model;
use yii\db\ActiveRecord;
use yii\db\Query;
use yii\helpers\Url;
use common\components\Tree;

/**
 * 树基本模型
 *
 * @author Strief http://blog.u-bo.com
 * @since 0.1
 */
class TreeList extends ActiveRecord
{
    public static $list;

    /**
     * 获取数据
     * 
     * @param  array $map   查询条件
     * @param  array $order 排序方式
     * @param  char  $field 查询字段，默认所有
     */
    public static function getData($map = [], $order = ['cat_id' => SORT_ASC], $field = "*", $column = '')
    {
        $query = static::find()
            ->select($field)
            ->where($map)
            ->orderBy($order);
        if (!empty($column)) {
            $query->indexBy($column);
        }
        $List = $query->asArray()
            ->all();
        return $List;
    }

    /**
     * 列表页树形结构列表显示
     * 
     * @param  integer $curCat 默认选择节点
     * @param  array   $where  关键字搜索
     * @param  char    $str    列表样式
     * @param  char    $pk     表的主键
     * @param  integer $width  编辑弹出框的宽
     * @param  integer $height 编辑弹出框的高
     * @param  integer $showFirst 是否只看一级目录
     * 
     * @return array   $list   列表内容
     */
    public static function getIndexTreeList($curCat = 0, $where = [], $str = '', $pk = 'cat_id', $width = 650, $height = 450, $showFirst = 0)
    {
        if ($showFirst == 1) {
            $where = ['parent_id' => 0];
        }
        $order = [
            'sort' => SORT_DESC,
            $pk => SORT_DESC
        ];
        $data = self::getData($where, $order, '*, parent_id as pid');
        $parent_id = $data[0]['pid'];
        $key = 1;
        foreach ($data as $result) {
            if ($parent_id > $result['pid']) {
                $parent_id = $result['pid'];
            }
            $dataList[$result[$pk]] = $result;
            $dataList[$result[$pk]]['create_time'] = date('Y-m-d',$result['create_time']);
            $dataList[$result[$pk]]['str_status'] = ($result['status'] == 1) ? '<font color="green">启用</font>' : '<font color="red">禁用</font>';
            $childs = self::getData(['parent_id' => $result[$pk]], [], $pk); //检测是否有子
            //如果存在子类别则该类别无法删除
            if (!empty($childs)) {
                $link = " <a href='javascript:;' class='gray' title='该类别存在子类，无法删除'><del>删除</del></a>";
                $dataList[$result[$pk]]['checkbox'] = "<input type='checkbox' name='delete[]' class='box-delete' value='".$result[$pk]."' disabled/>";
            } else {
                $deleteUrl = Url::to(['delete', 'id' => $result[$pk]]);
                $classInfo = 'link-delete';
                $link = " <a href='" . $deleteUrl . "' class='" . $classInfo . "'>删除</a>";
                $dataList[$result[$pk]]['checkbox'] = "<input type='checkbox' name='delete[]' class='box-delete' value='".$result[$pk]."'/>";
            }
            if ($result['status'] == 1) {
                $create = "<a href='javascript:;' class='open-dialog' 
                data-url='".Url::to(['create', 'id' => $result[$pk]])."' data-title='添加类别'"."data-width='".$width."' data-height='".$height."'>添加子类</a>";
            } else {
                $create = "<a href='javascript:;' title='该类别处于禁用状态，无法添加子类' class='gray'>添加子类</a>";
            }

            $dataList[$result[$pk]]['str_operation'] = "<a href='javascript:;' class='open-dialog' 
                data-url='".Url::to(['view', 'id' => $result[$pk]])."' data-title='编辑类别'"."data-width='".$width."' data-height='".$height."'>编辑</a> ".$create.$link;
            $dataList[$result[$pk]]['keyNum']=$key++; //序号
        }
        $Tree = new Tree($dataList);
        $Tree->icon = array('&nbsp;&nbsp;│ ', '&nbsp;&nbsp;├─ ', '&nbsp;&nbsp;└─ ');
        $Tree->nbsp = '&nbsp;&nbsp;';
        $list = $Tree->get_tree(0, $str, (int)$curCat);
        return $list;
    }

    /**
     * 生成树形结构下拉框
     * 
     * @param  integer $curCat      默认选择节点
     * @param  integer $disabledId  忽略节点
     * @param  char    $pk          主键
     * @param  boolean $isNewRecord 是否为插入操作
     * @param  char    $value       下拉框value值
     * 
     * @return array   $list        上级类别下拉框内容
     */
    public static function getDropDownTreeList($curCat = 0, $disabledId = 0, $pk = 'cat_id', $isNewRecord = true, $value = 'cat_id')
    { 
        $dataList = [];
        $order = [
            'sort' => SORT_DESC,
            $pk => SORT_DESC
        ];
        $data = self::getData($isNewRecord ? ['status' => 1] : '', $order, $pk. ', parent_id as pid, name, child_ids');
        foreach ($data as $result) {
            $dataList[$result[$pk]] = $result;
        }
        $str = "<option value='\$" . $value . "' \$selected \$disabled>\$spacer  \$name</option>";
        $Tree = new Tree($dataList);
        $Tree->icon = array('│', '├', '└');
        $list = $Tree->get_tree(0, $str, intval($curCat), intval($disabledId));
        return $list;
    }

    /**
     * 详情页类别显示(按顶级类别逐级罗列)
     * @param integer $cat_id ID
     */
    public static function getNameWithAllParents($cat_id) {
        if ($cat_id == 0 || $cat_id == null) {
            return '';
        }

        $str = '';
        $cat = static::findOne($cat_id);
        $parent_ids = $cat['parent_ids'];
        $arrparentids = explode(',', $parent_ids);
        foreach ($arrparentids as $key => $value) {
            if ($value != 0) {
                $str .= static::findOne($value)['name'] . '—';
            }
        }
        $str .= $cat['name'];
        return $str;
    }

    /**
     * 更新表里的父级ID集，子ID集
     *
     * @param char $tableName 要更新的表名
     * @param char $pk        主键
     * @param boolean $haveNo 是否有编码更新
     */
    public static function repairTree($tableName, $pk = 'cat_id', $haveNo = false)
    {
        self::$list = self::getCategoryList($pk);
        if (is_array(self::$list)) {
            $command = Yii::$app->db->createCommand();
            //\common\components\Tool::dump('OK');
            //先更新父级ID集
            foreach (self::$list as $id => $value) {
                self::$list[$id]['parent_ids'] = $parent_ids = self::getParentids($id);
                self::$list[$id]['child_ids'] = $child_ids = self::getChildids($id);
                if ($haveNo) {
                    self::$list[$id]['cat_no'] = $cat_nos = self::getCatNo($id);
                    $command->update($tableName, ['parent_ids' => $parent_ids, 'child_ids' => $child_ids, 'cat_no' => $cat_nos], $pk.' = :id', [':id' => $id])->execute();
                } else {
                    $command->update($tableName, ['parent_ids' => $parent_ids, 'child_ids' => $child_ids], $pk.' = :id', [':id' => $id])->execute();
                }
            }
        }
    }

    /**
     * 返回以类别id为索引的数据表
     * 
     * @return array 列表数据
     */
    public static function getCategoryList($pk = 'cat_id')
    {
        $catInfo = self::getData([], [$pk => SORT_DESC], '*, parent_id as pid', $pk);
        if ($catInfo) {
          return $catInfo;
        }
    }

    /**
     * 获取父级ID集
     * 
     * @param  integer $id          表ID
     * @param  string  $arrparentid 父级ID集
     * @return string  $arrparentid 父级ID集
     */
    public static function getParentids($id, $arrparentid = '')
    {
        $category = self::$list;
        if (!is_array($category) || !isset($category[$id]))
            return false;
        $parentid = $category[$id]['pid'];
        $arrparentid = $arrparentid ? $parentid . ',' . $arrparentid : $parentid;
        if ($parentid) {
            $arrparentid = self::getParentids($parentid, $arrparentid);
        } else {
            $category[$id]['parent_ids'] = $arrparentid;
        }
        return $arrparentid;
    }

    /**
     * 获取子ID集
     * 
     * @param  integer $id         表ID
     * @return string  $arrchildid 子ID集
     */
    public static function getChildids($id)
    {
        $category = self::$list;
        $arrchildid = $id;
        if (is_array($category)) {
            foreach ($category as $catid => $value) {
                if ($value['pid'] && $id != $catid) {
                    $arrparentids = explode(',', $value['parent_ids']);
                    if (in_array($id, $arrparentids)) {
                        $arrchildid .= ',' . $catid;
                    }
                }
            }
        }
        return $arrchildid;
    }

    /**
     * 更新类别编码
     * @param  [type] $id    类别ID
     * @param  string $catno 类别编码
     * 
     * @return string        类别编码
     */
    public static function getCatNo($id, $catno = '')
    {
        $category = self::$list;
        if (!is_array($category) || !isset($category[$id]))
            return false;
        $parentno = $category[$id]['no'];
        $parentid = $category[$id]['pid'];

        $catno = $catno ? $parentno . $catno : $parentno;
        if ($parentid) {
            $catno = self::getCatNo($parentid, $catno);
        } else {
            $category[$id]['cat_no'] = $catno;
        }
        return $catno;
    }

    /**
     * 遍历表检查禁用状态
     * 
     * @param char $tableName 要更新的表名
     */
    public static function updateStatusFalse($tableName, $pk = 'cat_id')
    {
        $parent = $child = self::getCategoryList($pk);
        if (is_array($parent)) {
            foreach ($parent as $parentId => $parentValue) {
                //若当前状态为禁用将其子项目状态
                if ($parentValue['status'] == 0) {
                    self::updateStatus($tableName, $parentId, $pk);
                }
            }  
        }
    }

    /**
     * 更新当前修改任务类别下的子任务类别状态
     * 
     * @param  integer $id 当前修改的任务类别ID
     */
    public static function updateStatus($tableName, $id, $pk = 'cat_id')
    {
        $parent = static::findOne([$pk => $id]);
        $parentStatus = $parent['status'];
        $childs = $parent['child_ids'];
        $arrparentids = explode(',', $childs);
        $command = Yii::$app->db->createCommand();
        $child = self::getCategoryList($pk);
        //将当前部门下的所有子项目状态与当前项目的状态保持一致
        if (is_array($child)) {
            foreach ($child as $catid => $value) {
                if ($value['pid'] && $id != $catid) {
                    if (in_array($catid, $arrparentids)) {
                        $command->update($tableName, ['status' => $parentStatus], $pk.' = :id', [':id' => $catid])->execute();
                    }
                }
            }
        }
    }

    /**
     * 检测当前类的父类的禁用状态
     */
    public static function checkStatus($id, $pk = 'cat_id')
    {
        $cat = static::findOne([$pk => $id]);
        $parentCat = static::findOne([$pk => $cat->parent_id]);
        if (isset($parentCat)) {
            $status = $parentCat->status == 1 ? true : false;
        } else {
            $status = true;
        }
        return $status;
    }
}
