<?php
namespace model\pro;
use \model;
use \model\grid\lrtree;
/**
 * Class procate
 * @package model
 */
class cate extends model
{
    public $table = 'pro_cate';
    public $key = 'id';
    public $name = LG_NAME;
    public $order = LG_NAME;
	public $lrtree = null;
	public function __construct()
    {
		parent::__construct();
        $this->options = [
			'table'=>'pro_cate',
			'id'=>'id',
			'parent_id'=>'parent_id',
			'left'=>'left',
			'right'=>'right',
			'level'=>'level',
			'ismove'=>'ismove',
			'cn_name'=>'cn_name',
			'en_name'=>'en_name',
			'py_name'=>'py_name',
			'cat_zhuyi'=>'cat_zhuyi',
			'cat_pzbz'=>'cat_pzbz',
			'cat_zpsl'=>'cat_zpsl',
			'attaqty'=>'attaqty',
			'create_time'=>'create_time',
			'update_time'=>'update_time'
		];
        $this->attaqtys = [
			'pdf_attaqty_1'=>'轮毂附件 Hub Assemblies',
			'pdf_attaqty_2'=>'轮毂附件 Bearing Kits',
			'pdf_attaqty_3'=>'轮毂附件 Stub Axle',
		];
		$this->attaqtys2 = [
			'mas_attaqty_1'=>'Wheel Bearing',
			'mas_attaqty_2'=>'Boot Kits',
		];
		$this->lrtree = new lrtree($this->options);
	}



	public function attaqtysItems()
	{
		$attaqtysitems = [':'];
		foreach($this->attaqtys as $k=>$v)
		{
			$attaqtysitems[] = $k.':'.$v;
		}
		return implode(',', $attaqtysitems);
	}

	public function attaqtys2Items()
	{
		$attaqtys2items = [':'];
		foreach($this->attaqtys2 as $k=>$v)
		{
			$attaqtys2items[] = $k.':'.$v;
		}
		return implode(',', $attaqtys2items);	
	}

    /**
     * 保存参数示意图
     * @param $data
     * @param $config
     */
    public function save($data,$config)
    {
        $fileid = $data['file_id'];
        $data['param'] = json_decode($data['param'],true);
        $id = $data['param']['id'];
        $this->db->update($this->table,['photo_param' => $fileid],['id' => $id]);
    }

	function addCate($parent_id,$data)
	{
		$this->db->Begin();
		$id = $this->lrtree->addNode($parent_id,$data);
		$this->db->End();
		return $id;
	}

	function editCate($id,$parent_id,$data)
	{
		$this->db->Begin();
		$result = $this->lrtree->editNode($id,$parent_id,$data);
		$this->db->End();
		return $result;
	}

	function delCate($id)
	{
		$pid = $this->db->get('pro_cate', 'id', ['parent_id'=>$id]);
		if(!empty($pid)) exitJson('此分类有子类，请先删除子类');
		
		$pid = $this->db->get('pro', 'p_id', ['p_cate'=>$id]);
		if(!empty($pid)) exitJson('此品名有产品，请先删除产品');
		
		$this->db->Begin();

		$this->lrtree->deleteNode($id);
		//参数绑定
		$this->db->delete('part_param', ['ptpa_pc_id'=>$id]);
		//参数值
		$this->db->delete('pro_param_val', ['ppv_pc_id'=>$id]);
		$this->db->End();
		return [];
	}

	/**
	  * @method 获取中国车型的位置信息
	  * @author soul
	  */
	public function getCnModelFiled($cat_id = 0, $p_id = 0)
	{
		if(!empty($p_id))
		{
			$row = $this->db->get('pro(p)',['[><]pro_cate(cat)'=>['p.p_cate'=>'id']], ['cat.id', 'cat.cat_cnpos'], ['p.p_id'=>$p_id]);
		}
		else
		{
			$row = $this->db->get('pro_cate', ['id', 'cat_cnpos'], ['id'=>$cat_id]);
		}
		$fileds = [];
		if(!empty($row['cat_cnpos']))
		{
			$row['cat_cnpos'] = json_decode($row['cat_cnpos'], true);
			if(is_array($row['cat_cnpos'])) $fileds = array_column($row['cat_cnpos'], 'name', 'filed');
		}
		return $fileds;
	}


    /**
     *  删除参数示意图
     * @param $id
     * @param $photoParam
     * @return false|\PDOStatement
     */
    public function deleteImage($id,$photoParam)
    {
        return $this->db->update($this->table,['photo_param' => ''],['id' => $id]);
    }

