<?php
namespace model\pro;
use \model;
use \model\tags;
use \model\pro\pro;
use \model\pro\factory;
use \model\carmodel;
use \model\check;
use \model\collocation;

/**
 * Class 产品号码关系
 * @package Numidx
 */
class numidx extends model
{
	public function __construct ()
    {
		parent::__construct();
		$this->factory = new factory();
	}


	/**
     * 加入正式库检测是参考号否存在
	 * @param  $dataArr  array  [必填] ['pn_p_id'=>'', 'pn_pf_id'=>'', 'pn_formart'=>'']
     */
	public function checkExist($dataArr, $pn_id = 0)
	{
		//正式参考号
		$uniwhere = [
			//'p_state_main[!]'=>'Y5',
			'pn_type'=>'none',
			'pn_is_sys'=>0,
			'pn_id[!]'=>$pn_id,
			'pn_p_id'=>$dataArr['pn_p_id'],
			'pn_pf_id'=>$dataArr['pn_pf_id'],
			'pn_formart'=>$dataArr['pn_formart']
		];
		$table = 'pro_numidx(num)';
		$join = ["[><]pro(pro)" => ["num.pn_p_id" => "p_id"]];
		$exists = $this->db->get($table, $join, ['pn_id'], $uniwhere);
		if(!empty($exists)) return ['code'=>0, 'table'=>'pro_numidx', 'msg'=>$dataArr['pn_formart'].'已存在，禁止添加'];
		return [];
	}

	
	/**
	  * @method 正式交叉库 数据 pro_numidx
	  * @author soul
	  */
	public function getList($params, $rules = [])
	{
		$filters = $params['filters'];
		$page = $params['page'];
		$pagesize = $params['rows'];
		$sidx = empty($params['sidx'])? 'fac.pf_name,num.pn_formart': $params['sidx'];
		$sord = empty($params['sord'])? 'asc': $params['sord'];
		$orderby = $params['orderby'];

		//通过当前p_id获取引用的p_id
		// $pro = new pro();
		// $params['p_id'] = $pro->getQuoteIdbyPid($params['p_id']);
		
		$refiled = [
			'pb_name'=>'pb.pb_'.LG_NAME,
			'cat_name'=>'cat.'.cateName(),
			'pcat_name'=>'pcat.'.cateName(),
			'pn_number'=>'pn_formart',
			'opuser'=>'num.opuser',
			'create_time'=>'num.update_time',
			'update_time'=>'num.update_time'
		];
		$this->set('refiled', $refiled);
		$sidx =  strtr($sidx, $refiled);

		$table = 'pro_numidx(num)';
		$join = [
			"[>]pro(pro)" => ["num.pn_p_id" => "p_id"],
			"[>]pro_brand(pb)" => ["pro.p_pb_id" => "pb_id"],
			"[>]pro_cate(cat)" => ["pro.p_cate" => "id"],
			"[>]pro_cate(pcat)" => ["cat.parent_id" => "id"],
			"[>]pro_factory(fac)" => ["num.pn_pf_id" => "pf_id"],
			"[>]adm_user(au)"=>["num.opuser"=>'au_id']
		];
		
		$this->set('pnumwhere', []);
		$this->set('carmodel', new carmodel());
        $where = $this->filter2medoo($filters,function(&$field,&$op,&$data){
			$field = strtr( $field, $this->get('refiled'));

			// if($field == 'fac_number') {
			// 	$field = 'RAW #'.$field;
			// 	$data = raw(sprintf('CONCAT_WS(\':\', fac.pf_name, num.pn_formart) LIKE \'%%%s%%\'',$data));
			// } 
			if($field == 'pn_pf_id') $data = $this->factory->like($data);

			if($field == 'tags')
			{
				$res = $this->get('carmodel')->medooAnyLink($field, 'pn_id', $op, $data, ['tl_type'=>'number']);
				$data = $res['data'];
				$op = $res['op'];
			}
			if($field == 'pn_formart') $data = formatNum($data);
			if($field == 'p_comnum')
			{
				$res = $this->fiterProByNum('p_comnum', ['p_fined'=>'num.pn_p_id', 'op'=>$op, 'val'=>$data, 'pnumwhere'=>$this->get('pnumwhere')]);
				$op = $res['op'];
				$data = $res['data'];
				$this->set('pnumwhere', $res['pnumwhere']);
			}
			if($field == 'pn_cn_remark') $op = 'bw';
			if($field == 'pn_mk_id'){
			    if(in_array($op,['cn','bw','eq'])){
			        $data = $this->db->select('m_make','mk_id',['name['.$this->getMedooOp($op).']'=>$data]);
			        if(!$data) $data = [-1];
			        $op = 'eq';
			    }
			}
			if($field == 'pn_id') $data = explode(',', $data);
        });
		
		$where['pn_is_sys'] = 0;
		foreach($rules as $filed=>$val)
		{
			if(empty($val)) continue;
			switch($filed)
			{
				case 'numbers':
					if(!empty($rules['numfac']) && $rules['numfac'] == 2)
					{
						$res = $this->fiterProByNum('numbers', ['p_fined'=>'num.pn_p_id', 'numlike'=>$rules['numlike'], 'val'=>$val, 'pnumwhere'=>$this->get('pnumwhere')]);
						$where = array_merge($where, $res['sqlwhere']);
						$this->set('pnumwhere', $res['pnumwhere']);
					}
					else
					{
						foreach($val as $tk=>$tv)
						{
							$val[$tk] = formatNum($tv);
						}
						if($rules['numfac'] == 3)
						{
							$where['p_innum_format'.($rules['numlike']? '[~]': '')] = $val;
						}
						else if($rules['numfac'] == 1)
						{
							$where['pn_formart'.($rules['numlike']? '[~]': '')] = $val;
						}
						else
						{
							$where["AND #num"] = [
								"OR" => [
									'pn_formart'.($rules['numlike']? '[~]': '') => $val,
									'p_comnum_format'.($rules['numlike']? '[~]': '') => $val,
									'p_innum_format'.($rules['numlike']? '[~]': '') => $val
								]
							];
						}
						if(!empty($rules['numfac']))
						{
							if(!in_array($rules['numfac'], [2,3]))
							{
								$where['num.pn_pf_id'] = $rules['numfac'];
							}
						}
					}
				break;
				case 'p_cate': $where['p_cate'] = explode(',', $rules['p_cate']); break;
				case 'ver': 
					$join["[><]tags_link(tl)"] = ["num.pn_id" => "tl_value_id"];
					$where['tl_type'] = 'number';
					$where['tl_t_id[>]'] = raw(sprintf("tl_t_id ^ %d",$rules['ver']));
				break;
			}
		}
		
		// $where['p_pb_id'] = 1;
		$where['pn_type'] = 'none';
		if(!empty($params['keys'])) $where['pn_id'] = explode(',', $params['keys']);
		if(!empty($params['pn_id'])) $where['pn_id'] = $params['pn_id'];
		
		$where['p_id'] = $params['p_id'];
		$where['GROUP'] = ['num.pn_pf_id','num.pn_formart'];
		//综合
		if(!empty($params['p_id']) && !empty($params['pwcode']))
		{
			if(\p::fieldhas($params['pwcode'], 'oe') && \p::fieldhas($params['pwcode'], 'numidx'))
			{}else if(\p::fieldhas($params['pwcode'], 'oe')){
				$where['AND #rulefac']['num.pn_pf_id'] = 1;
			}else if(\p::fieldhas($params['pwcode'], 'numidx')){
				$where['AND #rulefac']['num.pn_pf_id[!]'] = 1;
			}else{
				$where['AND #rulefac']['num.pn_pf_id'] = -1;
			}
		}
		else
		{//正式库
			$check = new \model\check();
			$ruleWhere = $check->getPowerWhere('pro_numidx', 'E200');
			$where = array_merge($where, $ruleWhere);
		}

        $where = $this->listWhere($where,$page,$pagesize,$sidx,$sord,$orderby);
		if($page>0 && $pagesize>0){
			$fields = '*';
			$pages = $this->paging($table,$join,$fields,$where,$page,$pagesize, 15*60); // 15分钟缓存
			$where["LIMIT"] = [$pages['limit'],$pagesize];
		}
		$fields = ['cat.id(cat_id)', 'pcat.'.cateName().'(pcat_name)', 'cat.'.cateName().'(cat_name)', 'p_id', 'p_innum', 'p_comnum', 'p_state_main', 'fac.pf_id', 'fac.pf_name', 'pb_'.LG_NAME.'(pb_name)','pn_ismain'=>raw('MAX(num.pn_ismain)'),  'num.pn_id',
        'num.pn_p_id',
        'num.pn_pf_id',
        'num.pn_formart',
        'num.pn_number',
        'num.pn_mk_id',
		'num.pn_isborrow','au_name'];

        $arr = $this->db->select($table,$join,$fields,$where);
		if(!empty($this->get('pnumwhere'))) $arr = $this->getSearchOutnum($arr, $this->get('pnumwhere'));
		if(!empty($arr)){
			$arr = $this->fillProNumidx($arr);
		}
		$data = [
			'page'=> $page,
			'total'=> $pages['total'],
			'records' => $pages['records'],
			'rows' => $arr
		];
		return $data;
	}

