<?php

namespace app\common\model\score;

use app\common\model\BaseModel;
use think\Model;
use traits\model\SoftDelete;

class Log extends BaseModel
{

    use SoftDelete;

    

    // 表名
    protected $name = 'score_log';
    
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'integer';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';

    // 追加属性
    protected $append = [
        'status_text',
        'authtime_text',
        'createtime_text'
    ];

    public function getCreatetimeTextAttr($value, $data)
    {
        $value = $value ?: ($data['createtime'] ?? '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }

    
    public function getStatusList()
    {
        return ['0' => __('Status 0'), '1' => __('Status 1'), '2' => __('Status 2')];
    }


    public function getStatusTextAttr($value, $data)
    {
        $value = $value ?: ($data['status'] ?? '');
        $list = $this->getStatusList();
        return $list[$value] ?? '';
    }


    public function getAuthtimeTextAttr($value, $data)
    {
        $value = $value ?: ($data['authtime'] ?? '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }

    protected function setAuthtimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }


    public function scoreevent()
    {
        return $this->belongsTo('Event', 'score_event_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }


    public function employee()
    {
        return $this->belongsTo('Employee', 'score_employee_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }


    public function user()
    {
        return $this->belongsTo('app\admin\model\User', 'user_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }


    public function team()
    {
        return $this->belongsTo('Team', 'score_team_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }



    public function getImagesAttr($value, $data)
    {
        $imagesArray = [];
        if (!empty($value)) {
            $imagesArray = explode(',', $value);
            foreach ($imagesArray as &$v) {
                $v = cdnurl($v, true);
            }
            return $imagesArray;
        }
        return $imagesArray;
    }

    public function setImagesAttr($value, $data)
    {
        $imagesArray = $value;
        if (!empty($value) && is_array($value)) {
            //转成逗号拼接字符串
            $imagesArray = implode(',', $value);
        }
        return $imagesArray;
    }




    /** 通用新增(后台api版本)
     * @param $params
     * @param $trans
     * @return $this
     * @throws \Exception
     */
    public function add($params,$check  = true,$trans=false){

        if (empty($params)) {
            throw new \Exception(__('Parameter %s can not be empty', ''));
        }

        if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
            $params[$this->dataLimitField] = $this->auth->id;
        }
//判断逻辑
        if($trans){
            self::beginTrans();
        }
        $res = true;
        try{
            $user_id = $params["user_id"]??0;
            $score_event_id = $params["score_event_id"]??0;
            $score_employee_id  = $params["score_employee_id"]??0;
            $employee = null;
            if($score_employee_id){
                //判断是否是员工
                $employee =  Employee::where("id",$score_employee_id)->find();
                if(!$user_id){
                    $user_id = $employee["user_id"];
                    $params["user_id"] = $user_id;
                }
            }
            if($score_event_id){
                $score_event = Event::where("id",$score_event_id)->find();
                if(!$score_event) throw new \Exception(__('积分项不存在'));
                 $way = explode(",",$score_event["way"]);
                 if($check){
                     if(!in_array( "free",$way))throw new \Exception(__('该积分项不允许申请'));
                     if(!empty( $params["score"])) throw new \Exception(__('积分项不允许手动输入'));
                     if(!empty( $params["name"])) throw new \Exception(__('积分项名稱不允许手动输入'));

                 }

                 //进行频次判断
                switch ($score_event["frequency"]){
                     case "day":
                         $count = self::where("score_event_id",$score_event_id)
                             ->where("user_id",$user_id)
                             ->where("status","in",[0,1])
                             ->whereTime("createtime","today")
                             ->count();
                         if($score_event["max_times"] > 0 && $count >= $score_event["max_times"]){
                             throw new \Exception(__('积分项在期限内已申请上限，请明日再尝试！'));
                         }

                         $score = self::where("score_event_id",$score_event_id)
                             ->where("user_id",$user_id)
                             ->where("status","in",[0,1])
                             ->whereTime("createtime","today")
                             ->sum( "score");
                         if($score_event["monthly_highest_score"] > 0 && $score >= $score_event["monthly_highest_score"]){
                             throw new \Exception(__('积分项在期限内已申请上限，请明日再尝试！'));
                         }


                         break;
                    case "week":
                         $count = self::where("score_event_id",$score_event_id)
                             ->where("user_id",$user_id)
                             ->where("status","in",[0,1])
                             ->whereTime("createtime","week")
                             ->count();
                        if($score_event["max_times"] > 0 && $count >= $score_event["max_times"]){
                            throw new \Exception(__('积分项在期限内已申请上限，请明日再尝试！'));
                        }

                        $score = self::where("score_event_id",$score_event_id)
                            ->where("user_id",$user_id)
                            ->where("status","in",[0,1])
                            ->whereTime("createtime","week")
                            ->sum( "score");
                        if($score_event["monthly_highest_score"] > 0 && $score >= $score_event["monthly_highest_score"]){
                            throw new \Exception(__('积分项在期限内已申请上限，请明日再尝试！'));
                        }

                        break;
                    case "month":
                        $count = self::where("score_event_id",$score_event_id)
                            ->where("user_id",$user_id)
                            ->where("status","in",[0,1])
                            ->whereTime("createtime","month")
                            ->count();
                        if($score_event["max_times"] > 0 && $count >= $score_event["max_times"]){
                            throw new \Exception(__('积分项在期限内已申请上限，请明日再尝试！'));
                        }

                        $score = self::where("score_event_id",$score_event_id)
                            ->where("user_id",$user_id)
                            ->where("status","in",[0,1])
                            ->whereTime("createtime","month")
                            ->sum( "score");
                        if($score_event["monthly_highest_score"] > 0 && $score >= $score_event["monthly_highest_score"]){
                            throw new \Exception(__('积分项在期限内已申请上限，请明日再尝试！'));
                        }

                        break;
                    case "once":
                        $count = self::where("score_event_id",$score_event_id)
                            ->where("status","in",[0,1])
                            ->where("user_id",$user_id)->count();
                        if($score_event["max_times"] > 0 && $count >= $score_event["max_times"]){
                            throw new \Exception(__('积分项已申请上限，无法再申请！'));
                        }

                        $score = self::where("score_event_id",$score_event_id)
                            ->where("user_id",$user_id)
                            ->where("status","in",[0,1])
                            ->sum( "score");
                        if($score_event["monthly_highest_score"] > 0 && $score >= $score_event["monthly_highest_score"]){
                            throw new \Exception(__('积分项已申请上限，无法再申请！'));
                        }


                        break;


                }



                $params["name"] = $params["name"] ?? "";
                $params["score"] = $params["score"] ?? "";


                $params["name"]  = $params["name"] ?: $score_event["name"];
                $params["score"] = $params["score"] ?: $score_event["score"];
            }

            if(!$user_id) throw new \Exception(__('用户需登录'));
            //判断是否是员工
            if(!$employee)$employee =  Employee::where("user_id",$user_id)->find();
            if(!$employee) throw new \Exception(__('用户不是员工'));
//            if(!$employee["team_id"])throw new \Exception(__('用户未加入队伍！'));
//            $team = Team::where("id",$employee["team_id"])->find();
//            if(!$team)throw new \Exception(__('用户未加入队伍！'));

            if(!$params["images"] || !$params["name"] || !$params["score"])throw new \Exception(__('缺少关键申请参数！'));


            $params["score_employee_id"] = $employee["id"];
            $params["score_event_id"] = $score_event_id;
            $params["score_team_id"] = $team["id"] ?? 0;

            $params["status"] = $params["status"] ?? 0;
            $params["authtime"] = $params["status"] != 0 ? time() : NULL;
            $params["reason"] =  $params["reason"] ?? "";

            //如果审核失败，需要填写原因
            if ($params["status"] == 2) {
                if (!$params['reason']) {
                    $this->error('审核失败，请填写原因');
                }
            }

            //是否采用模型验证
            if ($this->modelValidate) {
                $name = str_replace("\\model\\", "\\validate\\", get_class($this));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
                $this->validateFailException()->validate($validate);
            }

            $result = $this->allowField(true)->save($params);

            if($trans){
                self::commitTrans();
            }
        }catch (\Exception $e){
            if($trans){
                self::rollbackTrans();
            }
            throw new \Exception($e->getMessage());
        }
        return $this;
    }





    /**得到基础条件
     * @param $status
     * @param null $model
     * @param string $alisa
     */
    public static function getBaseWhere($whereData = [], $model = null, $alisa = '',$with = false)
    {

        if (!$model) {
            $model = new static;
            if ($alisa&&!$with) $model = $model->alias($alisa);
        }
        if ($alisa) $alisa = $alisa . '.';
        $tableFields = (new static)->getTableFields();
        foreach ($tableFields as $fields)
        {
            if(in_array($fields, ['status']))continue;
//            if (isset($whereData[$fields]) && $whereData[$fields]) $model = $model->where("{$alisa}{$fields}", '=', $whereData[$fields]);

            if (isset($whereData[$fields]) && $whereData[$fields]){
                if(is_array($whereData[$fields])){
                    $model = $model->where("{$alisa}{$fields}", $whereData[$fields][0], $whereData[$fields][1]);
                }else{
                    $model = $model->where("{$alisa}{$fields}", '=', $whereData[$fields]);
                }

            }


        }


        if (isset($whereData['keywords'])&&$whereData['keywords']){
            if($with){

                $model = $model->where( function($query) use($whereData,$alisa,$with){
                    $query = $query->where("{$alisa}name|{$alisa}desc|{$alisa}reason", '=', $whereData['keywords']);
                    if(in_array('user',$with)){
                        $query = $query->whereOr("user.nickname|user.mobile", 'like', "%". $whereData['keywords']."%");
                    }
                    if(in_array('scoreevent',$with)){
                        $query = $query->whereOr("scoreevent.event_name|scoreevent.name|scoreevent.desc", 'like', "%". $whereData['keywords']."%");
                    }
                    if(in_array('employee',$with)){
                        $query = $query->whereOr("employee.name", 'like', "%". $whereData['keywords']."%");
                    }
                    if(in_array('team',$with)){
                        $query = $query->whereOr("team.name", 'like', "%". $whereData['keywords']."%");
                    }

                });
            }else{
                $model = $model->where("{$alisa}name|{$alisa}desc|{$alisa}reason", '=', $whereData['keywords']);
            }
        }

        if (isset($whereData['status']) && $whereData['status']!=="" && $whereData['status']!==null){
            $model = $model->where("{$alisa}status","in",$whereData['status']);
        }


        if (isset($whereData['time'])&&$whereData['time']){
            $model = $model->time(["{$alisa}createtime",$whereData['time']]);
        }

//        if (isset($whereData['has_evaluate'])&&$whereData['has_evaluate']){
//            //1查已评价 2查未评价
//            if($whereData['has_evaluate'] == 1){
//                //1查已评价
//                $model = $model->where("{$alisa}classes_evaluate_id", '<>', 0);
//            }else{
//                //2查未评价
//                $model = $model->whereExists(function ($query) use ($alisa) {
//                    $order_table_name = (new \app\common\model\school\classes\hourorder\Order())->getQuery()->getTable();
//                    $query->table($order_table_name)->where($order_table_name . '.classes_order_id=' . $alisa . 'id')->where('status', '=', '3');
//                })->where("{$alisa}classes_evaluate_id", '=', 0);
//
//            }
//        }

        return $model;
    }






    public static function allList($page, $limit,$keywords,$params=[]){
        $with_field = [
            'user'=>['nickname','mobile','avatar'],
            'scoreevent'=>['*'],
            'employee'=>['name',"image"],
            'team'=>['name',"image"],
            'base'=>['*'],
        ];

        $alisa = (new self)->getWithAlisaName();
        $sort = "{$alisa}.id desc";

//        $sort = "weigh desc,id desc";
        $serch_where = ['keywords'=>$keywords];

        return (new self)->getBaseList(array_merge($serch_where,$params), $page, $limit,$sort,$with_field);
    }
    
    
    public static function statistics($user_id=null,$time=null){
        if(!$time) $time = time();
        //得到当前时间戳指向的月开始和结束时间戳
        $month_start = strtotime(date('Y-m-01 00:00:00', $time)); // 月初
        $month_end = strtotime(date('Y-m-t 23:59:59', $time));    // 月末

//        var_dump($month_start,$month_end);


        //统计当前所有员工积分
        $employees = Employee::where("status","entry")->select();
        $employee_score = [];
        $team_score = [];
        //自己的积分
        $my_employee_score = null;
        //自己团队的积分
        $my_team_score = null;
        $my_team_id = null;


//        var_dump($user_id);

        foreach ($employees as $employee){
            //统计当前员工积分
            $score = self::where("score_employee_id",$employee['id'])
                ->where("createtime",">=",$month_start)
                ->where("createtime","<=",$month_end)
                ->where("status","1")
                ->sum('score');
            $employeedata = [
                'id'=>$employee['id'],
                'name'=>$employee['name'],
                'image'=>$employee['image'],
                'score'=>$score
            ];
            $employee_score[$employee['id']] = $employeedata;
            if($user_id && $user_id == $employee['user_id']){

                $my_employee_score = $employeedata;
                $my_team_id = $employee['team_id'];
            }


          if($employee['team_id'] && $employee['team']){
            if(!isset($team_score[$employee['team_id']])){
                $team_data = [
                    'id'=>$employee['team_id'],
                    'name'=>$employee['team']['name'],
                    'image'=>$employee['team']['image'],
                    'score'=>$score
                ];
                $team_score[$employee['team_id']] = $team_data;
            }else{
                //累加积分
                $team_score[$employee['team_id']]['score'] += $score;
            }
          }
        }
        //自己团队的积分
        if($my_team_id){
            $my_team_score = $team_score[$my_team_id] ?? 0;
        }



        //清除各自键
        $employee_score = array_values($employee_score);
        $team_score = array_values($team_score);

        //根据$employee_score 查询当前时间戳所在月份的个人排行前10
//        $employee_rank = array_slice(array_values(array_sort($employee_score, 'score', 'desc')),0,10);
// 对员工积分进行降序排序
        usort($employee_score, function ($a, $b) {
            return $b['score'] <=> $a['score'];
        });
        $employee_rank = array_values($employee_score);

// 对团队积分进行降序排序
        usort($team_score, function ($a, $b) {
            return $b['score'] <=> $a['score'];
        });
        $team_rank = array_values($team_score);
        //查询当前时间戳个人所在月积分
        //查询当前时间戳个人所在队伍总积分


        return  [
            'my_employee_score'=>$my_employee_score,
            'my_team_score'=>$my_team_score,
            'employee_rank'=>$employee_rank,
            'team_rank'=>$team_rank
        ];
    }






}