    public function list($where='',$page=0,$pagesize=0,$sidx='',$sord='asc',$orderby='')
    {
        if($where){
            $where = $this->filter2medoo($where);
        }
        $arr = $this->lrtree->list($where, $page, $pagesize, $sidx, $sord);
		foreach($arr['rows'] as &$row)
		{
			$row['captions']['attaqty'] = isset($this->attaqtys[$row['attaqty']])? $this->attaqtys[$row['attaqty']]: '';
			$row['captions']['cat_model_fileds'] = $this->getSmallFiledsName($row);
		}
		return $arr;
    }

	function list2($rules, $where='',$page=0,$pagesize=0,$sidx='',$sord='asc',$orderby=''){
	    $page=1;
	    $pagesize = 1000;
	    $orderby='level,parent_id,en_name';
	    
        $table = $this->table.'(c)';
        $this->fields = ['c.*'];
        $this->join = [];
		$this->joinWhere = [];
		$this->group = [];
        $where = $this->filter2medoo($where,function(&$field,&$op,&$data){
            if($field=='en_name' || $field=='cn_name'|| $field=='py_name'){
                $op = 'eq';
                $field = 'id';
                $data = $this->likeAndChilds($data,true);
				if(empty($data)) $data = 0;
            }
			if($field=='cat_model_fileds' || $field=='cat_cnpos')
			{
				if($data == 1)
				{
					$op = 'not';
					$data = '{}';
				}
				else if($data == 0)
				{
					$data = '{}';
				}
			}
        });
		if($where==null) $where = [];
		if(!empty($rules['pwcode']))
		{
			$pwids = \p::cates($rules['pwcode']);
			if($pwids != ''){
				$where['id'] = $this->getParentIds($pwids,true);
			}
		}
		if(!empty($this->joinWhere)){
			$where = array_merge($where, $this->joinWhere);
		}

		if(!empty($this->group)){
			$where = array_merge($where, $this->group);
		}
        $where = $this->listWhere($where,$page,$pagesize,$sidx,$sord,$orderby);

		if($page>0 && $pagesize>0){
            if(empty($this->join)){
                $pages = $this->paging($table,$where,$page,$pagesize);
            }else{
                $pages = $this->paging($table,$this->join,'*',$where,$page,$pagesize);
            }
			$where["LIMIT"] = [$pages['limit'],$pagesize];
		}
        if(empty($this->join)){
            $rows = $this->db->select($table,$this->fields,$where);
        }else{
            $rows = $this->db->select($table,$this->join,$this->fields,$where);
        }
		//dd($this->db->last());
		
		$sortRows = [];
        $this->treeSortRows($rows,$sortRows);
        
        foreach($rows as $row){
            $sortRows[] = $row; //遗留
        }
		
        foreach($sortRows as $k=>&$row){
			$t = json_decode($row['cat_cnpos'], true);
			if(!is_array($t)) $t = [];
			$row['captions']['cat_cnpos'] = implode(',', array_column($t, 'name'));
			$row['captions']['attaqty'] = isset($this->attaqtys[$row['attaqty']])? $this->attaqtys[$row['attaqty']]: '';
            //叶子节点
            if($row['right']-$row['left']==1){
                $row['leaf'] = true;
            }else{
                $row['leaf'] = false;
            }
			$row['tcd_name'] = trim($row['tcd_name'], ';');
        }
        
		$data = [
			'page'=> $page,
			'total'=> $pages['total'],
			'records' => $pages['records'],
			'rows' => $sortRows
		];
		return $data;
	}
	function listOppo($rules, $where='',$page=0,$pagesize=0,$sidx='',$sord='asc',$orderby=''){
	    $page=1;
	    $pagesize = 1000;
	    $orderby='level,parent_id,en_name';
	    
        $table = $this->table.'(c)';
        $this->fields = ['*'];
        $this->join['[>]oppo_pro_cate'] = ['c.id'=>'opc_id'];
		$this->joinWhere = [];
		$this->group = [];
        $where = $this->filter2medoo($where,function(&$field,&$op,&$data){
            if($field=='en_name' || $field=='cn_name' || $field=='py_name'){
                $op = 'eq';
                $field = 'id';
                $data = $this->likeAndChilds($data,true);
				if(empty($data)) $data = 0;
            }
			if($field=='cat_model_fileds' || $field=='cat_cnpos')
			{
				if($data == 1)
				{
					$op = 'not';
					$data = '{}';
				}
				else if($data == 0)
				{
					$data = '{}';
				}
			}
        });
		if($where==null) $where = [];
		if(!empty($rules['pwcode']))
		{
			$pwids = \p::cates($rules['pwcode']);
			if($pwids != ''){
				$where['id'] = $this->getParentIds($pwids,true);
			}
		}
		if(!empty($this->joinWhere)){
			$where = array_merge($where, $this->joinWhere);
		}

		if(!empty($this->group)){
			$where = array_merge($where, $this->group);
		}
        $where = $this->listWhere($where,$page,$pagesize,$sidx,$sord,$orderby);

		if($page>0 && $pagesize>0){
            if(empty($this->join)){
                $pages = $this->paging($table,$where,$page,$pagesize);
            }else{
                $pages = $this->paging($table,$this->join,'*',$where,$page,$pagesize);
            }
			$where["LIMIT"] = [$pages['limit'],$pagesize];
		}
        if(empty($this->join)){
            $rows = $this->db->select($table,$this->fields,$where);
        }else{
            $rows = $this->db->select($table,$this->join,$this->fields,$where);
        }
		//dd($this->db->last());
		
		$sortRows = [];
        $this->treeSortRows($rows,$sortRows);
        
        foreach($rows as $row){
            $sortRows[] = $row; //遗留
        }
		
        foreach($sortRows as $k=>&$row){
			$t = json_decode($row['cat_model_fileds'], true);
			if(!is_array($t)) $t = [];
			$row['captions']['cat_model_fileds'] = implode(',', $t);

			$t = json_decode($row['cat_cnpos'], true);
			if(!is_array($t)) $t = [];
			$row['captions']['cat_cnpos'] = implode(',', array_column($t, 'name'));

            //叶子节点
            if($row['right']-$row['left']==1){
                $row['leaf'] = true;
            }else{
                $row['leaf'] = false;
            }
        }
        
		$data = [
			'page'=> $page,
			'total'=> $pages['total'],
			'records' => $pages['records'],
			'rows' => $sortRows
		];
		return $data;
	}
	