	public function fillProNumidx($arr)
	{
		if(!empty($arr))
		{
			$collocation = new collocation();
			$collArr = $collocation->getCollItems('number');
			$carmodel = new carmodel();
			$tags = new tags();
			$verArr = $tags->getTypeValTags('number', array_column($arr, 'pn_id'));
			$verArr = array_column($verArr, 'tags', 'tl_value_id');

			$coll13Arr = $collocation->lrtree->getChilds(13);
			$coll13Arr = array_column($coll13Arr, LG_NAME, 'o_id');
			//汽车品牌
			$pnIds = array_unique(array_column($arr, 'pn_id'));
			$protbRes = $this->db->select('pro_numidx_tag_brand(pntb)',['[><]tag_brand(tb)'=>['pntb.pntb_tb_id'=>'tb_id']],['pntb_pn_id','tb_names'=>raw(sprintf("GROUP_CONCAT(tb_%s)",cateName()))],['pntb_pn_id'=>$pnIds,'GROUP'=>'pntb_pn_id']);
			if($protbRes){
				$protbArr = array_column($protbRes, 'tb_names', 'pntb_pn_id');
			}
			foreach($arr as &$v)
			{
				$oemake = [];
				if(!empty($v['pn_mk_id'])) $oemake = $carmodel->getMakes(explode(',', $v['pn_mk_id']));
				$v['tags'] = empty($verArr[$v['pn_id']]) ? '': implode(',', array_column($verArr[$v['pn_id']], 't_id'));
				$v['captions'] = [
					'pn_pf_id'=>$v['pf_name'],
					'pn_mk_id'=>implode(',', array_column($oemake, 'mk_'.LG_NAME)),
					'tags'=> empty($verArr[$v['pn_id']]) ? '': implode(',', array_column($verArr[$v['pn_id']], LG_NAME)),
					'pn_src'=>!empty($collArr[$v['pn_src']])? $collArr[$v['pn_src']]: '',
					'ckresult2'=>!empty($collArr[$v['ckresult2']])? $collArr[$v['ckresult2']]: '',
					'pn_from'=>!empty($coll13Arr[$v['pn_from']])? $coll13Arr[$v['pn_from']]: '',
					'opuser'=>$v['au_name'],
					'pn_tag_brand'=>$protbArr[$v['pn_id']] ?? '',
				];
			}
		}
		return $arr;
	}

	
	/**
	$type = 'p_comnum'  ['p_fined'=>'num.pn_p_id', 'pnumwhere'=>$pnumwhere,'op'=>'eq', 'val'=>'NTK']
	$type = 'numbers'   ['p_fined'=>'num.pn_p_id', 'numlike'=>$rules['numlike'], 'val'=>$val, 'pnumwhere'=>$this->get('pnumwhere')]
	**/
	public function fiterProByNum($type, $params)
	{
		if($type == 'p_comnum')
		{
			$pnumwhere['pn_pf_id'] = [2,5];
			$data = formatNum($params['val']);
			if($params['op'] == 'eq')
			{
				$pnumwhere['pn_formart'] =$data;
				$data= raw(sprintf("%s in (select pn_p_id from pro_numidx where pn_type = 'none' and pn_pf_id in (2,5) and pn_formart = '%s')", $params['p_fined'], $data));
			}
			else
			{
				$pnumwhere['pn_formart[=~]'] =$data;
				$data= raw(sprintf("%s in (select pn_p_id from pro_numidx where pn_type = 'none' and pn_pf_id in (2,5) and pn_formart like '%s%%')", $params['p_fined'], $data));
			}
			$this->set('pnumwhere', $pnumwhere);
			return ['pnumwhere'=>$pnumwhere, 'data'=>$data, 'op'=>'RAW'];
		}
		else if($type == 'numbers')
		{
			$nums = [];
			foreach($params['val'] as $tnum)
			{
				$nums[] = formatNum($tnum);
			}
			$nums = array_unique($nums);
			$sqlwhere = [];
			if($params['numlike'])
			{
				$twhere = [];
				foreach($nums as $tnum)
				{
					$twhere[] = sprintf(" pn_formart like '%s%%'", $tnum);
				}
				$sqlwhere["RAW_PNUM"] = raw(sprintf("%s in (select pn_p_id from pro_numidx where pn_type = 'none' and pn_pf_id in (2,5) and (%s))", $params['p_fined'], implode(" or ", $twhere)));
				$pnumwhere['pn_formart[=~]'] =$nums;
			}
			else
			{
				$sqlwhere["RAW_PNUM"] = raw(sprintf("%s in (select pn_p_id from pro_numidx where pn_type = 'none' and pn_pf_id in (2,5) and pn_formart in ('%s'))", $params['p_fined'], implode("','", $nums)));
				$pnumwhere['pn_formart'] =$nums;
			}
			return ['pnumwhere'=>$pnumwhere, 'sqlwhere'=>$sqlwhere];
		}
		return ['pnumwhere'=>$pnumwhere];
	}


	
	/**
	  * @method 变更某源的标签
	  * @param  $actType string [必填] add:只增加  del:只删除 replace:替换
	  * @param  $dataArr array [必填] 
				单个 ['t_id'=>[1,2,3,4]（string|array actType=replace空表示删除）, 'value_id'=>11]
				批量 [['t_id'=>[1,2,3,4]（string|array actType=replace空表示删除）, 'value_id'=>11],...]
	  * @author soul
	  */
	public function changeTagsLinkNumber($actType, $dataArr)
	{
		if(is_array($dataArr) && !empty($dataArr))
		{
			if(!empty($dataArr['value_id'])) $dataArr = [$dataArr];
			
			$where = [
				'tl_type'=>'number',
				'tl_value_id'=>array_unique(array_column($dataArr, 'value_id')),
			];
			
			$hasArr = [];
			$rows = $this->db->select('tags_link', ['tl_t_id', 'tl_value_id'], $where);
			$hasArr = array_column($rows, 'tl_t_id', 'tl_value_id');
			
			$newArr = [];
			foreach($dataArr as $v)
			{
				if(!is_array($v['t_id'])) $v['t_id'] = explode(',', $v['t_id']);
				$newArr[$v['value_id']] = [];
				foreach($v['t_id'] as $tid)
				{
					if($tid > 0)
						$newArr[$v['value_id']][] = $tid;
				}
			}
			//标签合并处理
			switch($actType)
			{
				case 'add':
					foreach($newArr as $valid=>$tidArr)
					{
						if(!empty($hasArr[$valid]))
						{
							$tl_t_id = addXor($tidArr, $hasArr[$valid]);
							$newArr[$valid] = explodeXor($tl_t_id);
						}
					}
				break;
				case 'del':
					foreach($newArr as $valid=>$tidArr)
					{
						if(!empty($hasArr[$valid]))
						{
							$tl_t_id = deleteXor($tidArr, $hasArr[$valid]);
							$newArr[$valid] = explodeXor($tl_t_id);
						}
						else
						{
							unset($newArr[$valid]);
						}
					}
				break;
				case 'replace': break;
			}
			$this->db->Begin();
			foreach($newArr as $pn_id=>$tidArr)
			{
				$this->setNumidxCell($pn_id, ['tags'=>implode(',', $tidArr)]);
			}
			$this->db->End();
		}
		return [];
	}




