<?php    
    /**
    * Created by PhpStorm.
    * User: Administrator
    * Date: 2017/3/9
    * Time: 19:16
    */
    namespace searchapi\controllers;
     
    use Yii;
    use yii\web\Controller;
    use searchapi\models\CarBrandInfo;
    use searchapi\models\CarBrandType;
    use searchapi\models\CarBrandTypeInfo;
    use searchapi\models\CarBrandSonTypeInfo;
    use searchapi\models\CarFactory;
    use yii\data\Pagination;
    use yii\helpers\BaseJson;
    use Elasticsearch;
     
    class QueryController extends Controller
    {
     
        private static $debug =false; //是否调试
        const ES_INDEX ='ccindex';
        const ES_TYPE ='cctype';
         
        public function beforeAction($action)
        {
            //echo md5('1502267488'.'ECCBC87E4B5CE2FE28308FD9F2A7BAF3');exit;#73d79682dd9d40aa9f9bab9c3558ccd1
            $time = Yii::$app->request->get('time');
            $token = Yii::$app->request->get('token');
            self::$debug =Yii::$app->request->get('debug','false');
         
            $result = [
            'data' =>[],
            'msg' =>'',
            'status' =>1,
            ];
            //判断验证
            if(empty($time) || empty($token)){
                $result['status'] =0;
            $result['msg'] ='缺少验证';
            }
            elseif(time()-600>$time){
                $result['status'] =0;
            $result['msg'] ='请求超时';
            }elseif($token!=md5($time.\CEnv::TOKEN_SALT)){
                $result['status'] =0;
                $result['msg'] ='token错误';
            }
         
        if($result['status']==0){
            self::returnResult($result);
        }else{
            return parent::beforeAction($action); // TODO: Change the autogenerated stub
        }
     
    }
     
    /**
    * @inheritdoc
    */
    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
        ];
    }
     
    /**
    * 关键词查询文章
    */
    public function actionQuery(){
     
        $result = [
            'data' =>[],
            'msg' =>'',
            'status' =>1,
        ];
        $keywords =Yii::$app->request->get('keywords'); //关键词
        $limit = Yii::$app->request->get('limit',10); //取的数量
        $page = Yii::$app->request->get('page',1); //页数
        $version = Yii::$app->request->get('version','v2.0'); //兼顾app老版本,v1.0老版本只能查news
         
         
        $key = 'search:'.$version.":".$keywords.":".$page.":".$limit;
        $rtnData = Yii::$app->cache->get($key);
        if($rtnData === false){
         
        $offset = ($page-1)*$limit;
        if(!$keywords){
            $result = array('msg'=>'参数为空','status'=>0);
        }
         
        $param = [
            'index'=>self::ES_INDEX,
            'type'=>self::ES_TYPE,
            'keywords'=>$keywords,
            'offset'=>$offset,
            'limit'=>$limit,
            'fields'=>['_id']
        ];
        if($version == 'v1.0'){ //只能查询news
            $result['data'] = $this->queryEsnews($param);
        }else{
            $result['data'] = $this->queryEs($param);
        }
         
         
         
            $rtnData = $result;
            if($result){
                Yii::$app->cache->set($key,$rtnData,3600*24);
            }
        }
         
        self::returnResult($rtnData);
    }
     
     
   
     
     /**
      * 查询es news 和自媒体都有
      * @param $param
      * @return array
      */
     private function queryEs($param){

          //实例化es 配置
          $client = Elasticsearch\ClientBuilder::create()
               # ->setHosts(["localhost:9200"])
               #->setHosts(["101.37.85.163:9200"])
               ->setHosts([\CEnv::ES_API])
               ->setRetries(1)
               ->build();

          #$index = 'che_article';
          #$type = 'car_archives';
          $index = $param['index'];
          $type = $param['type'];
          $keywords = $param['keywords'];
          $from = $param['offset'];
          $size = $param['limit'];
          $fields = $param['fields'];

          $params = [
               'index' =>$index,
               'type' => $type,
               #'analyzer' => 'elasticsearch-analysis-ik',
               'from'=>$from, //offset
               'size'=>$size, //limit
               //'analyzer'=>'ik',
               'body' => [
                    'query' => [
                         'bool'=>[
                              "should"=>[
                                   [
                                        'match'=>[
                                             'title'=>[
                                                  'query'=>$keywords,
                                                  'boost'=>4,
                                             ]
                                        ]
                                   ],
                                   [
                                        'match'=>[
                                             'content'=>[
                                                  'query'=>$keywords,
                                                  'boost'=>1,
                                             ]
                                        ]
                                   ],

                              ],
                              /*'must'=>[
                              [
                              'match' => [
                              'status' => [
                              'query'=>0,
                              ],
                              ]
                              ],
                              ],*/

                              'filter'=>[
                                   "range"=>[
                                        "inputtime"=>[
                                             "gte"=>time()-7776000,
                                             //"gte"=>time()-31104000,
                                             "lte" =>time(),
                                        ],
                                   ]
                              ]
                         ],
                         // 'analyzer' => 'ik',
                    ],
                    'sort'=>[
                         '_score'=>[
                              'order'=>'desc',
                         ],
                         'inputtime'=>[
                              'order'=>'desc',
                         ],
                         /*'id'=>[
                         'order'=>'desc',
                         ],*/
                    ],
                    'min_score'=>0.3
               ],
               #'fields'=>$fields
          ];

          $results = $client->search($params);


          $data=array();
          if(!empty($results['hits']))
          {
               $data['total']=($results['hits']['total']>500?500:$results['hits']['total']);
               foreach ($results['hits']['hits'] as $key=>$value)
               {
                    $data['item'][]=[
                         'id'=>$value['_source']['id'],
                         'score'=>$value['_score'],
                         'title'=>$value['_source']['title'],
                         'description'=>$value['_source']['description'],
                         'inputtime'=>date('Y-m-d H:i:s',$value['_source']['inputtime']),
                         'type'=>$value['_source']['type'],
                    ];

                    #$data['idx'][]=$value['_id'];
               }
          }

          return $data;
     }
    
     /**
     *
     * 下拉关联的搜索
     */
    public function actionRelation(){
         $result = [
              'data' =>[],
              'msg' =>'',
              'status' =>1,
         ];
         //$data = [];
    
         $keywords = $this->formateKeywords(Yii::$app->request->get('keywords')); //关键词
         $limit = Yii::$app->request->get('limit',10); //取的数量
    
         if(!$keywords){
              $result = array('msg'=>'参数为空','status'=>0);
         }else{
              $result = $this->getRelation($keywords,$limit);
         }
         self::returnResult($result);
    
         //缓存量太大
         /*$key = 'search:relation:'.$keywords.":".$limit;
         $rtnData = Yii::$app->cache->get($key);
         if($rtnData === false){
         $result = $this->getRelation($keywords,$limit);
          
         $rtnData = $result;
         if($result){
         Yii::$app->cache->set($key,$rtnData,3600*24);
         }
         }*/
    }
    
    private function getRelation($keywords='',$limit=10){
         $result = [
              'data' =>[],
              'msg' =>'',
              'status' =>1,
         ];
         $data = [];
         //先判断是否完全匹配车系
         $info = $this->isChexi($keywords);
         if($info){
              $data[] = ['id'=>$info['car_brand_type_id'],'name'=>$info['car_brand_type_name'],'level'=>3,'type'=>''];
              $data[] = ['id'=>$info['car_brand_type_id'],'name'=>$info['car_brand_type_name']."资讯",'level'=>3,'type'=>'news'];
              $data[] = ['id'=>$info['car_brand_type_id'],'name'=>$info['car_brand_type_name']."图片",'level'=>3,'type'=>'photo'];
              $data[] = ['id'=>$info['car_brand_type_id'],'name'=>$info['car_brand_type_name']."报价",'level'=>3,'type'=>'price'];
              $data[] = ['id'=>$info['car_brand_type_id'],'name'=>$info['car_brand_type_name']."参配",'level'=>3,'type'=>'param'];
              $data[] = ['id'=>$info['car_brand_type_id'],'name'=>$info['car_brand_type_name']."口碑",'level'=>3,'type'=>'koubei'];
    
              $result['data'] = $data;
              return $result;
         }
    
         //判断是否完全匹配品牌
         $info = $this->isBrand($keywords);
         if($info){
              $brandId = $info['brand_id'];
              $data[] = ['id'=>$info['brand_id'],'name'=>$info['brand_name'],'level'=>1,'type'=>''];
              //查询该品牌下的最热5个车系
              $brandTypeInfoArr = CarBrandTypeInfo::getChexiByBrandId($brandId,($limit-1));
              foreach ($brandTypeInfoArr as $k=>$v){
                   $data[] = ['id'=>$v['car_brand_type_id'],'name'=>$v['car_brand_type_name'],'level'=>3,'type'=>''];
              }
              #echo json_encode($result);exit;
              $result['data'] = $data;
              return $result;
    
         }
    
    
         //判断是否是厂商
         $info = $this->isFactory($keywords);
         if($info){
              $data[] = ['id'=>$info['brand_type_id'],'name'=>$info['brand_type'],'level'=>2,'type'=>''];
              //如果完全品牌厂商则获取厂商下的车系
              $factoryId = $info['brand_type_id'];
    
              $brandTypeInfoArr = CarBrandTypeInfo::getBrandTypeInfoByFactoryId($factoryId,$limit-1);
              foreach ($brandTypeInfoArr as $k=>$v){
                   $data[] = ['id'=>$v['car_brand_type_id'],'name'=>$v['car_brand_type_name'],'level'=>3,'type'=>''];
              }
              #echo json_encode($result);exit;
              $result['data'] = $data;
              return $result;
         }
    
    
         //如果都不完全匹配,先品牌、再厂商、最后车系
         $brandArr = CarBrandInfo::getBrandInfoLikeName($keywords,$limit);
         foreach ($brandArr as $k=>$v){
              $data[] = ['id'=>$v['brand_id'],'name'=>$v['brand_name'],'level'=>1,'type'=>''];
         }
    
         $factoryArr = CarFactory::getFactoryLikeName($keywords,$limit);
         foreach ($factoryArr as $k=>$v){
              $data[] = ['id'=>$v['brand_type_id'],'name'=>$v['brand_type'],'level'=>2,'type'=>''];
         }
         $brandTypeInfoArr = CarBrandTypeInfo::getBrandTypeInfoLikeName($keywords,$limit);
         foreach ($brandTypeInfoArr as $k=>$v){
              $data[] = ['id'=>$v['car_brand_type_id'],'name'=>$v['car_brand_type_name'],'level'=>3,'type'=>''];
         }
         $data = array_slice($data,0, $limit);
         $result['data'] = $data;
         return $result;
    
    }   
     
    /**
    * 更新es 文章状态
    * @return bool
    */
    public function actionUpdate(){
     
    $ids = Yii::$app->request->get('ids'); //文章id
    $status = Yii::$app->request->get('status',0); //默认审核通过 0通过-1审核没通过
    if(empty($ids)) return false;
     
    $idArray=explode(',',$ids);
    //实例化es 配置
    $client = Elasticsearch\ClientBuilder::create()
    ->setHosts([\CEnv::ES_API])
    ->setRetries(1)
    ->build();
     
    foreach ($idArray as $v){
    $params = [
    'index' => self::ES_INDEX,
    'type' => self::ES_TYPE,
    'id' => $v,
    ];
    if($client->exists($params)==true){
    $params['body']=[
    'doc'=>[
    'status' => $status
    ]
    ];
    $response = $client->update($params);
    }
    }
    }
     
    /**
    * 删除es文章
    * @return bool
    */
    public function actionDelete(){
    $ids = Yii::$app->request->get('ids'); //文章id
    if(empty($ids)) return false;
    $idArray=explode(',',$ids);
     
    //实例化es 配置
    $client = Elasticsearch\ClientBuilder::create()
    ->setHosts([\CEnv::ES_API])
    ->setRetries(1)
    ->build();
     
    foreach ($idArray as $v){
    $params = [
    'index' => self::ES_INDEX,
    'type' => self::ES_TYPE,
    'id' => $v,
    ];
    if($client->exists($params)==true)
    $client->delete($params);
    }
    }
     
    //是不是完全品牌
    private function isBrand($keywords=''){
    $data = [];
    $data = CarBrandInfo::getBrandInfoBykeywords($keywords);
     
    if(!$data){
    $brandArr = CarBrandInfo::getBrandInfoLikeName($keywords);
    //判断是不是唯一匹配品牌
    if(count($brandArr) == 1){
    $data = $brandArr[0];
    }
    }
    return $data;
     
    }
    //是不是完全厂商
    private function isFactory($keywords=''){
    return CarFactory::getFactoryBykeywords($keywords);
    }
    //是不是完全车系
    private function isChexi($keywords=''){
    return CarBrandTypeInfo::getChexiBykeywords($keywords);
     
    }
     
    //白名单,卡宴&mdash;Cayenne 帕拉梅拉&mdash;Panamera,车系是英文
    private function formateKeywords($keywords=''){
    $keywordsArr = ['卡宴'=>'Cayenne','帕拉梅拉'=>'Panamera'];
    if(key_exists($keywords,$keywordsArr)){
    $keywords = $keywordsArr[$keywords];
    }
    return $keywords;
    }
     
    //返回结果
    private static function returnResult($result = []){
    if(self::$debug =='false'){
    echo json_encode($result);Yii::$app->end();
    }else{
    echo "<pre>";print_r($result);Yii::$app->end();
    }
    }
     
    }