	function treeSortRows(&$rows,&$sortRows,$parent=0)
	{
	    foreach($rows as $k=>$row){
	        if($row['parent_id']==$parent){
	            $sortRows[] = $row;
	            unset($rows[$k]);
	            $this->treeSortRows($rows,$sortRows,$row['id']);
	        }
	    }
	}

	/*模糊摸查名称*/
    public function like($value){
        $value = trim($value);
        $where = ['OR'=>[
                    'cn_name[~]'=>$value,
                    'en_name[~]'=>$value,
                    'keyword[~]'=>$value
                    ]
                 ];
        $rows = $this->db->select($this->table,"id",$where);
        $rows = array_unique($rows);
        if(count($rows)==1) $rows = $rows[0];
        return $rows;
    }

	/*精确查名称*/
    public function eqname($value, $pcate = '', $isend = 1){
		//SELECT cat.id, pcat.`cn_name`, pcat.`en_name`, cat.`cn_name`, cat.`en_name` FROM `pro_cate` AS cat LEFT JOIN `pro_cate` AS pcat ON cat.`parent_id` = pcat.id WHERE (pcat.`cn_name` = '' OR  pcat.`en_name` = '') AND (cat.`cn_name`= '' cat.`en_name` ='')
        $value = trim($value);
        $pcate = trim($pcate);
		if(!empty($pcate))
		{
			$join = ["[>]pro_cate(pcat)" => ["cat.parent_id" => "id"]];
			$where = [
			'AND #'=>[
					'OR #1'=>[
						'pcat.cn_name'=>$pcate,
						'pcat.en_name'=>$pcate,
						'pcat.py_name'=>$pcate,
					],
					'OR #2'=>[
						'cat.cn_name'=>$value,
						'cat.en_name'=>$value,
						'cat.py_name'=>$value,
						'cat.cat_as[~]'=>','.$value.',',
						'tcd_name[~]'=>';'.$value.';',
						'tcd_name[~]'=>';'.$value.';',
					],
				]
			];
			if($isend) $where['cat.right'] = raw('`cat`.`left`+1');
			return $this->db->get('pro_cate(cat)', $join,"cat.id",$where);
		}
		else
		{
			$where = [
				'AND #'=>[
					'OR'=>[
						'cn_name'=>$value,
						'en_name'=>$value,
						'py_name'=>$value,
						'cat_as[~]'=>','.$value.',',
						'tcd_name[~]'=>';'.$value.';',
					]
				]
			 ];
		    if($isend) $where['right'] = raw('`left`+1');
			return $this->db->get($this->table,"id",$where);
		}
    }

    public function getCate($id){
        return $this->db->get($this->table,'*', ['id'=>$id]);
    }