	/**
	  * @method 编辑正式参考号单字段
	  * @param  $pn_id  int  [必填] pn_id
	  * @param  $setArr  array  [必填] ['pn_cn_remark'=>'',....]
	  * @author soul
	  */
	public function setNumidxCell($pn_id, $setArr, $chkExists = true)
	{
		$canSetFiled = ['pn_mk_id'=>'OE生产商', 'pn_src'=>'数据来源', 'pn_cn_remark'=>'中文描述', 'pn_en_remark'=>'英文描述', 'pn_ref'=>'参考来源', 'tags'=>'数据标签', 'ckresult2'=>'复审结论','sale_coun'=>'适用国家'];
		if(!empty($pn_id) && !empty($setArr))
		{
			$list = $this->getList(['all'=>1,'pn_is_sys'=>0,'pn_type'=>'none','pn_id'=>$pn_id]);
			$old = $list['rows'][0];
			if(empty($old)) exitJson($pn_id.'记录不存在');

			$row = $this->db->get('pro', ['p_cate', 'p_innum', 'p_comnum'], ['p_id'=>$old['pn_p_id']]);
			if(!\p::catesEdit('E200', $row['p_cate'])) exitJson('无此小类权限');

			$pro = new pro();
			$chk = $pro->canSetPro($old['pn_p_id']);
			if(!empty($chk['msg'])) exitJson($chk['msg']);

			$this->db->Begin();
			$chageceilArr = [];
			
			foreach($setArr as $filed=>$val)
			{
				if(empty($canSetFiled[$filed]) || $val == $old[$filed] || (isset($old['captions'][$filed]) && $val == $old['captions'][$filed])) 
				{
					unset($setArr[$filed]);
					continue;
				}
				
			}

			$opuser = getOpuser();
			$datetime = getNowTime();
			if(!empty($setArr))
			{
				if(isset($setArr['pn_number']))
					$setArr['pn_formart'] = formatNum($setArr['pn_number']);
				if(isset($setArr['ckresult2']))
				{
					$setArr['ckuser2'] = $opuser;
					$setArr['cktime2'] = $datetime;
				}
				if($chkExists)
				{
					$chkdata = array_merge($old, $setArr);
					$exists = $this->checkExist($chkdata, $pn_id);
					if(!empty($exists)) exitJson($exists['msg']);
				}
				$setArr['opuser'] = $opuser;
				$setArr['update_time'] = $datetime;
				$this->db->update('pro_numidx', $setArr, ['pn_id'=>$pn_id]);
			}
			make(\model\pro\pro::class)->addProSynLog([$old['pn_p_id']], 'set', 'text');
			$this->db->End();
		}
		return [];
	}