	/*模糊摸查别名*/
    public function likeAs($value){
        $value = trim($value);
        $where = ['as[~]'=>$value];
        $rows = $this->db->select($this->table,"id",$where);
        $rows = array_unique($rows);
        if(count($rows)==1) $rows = $rows[0];
        return $rows;
    }

	/*模糊摸查名称，并返回所有子节点*/
    public function likeAndChilds($value,$hasSelf=false){
        $value = trim($value);
        $where = ['OR'=>[
                    'cn_name[~]'=>$value,
                    'en_name[~]'=>$value,
                    'py_name[~]'=>$value,
                    ]
                 ];
        $ids = $this->db->select($this->table,"id",$where);
        $ids = array_unique($ids);
		$rows=[];
		if($ids){
			if($rows = $this->db->select($this->table,"id",['OR'=>['id'=>$ids,'parent_id'=>$ids]])){
    			$rows = array_unique($rows);
			}
			if($rows && $rows = $this->db->select($this->table,"id",['OR'=>['id'=>$ids,'parent_id'=>$rows]])){
    			$rows = array_unique($rows);
			}
		}
        if(count($rows)==1) $rows = $rows[0];
        return $rows;
    }

	/*模糊摸查名称，并返回所有父节点*/
    public function getParentIds($ids,$hasSelf=false){
        if(is_string($ids)) $ids = explode(',',$ids);
        $frows = $this->db->select($this->table,['left','right'],['id'=>$ids]);
		
        $arrAnd = [];
        $opLeft  = $hasSelf ? 'left[<=]' : 'left[<]';
        $opRight = $hasSelf ? 'right[>=]' : 'right[>]';
        foreach ($frows as $fk=>$frow){
            $arrAnd['AND #'.$fk] = [$opLeft=>$frow['left'],$opRight=>$frow['right']];
        }
        $where['OR'] = $arrAnd;
        $arrIds = $this->db->select($this->table,'id',$where);
        return $arrIds;
    }


	public function searchPart($word,$isbigCate=false,$limit=10000, $pwids = '')
	{
		$word = trim($word);
		$data = [];
		/*
		if(strlen($word) > 0)
		{
			$pdata = $this->db->select('pro_cate', ['parent_id']);
			$join = [
				"[><]pro_cate(pcat)" => ["p.parent_id" => "id"]
			];
			$where = [
				'p.id[!]'=>array_unique(array_column($pdata, 'parent_id')),
				'AND'=>[
					'OR'=>[
						'p.keywords[~]'=>$word,
						'p.cn_name[~]'=>$word,
						'p.en_name[~]'=>$word,
					]	
				],
				'GROUP'=>['p.id']
			];
			$data = $this->db->select('pro_cate(p)', $join, ['p.id', 'p.cn_name', 'p.en_name', 'pcat.id(pid)', 'pcat.cn_name(pcn_name)', 'pcat.en_name(pen_name)'], $where);
		}
		*/
		if($word!=''){
			$fields = ['c.id', 'c.cn_name', 'c.en_name', 'c.py_name'];
			$where['OR'] =[
				'c.keywords[~]'=>$word,
				'c.cn_name[~]'=>$word,
				'c.en_name[~]'=>$word,
				'c.py_name[~]'=>$word,
			];
			$where['LIMIT'] = $limit;
			
		    if($isbigCate){
		        $where['RAW'] = raw("c.`right`-c.`left`>1");
				if(!empty($pwids))
					$where['RAW_ids'] = raw(" c.id in (select parent_id from pro_cate where id in (".$pwids."))");
		    }else{
		        $where['RAW'] = raw("c.`right`-c.`left`=1");
				if(!empty($pwids))
					$where['c.id'] = explode(',', $pwids);
		        $fields = array_merge($fields,[
		            'big.id(pid)', 'big.cn_name(pcn_name)', 'big.en_name(pen_name)', 'big.py_name(ppy_name)'
		        ]);
    			$join = [
    				"[><]pro_cate(big)" => ["c.parent_id" => "id"]
    			];
		    }
		    if(!$join){
		        $join = $fields; $fields = $where; $where = null;
		    }
			
			$data = $this->db->select('pro_cate(c)', $join, $fields, $where);
		}else if($isbigCate){
		    $where['RAW'] = raw("`right`-`left`>1");
			if(!empty($pwids))
				$where['RAW_ids'] = raw(" id in (select parent_id from pro_cate where id in (".$pwids."))");
			$data = $this->getAll($where);
		}else{
			$data = $this->getAll();
		}
		return $data;
	}