	/**
	  * @method 删除产品的参考号
	  * @param  $idArr array  [必填] pn_id
	  * @param  $delremark string  [必填] 变更原因
	  * @author soul
	  */
	public function delNumidx($idArr, $delremark)
	{
		$list = $this->getList(['all'=>1,'pn_type'=>'none', 'pn_id'=>$idArr]);
		$numArr = $list['rows'];
		if(empty($numArr)) exitJson('记录不存在');
		//if(empty($delremark)) exitJson('删除原因必填');

		$check = new check();
		$proCateRule = $check->checkProRuleCate(array_column($numArr, 'pn_p_id'), 'E200', 'delete');
		if(!empty($proCateRule['no'])) exitJson('无此小类权限');
		
		//检测OE是否被使用为主OE
		$rows = $this->db->select('pro_numidx', ['pn_p_id', 'pn_formart'], ['pn_type'=>'none', 'pn_pf_id'=>1, 'pn_id'=>$idArr]);
		foreach($rows as $v){
			$has = $this->db->get('pro_numidx', ["[><]pro" => ["pn_p_id"=>"p_id"]], ['p_innum', 'pn_number'], ['pn_ismain'=>1, 'p_lnk_p_id'=>$v['pn_p_id'], 'pn_formart'=>$v['pn_formart']]);
			if($has['pn_number']) exitJson($has['pn_number'].'已被'.$has['p_innum'].'使用为主OE，禁止删除');
		}

		$oldArr = $this->db->select('pro_numidx','*' ,['pn_type'=>'none', 'pn_id'=>$idArr]);
		$this->db->Begin();

		$this->db->delete('pro_numidx', ['pn_type'=>'none', 'pn_id'=>$idArr]);

		//日志记录
		$logdata = [];
		foreach ($oldArr as $item) {
			$changeArr[$item['pn_p_id']][] = $item; 
		}
		foreach ($changeArr as $pid => $changeItem) {
			$arr['num'] = $changeItem;
			$logdata[] = [
				'cl_type'=>'pro',
				'cl_act'=>'del',
				'cl_dataid'=>$pid,
				'cl_change'=>json_encode($arr, JSON_UNESCAPED_UNICODE),
				'cl_opuser'=>getOpuser(),
				'cl_create_time'=>getNowTime(),
			];
		}
		
		if($logdata) $this->db->insert('change_log',$logdata);
		make(\model\pro\pro::class)->addProSynLog(array_column($numArr, 'pn_p_id'), 'set', 'text');
		$this->db->End();
		return [];
	}

  
	/**
	 * @method 添加 交叉库
	* @param  $dataArr  array  [必填] ['pn_number'=>'', 'pn_mk_id'=>'',....]
	* @author soul
	*/
	public function addNumidx($dataArr)
	{
		$fileds = ['pn_p_id','pn_innum', 'pn_pf_id', 'pn_number', 'pn_mk_id'];
		$baseArr = [];
		$othArr = [];
		foreach($dataArr as $filed=>$v)
		{
			if(in_array($filed, $fileds))
			{
				$baseArr[$filed] = $v;
			}
			else
			{
				$othArr[$filed] = $v;
			}
		}
		$pro = new pro();
		//确认产品ID
		if(empty($baseArr['pn_p_id'])){
			$pid = $pro->getLinkPidByInnum($baseArr['pn_innum']);
			if(empty($pid)) exitJson('', '物料编码不存在');
			$baseArr['pn_p_id'] = $pid;
		}
		unset($baseArr['pn_innum']);
		
		$baseArr['pn_formart'] = formatNum($baseArr['pn_number']);
		if(empty($baseArr['pn_pf_id'])) exitJson('号码厂商必填');
		if(empty($baseArr['pn_formart'])) exitJson('号码必填');
		
		$exists = $this->checkExist($baseArr);
		if(!empty($exists)) exitJson($exists['msg']);

		$opuser = getOpuser();
		$datetime = getNowTime();
		$baseArr['opuser'] = $opuser;
		$baseArr['create_time'] = $datetime;
		$baseArr['update_time'] = $datetime;
		
		//初审人
		if(!empty($baseArr['ckresult1']) || !empty($baseArr['ckremark1']))
		{
			$baseArr['ck1'] = 1;
			$baseArr['ckuser1'] = $opuser;
			$baseArr['cktime1'] = $datetime;
		}
		$this->db->Begin();
		$this->db->insert('pro_numidx', $baseArr);
		$pn_id = $this->db->id();

		$pro->addProSynLog([$baseArr['pn_p_id']], 'set', 'text');
		$this->db->End();
		return ['pn_id'=>$pn_id];
	}
  
}