	/**
	  * @method 复制属性
	  * @param  $from_cate  int  [必填] 
	  * @param  $to_cate  string  [必填] 逗号分隔
	  * @param  $fileds  string  [必填] cat_model_fileds,cat_zhuyi...
	  * @author soul
	  */
    function copyFileds($from_cate, $to_cate, $fileds)
	{
		$canSetFiled = ['cat_model_fileds', 'cat_zhuyi', 'cat_pzbz', 'cat_zpsl'];
		$setfiles = [];
		foreach(explode(',', $fileds) as $fk)
		{
			if(in_array($fk, $canSetFiled)) $setfiles[] = $fk;
		}
		if(empty($setfiles)) exitJson('参数异常');

		$fromArr = $this->db->get('pro_cate', $setfiles, ['id'=>$from_cate]);
		if(empty($fromArr)) exitJson('数据不存在');
		$this->db->update('pro_cate', $fromArr, ['id'=>explode(',', $to_cate)]);
		return [];
    }
    
	/**
	  * @method 取二级产品线,通过指定ID
	  * @param  $ids  array 
	  */
    function getBigCatesByIds($ids=[])
	{
	    $where = [];
	    if(!empty($ids)){
	       $where['OR']['parent_id'] = $ids; 
	       $where['OR']['id'] = $ids; 
	    }
	    $where['RAW'] = raw("`right`-`left`>1");
	    
		$rows = $this->db->select('pro_cate', '*', $where);
		$data = [];
		foreach ($rows as $row){
            $hasWhere['left[>]'] = $row['left']*1;
            $hasWhere['right[<]'] = $row['right']*1;
            $hasWhere['RAW'] = raw("`right`-`left`>1");
		    if(!$this->db->has('pro_cate',$hasWhere)){
		        $data[] = $row;
		    }
		}
		return $data;
    }
    
	/**
	  * @method 取二级产品线,通过品名
	  * @param  $cates  array 
	  */
    function getBigCatesByCates($cates)
	{
        $where['id'] = $cates; 
		$rows = $this->db->select('pro_cate', ['parent_id'], $where);
		$parent_ids = [];
		foreach ($rows as $row){
            $parent_ids[] = $row['parent_id'];
		}
		return $this->db->select('pro_cate', '*', ['id'=>$parent_ids]);
    }
    
	/**
	  * @method 通过产品线,取所有品名
	  * @param  $cates  array 
	  */
    function getCatesByBigCates($ids)
	{
		return $this->db->select('pro_cate', ['id','cn_name','en_name','py_name'], ['parent_id'=>$ids]);
    }

	//获取品类的竞品统计信息
	function cleanGaTj($cat_id)
	{
		$data = [];
		$row = $this->db->get('pro_cate', ['id','cn_name','en_name','py_name', 'tcd_name'], ['id'=>$cat_id]);
		if(!empty($row))
		$names = [];
		if(!empty($row['tcd_name'])){
			$names[] = $row['tcd_name'];
		}else{
			if(!empty($row['cn_name'])) $names[] = $row['cn_name'];
			if(!empty($row['en_name'])) $names[] = $row['en_name'];
			if(!empty($row['py_name'])) $names[] = $row['py_name'];
		}
		if(!empty($names)){
			$ypApi = new \model\ypApi();
			$res = $ypApi->Get('tcd/cleanGaTj', ['ganame'=>implode(';', $names)]);
			$data = $res['data'];
		}
		return $data;
	}

	function canMoveSubtree($id,$parent_id,$limitLevel=3)
	{
		if(!$id && !$parent_id) return ['status'=>true,'msg'=>''];
		
		$maxLevel =0;
		if(!$id){
			$curNode['level'] =0;
		}else{
			// 获取子树的当前层级
			$curNode = $this->db->get('pro_cate','*',['id'=>$id]);
			$left = $curNode['left']*1;
			$right = $curNode['right']*1;

			if($right - $left!=1){
				return ['status'=>false,'msg'=>'当前分类存在下级，不可变更上级'];
			}
			// 计算子树的最大层级
			$maxLevel =$this->db->max('pro_cate','level',[
				'left'."[>=]" => $left,
				'right'."[<=]" => $right,
			]);
		}
		
		$newParent = $this->db->get('pro_cate','*',['id'=>$parent_id]);
		// 检查新层级是否超过3级
		$newMaxLevel = $newParent['level'] + ($maxLevel - $curNode['level']) + 1;
		if ($newMaxLevel > $limitLevel) {
			return ['status'=>false,'msg'=>'系统只支持'.$limitLevel.'级品名，请选择另一个品名来添加'];
		}
	
		return ['status'=>true,'msg'=>''];
	}
}