<?php
namespace app\common\model;
use think\Exception;
use think\Db;
class PatrolTask extends Base {

    public function updates($mode){
        $post = request()->post();

        $validate = new \app\common\validate\PatrolTask();
        $result = $validate->check($post,[]);
        if(true !== $result){
            $this->error = $validate->getError();
            return false;
        }

        $addrs = json_decode($post['addrs'],true);
        if(empty($addrs)){
            $this->error='未设置地点';
            return false;
        }
        foreach ($addrs as $k=>$v){
            if($v['addrId'] <= 0 || count($v['forms']) <= 0){
                $this->error='地点设置错误';
                return false;
            }
        }

        if(!$post['user_ids']){
            $this->error='检查人员不能为空';
            return false;
        }
        if(strtotime($post['start_time']) < time()){
            $this->error = '开始时间不能小于当前时间';
            return false;
        }
        if($post['start_time'] >= $post['end_time']){
            $this->error = '结束时间请大于开始时间';
            return false;
        }
        if($post['id'] <= 0){
            $this->error = '参数错误';
            return false;
        }
        //编辑操作
        $curtime = date('Y-m-d H:i:s');
        $data = array(
            'title' => $post['title'],
            'update_time' => $curtime,
            'start_time' => $post['start_time'],
            'end_time' => $post['end_time'],
            'create_yyyymm' => date('Ym',strtotime($post['start_time'])),
            'create_yyyy' => date('Y',strtotime($post['start_time'])),
            'create_yyyymmdd' => date('Ymd',strtotime($post['start_time'])),
            'in_order' => $post['in_order'],
            'cate_id' => isset($post['cate_id'])?$post['cate_id']:0,
            'lines' => $post['in_order'] == 1&&$post['lines']?$post['lines']:''
        );

        Db::startTrans();
        try {
            //编辑任务
            $res = Db::name('patrol_task')->where('id',$post['id'])->update($data);
            if(!$res){
                exception('编辑任务失败');
            }

            Db::name('patrol_task_addr')->where('patrol_task_id',$post['id'])->delete();
            Db::name('patrol_task_user')->where('patrol_task_id',$post['id'])->delete();

            // 重新添加地点及表单
            $nforms = [];
            foreach ($addrs as $key=>$val){
                $pfms = [];
                foreach ($val['forms'] as $kk=>$vv){
                    $pfms[] = $vv['id'];
                }
                $nforms[] = [
                    'patrol_task_id' => $post['id'],
                    'address_id' => $val['addrId'],
                    'patrol_forms' => implode(',',$pfms),
                    'sorts' => $val['sorts'],

                ];
            }
            $fromRet = Db::name('patrol_task_addr')->insertAll($nforms);
            if($fromRet != count($nforms)){
                \exception('操作失败');
            }

            // 重新添加用户
            $uds = [];
            $users = explode(',',$post['user_ids']);
            foreach ($users as $key=>$val){
                $uds[] = [
                    'patrol_task_id' => $post['id'],
                    'user_id' => $val
                ];
            }
            $userRet = Db::name('patrol_task_user')->insertAll($uds);
            if($userRet != count($uds)){
                \exception('操作失败');
            }

            Db::commit();
            return true;
        }catch (\Exception $e){
            $this->error = $e->getMessage();
            Db::rollback();
            return false;
        }

    }

    /**
     * 格式化时间,获取时间数组
     * @param $starttime 开始时间
     * @param $endtime 结束时间
     * @param $hours 重复小时
     * @param $days 执行天数
     * @return array
     */
    private function get_time_arr($starttime,$endtime,$hours,$days){
        $onehour = 60*60;
        $oneday = 24*60*60;
        $start = strtotime($starttime);
        $end = strtotime($endtime);
        $ctime = $end - $start;
        $timearr = array();

        $timearr[] = array(
            'start_time' => $starttime,
            'end_time' => $endtime,
        );
        if($hours > 0){
            if($ctime > $hours*$onehour){
                $timearr = array(); //置空
                $i = $hours;
                while(true){
                    $nend = $start + $i*$onehour;
                    $nstart = $start + ($i-$hours)*$onehour;
                    $timearr[] = array(
                        'start_time' => date('Y-m-d H:i',$nstart),
                        'end_time' => date('Y-m-d H:i',$nend),
                    );
                    if($nend >= $end){
                        break;
                    }
                    $i += $hours;
                }
            }
        }

        if($days > 0){
            $timearray = $timearr;
            for ($i=1; $i<=$days;$i++){
                foreach ($timearray as $k=>$v){
                    $timearr[] = array(
                        'start_time' => date('Y-m-d H:i',strtotime($v['start_time']) + $i*$oneday),
                        'end_time' => date('Y-m-d H:i',strtotime($v['end_time']) + $i*$oneday),
                    );
                }
            }
        }
        return $timearr;
    }

    //获取巡查计划任务
    public function getTaskOne($taskId){
        $ret=Db::name('patrol_task')->where('id',$taskId)->find();
        //获取计划任务检查组id
        $old_addrs=Db::name('patrol_task_addr')
            ->where('patrol_task_id',$ret['id'])->select();
        foreach ($old_addrs as $k=>$v){
            $ids[$k]=$v['patrol_addr_form_id'];
        }
        $ret['old_addrs']=$ids;
        //获取计划任务检查人员
        $old_user_ids=Db::name('patrol_task_user')->where('patrol_task_id',$ret['id'])->column('user_id');
        $ret['old_user_ids']=$old_user_ids;
        return $ret;
    }

    //api接口
    public function lists($page,$size,$type,$userId,$orgId,$patrol_mode,$status){
        $ret['list']=[];
        if($type == 1){ // 待完成
            $map[] = ['t.user_id','=',$userId];
            $map[] = ['t.org_id','=',$orgId];
            $map[] = ['pt.del','=',0];
            $map[] = ['t.type','=',2];
            $map[] = ['pt.patrol_mode','=',$patrol_mode];
            $ret['list'] = Db::name('task')
                ->alias('t')
                ->field('pt.id,pt.start_time,pt.end_time,pt.title,pt.patrol_mode,pt.status,pt.is_exception')
                ->join('patrol_task pt','t.bus_id = pt.id')
                ->where($map)
                ->whereIn('pt.status',[0,1])
                ->order('pt.start_time desc')
                ->page($page,$size)
                ->select();

        }else if($type == 2){ // 已完成
            $where[] = ['pt.org_id','=',$orgId];
            $where[] = ['pt.del','=',0];
            $where[] = ['pt.patrol_mode','=',$patrol_mode];
            $where[] = ['ptu.user_id','=',$userId];
            if($status != ''){
                $where[] = ['pt.status','=',$status];
            }else{
                $where[] = ['pt.status','in',[2,3,5]];
            }
            $ret['list'] = Db::name('patrol_task_user')
                ->alias('ptu')
                ->field('pt.id,pt.start_time,pt.end_time,pt.title,pt.patrol_mode,pt.status,ptu.user_id,pt.is_exception')
                ->join('patrol_task pt','ptu.patrol_task_id=pt.id')
                ->where($where)
//                ->where('pt.status',$status)
                ->order('pt.start_time desc')
                ->page($page,$size)
                ->select();
            foreach ($ret['list'] as $k=>$v){
                $user = Db::name('user')
                    ->alias('u')
                    ->field('u.real_name,d.title')
                    ->join('user_dep ud','ud.user_id=u.id')
                    ->join('dep d','d.id=ud.dep_id')
                    ->where('u.id',$v['user_id'])
                    ->find();

                $ret['list'][$k]['dep_name'] = $user?$user['title']:"";
                $ret['list'][$k]['people_name'] = $user?$user['real_name']:"";
            }
        }

        if($ret['list']){
            foreach ($ret['list'] as $k=>$v){
                $info = Db::name('patrol_task_delay')
                    ->where('task_id',$v['id'])
                    ->where('status',1)
                    ->order('id desc')
                    ->find();

                if($info){
                    $ret['list'][$k]['end_time'] = $info['end_time'];
                }
            }

        }


        return $ret;
    }

    public function taskCount($userId,$orgId,$patrol_mode){
        $map[] = ['t.user_id','=',$userId];
        $map[] = ['t.org_id','=',$orgId];
        $map[] = ['pt.del','=',0];
        $map[] = ['t.type','=',2];
        $map[] = ['pt.patrol_mode','=',$patrol_mode];
        $ret= Db::name('task')
            ->alias('t')
            ->field('pt.id,pt.start_time,pt.end_time,pt.title,pt.patrol_mode,pt.status,pt.is_exception')
            ->join('patrol_task pt','t.bus_id = pt.id')
            ->where($map)
            ->whereIn('pt.status',[0,1])
            ->count();
        return $ret;
    }
    public function addrList($taskId,$orgId){
        $ret['user_list'] = Db::name('patrol_task_user')
            ->alias('ptu')
            ->field('u.real_name')
            ->join('patrol_task pt','ptu.patrol_task_id=pt.id')
            ->join('user u','u.id=ptu.user_id')
            ->where('pt.id',$taskId)
            ->select();

        $task = Db::name('patrol_task')
            ->field('interrupt_reson,interrupt_img,in_order')
            ->where('id',$taskId)
            ->find();

        $ret['task']['interrupt_reson'] =  isset($task['interrupt_reson'])?$task['interrupt_reson']:'';
        $ret['task']['interrupt_img'] =  isset($task['interrupt_img'])?$task['interrupt_img']:'';
        $ret['task']['in_order'] =  isset($task['in_order'])?$task['in_order']:0;

        $addrList = Db::name('patrol_task_addr')
            ->alias('pta')
            ->field('pt.id,pt.start_time,pt.end_time,pt.status,pta.id as patrol_addr_form_id,a.title,pta.address_id as patrol_addr_id,a.sn as device_sn')
            ->join('patrol_task pt','pta.patrol_task_id = pt.id')
            ->join('address a','pta.address_id = a.id')
            ->where('pt.id',$taskId)
            ->select();
        $addrList = $addrList?$addrList:[];
        foreach ($addrList as $k=>$v){
            $isNormal= Db::name('patrol_record')
                ->field('is_normal')
                ->where('org_id',$orgId)
                ->where('patrol_task_id',$v['id'])
                ->where('patrol_addr_id',$v['patrol_addr_id'])
                ->find();
            $addrList[$k]['is_normal'] = $isNormal?$isNormal['is_normal']:0;
            $addrList[$k]['address_status'] = $isNormal?1:0;
            if($isNormal){
                $addrList[$k]['type'] = 1;
            }else{
                $addrList[$k]['type'] = 0;
            }
            $addrList[$k]['addrCode'] = get_qrcode_str('address',$v['patrol_addr_id']);

            $formList = $this->forms($v['patrol_addr_form_id']);
            $addrList[$k]['formList'] = $formList?$formList:[];
        }
        $ret['addr_list'] = $addrList;
        return  $ret;
    }

    public function taskDeatils($taskId,$formId,$orgId){
        $ret['details'] = Db::name('patrol_task')
            ->field('id,title,create_time,start_time,end_time,patrol_form,in_order')
            ->where('id',$taskId)
            ->find();

        $patrolRecord = Db::name('patrol_record')
            ->field('id as recordId,images,create_time,content,check_json,user_id,time,wc_time,min,max,order_id')
            ->where('org_id',$orgId)
            ->where('patrol_task_id',$taskId)
            ->where('patrol_addr_form_id',$formId)
            ->find();
        $jsonArray=json_decode($patrolRecord['check_json'],true);
        $jsonArray = $jsonArray?$jsonArray:[];
        foreach ($jsonArray as $k=>$v){
            foreach ($v['forms'] as $kk=>$vv){
                if(!empty($vv['remark'])){
                    $remark=$vv['remark'];
                }else{
                    $remark='';
                }
                $v['forms'][$kk]['title'] = $vv['title'];
                $v['forms'][$kk]['remark'] = $remark;
            }

            $jsonArray[$k] = $v;
        }
        $ret['forms']=$jsonArray;
        unset($patrolRecord['check_json']);
        $ret['details']['images']=$patrolRecord?$patrolRecord['images']:'';
        $ret['details']['content']=$patrolRecord?$patrolRecord['content']:'';
        $ret['details']['user_id']=$patrolRecord?$patrolRecord['user_id']:'';
        $ret['details']['order_id']=$patrolRecord?$patrolRecord['order_id']:0;
        $ret['details']['recordId']=$patrolRecord?$patrolRecord['recordId']:0;
        $ret['details']['real_name']= Db::name('user')->where('id',$patrolRecord['user_id'])->value('real_name');

        $ret['details']['time']=$patrolRecord?$patrolRecord['time']:0;
        $ret['details']['wc_time']=$patrolRecord?$patrolRecord['wc_time']:0;
        $ret['details']['min']=$patrolRecord?$patrolRecord['min']:0;
        $ret['details']['max']=$patrolRecord?$patrolRecord['max']:0;
        $ret['details']['create_time']=$patrolRecord?$patrolRecord['create_time']:"";

        $user = Db::name('patrol_task_user')
            ->alias('ptu')
            ->field('u.real_name')
            ->join('patrol_task pt','ptu.patrol_task_id=pt.id')
            ->join('user u','u.id=ptu.user_id')
            ->where('pt.id',$taskId)
            ->select();
        $ret['users']=$user?$user:'';

        return $ret;
    }

    public function forms($patrolAddrFormId){
        $forms = Db::name('patrol_task_addr')->where('id',$patrolAddrFormId)->value('patrol_forms');
        $ret = [];
        if($forms){
            $patrolForm = Db::name('patrol_addr_form')
                ->where('id','in',$forms)
                ->field('id,title,patrol_form')
                ->select();
            $patrolForm = $patrolForm?$patrolForm:[];
            foreach ($patrolForm as $k=>$v){
                $pfs = $v['patrol_form']?explode(',',$v['patrol_form']):[];
                $pfret = Db::name('patrol_form')
                    ->whereIn('id',$pfs)
                    ->select();

                foreach ($pfret as $kk=>$vv){
                    $pfret[$kk]['remark'] = $vv['remark']?$vv['remark']:'';
                }
                $patrolForm[$k]['forms'] = $pfret;
                unset($patrolForm[$k]['patrol_form']);
            }
            $ret = $patrolForm;
        }

        return $ret;
    }

    public function updateStatus($patrolTaskId,$interruptReson,$interruptImg){
        if(!$interruptReson) {
            $this->error = '中断原因不能为空';
            return false;
        }
        $data=[
            'status'=>5,
            'interrupt_reson'=>$interruptReson,
            'interrupt_img'=>$interruptImg,
        ];
         $update = Db::name('patrol_task')
            ->where('id',$patrolTaskId)
            ->update($data);

        return $update;
    }

    /**
     * 巡更人员工作量统计
     *
     * @author wst
     * @date   2021/4/13 9:10
     */
    public function WorkerPatrol($orgId,$search,$model=1){
        $org_id = $orgId;

        $query = Db::name('patrol_record');
        if(!empty($search['start'])){
            $search['start'] = date('Ymd',strtotime($search['start']));
            $query->where('patrol_record.create_yyyymmdd','>=', $search['start']);
        }
        if(!empty($search['end'])){
            $search['end'] = date('Ymd',strtotime($search['end']));
            $query->where('patrol_record.create_yyyymmdd','<=', $search['end']);
        }
        $query->where('patrol_record.patrol_mode', $model);
        $query->where('patrol_record.org_id',$org_id);
        $query->group('patrol_record.user_id');
        $query->join('user','user.id = patrol_record.user_id');
        $query->field('patrol_record.id,patrol_record.user_id,user.nickname');
        $list  =$query->select();
        $list = $list?$list:array();
        foreach ($list as $k=>$v){
            $query1 = Db::name('patrol_record');
            $query1->where('org_id',$org_id);
            $query1->where('user_id',$v['user_id']);
            if(!empty($search['start'])){
                $search['start'] = date('Ymd',strtotime($search['start']));
                $query1->where('create_yyyymmdd','>=', $search['start']);
            }
            if(!empty($search['end'])){
                $search['end'] = date('Ymd',strtotime($search['end']));
                $query1->where('create_yyyymmdd','<=', $search['end']);
            }
            $query1->where('patrol_mode', $model);
            $count = $query1->count();
            $list[$k]['count'] = $count?$count:0;
        }
        return $list;
    }

    public function get_list_by_time($orgId,$mode,$start,$end){

        $map[] = ['org_id','=',$orgId];
        $map[] = ['del','=',0];
        $map[] = ['patrol_mode','=',$mode];
        $map[] = ['start_time','<',$end];
        $map[] = ['end_time','>=',$start];

        $list = $this->field('id,title,start_time,end_time,status')
          ->where($map)
            ->select();
        $list = $list?$list->toArray():[];
        foreach ($list as $k=>$v){
            $userList = Db::name('patrol_task_user')
                ->alias('a')
                ->field('u.id,u.real_name')
                ->join('user u','u.id = a.user_id')
                ->where('a.patrol_task_id',$v['id'])
                ->column('real_name');
            $list[$k]['users'] = $userList?implode(',',$userList):'';
        }
        return $list?$list:array();
    }

    //分组获取任务计划最近12个月份
    public function get_task_month($org_id,$mode){
        $list = $this
            ->field('create_yyyymm')
            ->group('create_yyyymm')
            ->where('org_id',$org_id)
            ->where('del',0)
            ->where('patrol_mode',$mode)
            ->order('create_yyyymm','desc')
            ->limit(12)
            ->select();
        $list = $list?$list->toArray():array();
        foreach ($list as $k=>$v){
            $list[$k]['create_yyyymm'] = date('Y-m',strtotime($v['create_yyyymm'].'01'));
        }
        return $list;
    }

    //复制任务
    public function plan_data($post,$org){ //TODO::已复制过的月份是否可以继续复制
        $from = strtotime($post['from'].'-01');
        $to = strtotime($post['to'].'-01');
        $max = strtotime(date('Y-m-d', strtotime($post['to'].'-01 +1 month')));
        $cha = $to - $from;

        $map[] = ['del','=',0];
        $map[] = ['org_id','=',$org];
        $map[] = ['patrol_mode','=',$post['mode']];
        $map[] = ['create_yyyymm','=',date('Ym',strtotime($post['from'].'-01'))];
        $list = $this->where($map)->select();
        if(!$list){
           $this->error = '要复制的月份下没有任务';
           return false;
        }
        $list = $list->toArray();
        $this->startTrans();
        try{
            $uuid = '';
            while (true) {
                $uuid = new_guid();
                $ret = $this
                    ->where('uuid',$uuid)
                    ->find();
                if(!$ret){
                    break;
                }
            }
            foreach ($list as $k=>$v){
                $start_time = strtotime($v['start_time'])+$cha;
                if($start_time >= $max){
                    continue;
                }
                $v['start_time'] = date('Y-m-d H:i:s',$start_time);
                $v['end_time'] = date('Y-m-d H:i:s',strtotime($v['end_time'])+$cha);
                $v['uuid'] = $uuid;
                $ret = $this->copy_one($v);
                if(!$ret){
                    \exception('复制失败');
                }
            }
            $this->commit();
            return true;
        }catch (Exception $e){
            $this->db->trans_rollback();
            $this->error = $e->getMessage();
            return false;
        }
    }

    //复制单个任务
    private function copy_one($data){
        $id = $data['id'];
        unset($data['id']);
        $data['status'] = 0;
        $data['create_time'] = date('Y-m-d H:i:s');
        $data['create_yyyymm'] = date('Ym',strtotime($data['start_time']));
        $data['create_yyyy'] = date('Y',strtotime($data['start_time']));
        $data['create_yyyymmdd'] = date('Ymd',strtotime($data['start_time']));
        $addrs = $this->get_task_addr($id);
        $userids = $this->get_task_user($id);

        //添加任务
        $taskid = $this->insertGetId($data);
        if(!$taskid){
            return false;
        }

        //添加检查地点
        $addr = array();
        foreach ($addrs as $k=>$v){
            $addr[] = array(
                'patrol_task_id' => $taskid,
                'patrol_addr_form_id' => $v
            );
        }
        $res = Db::name('patrol_task_addr')->insertAll($addr);
        if(!$res){
            return false;
        }

        //添加检查人员
        $user = array();
        foreach ($userids as $k=>$v){
            $user[] = array(
                'patrol_task_id' => $taskid,
                'user_id' => $v
            );
        }
        $res = Db::name('patrol_task_user')->insertAll($user);
        if(!$res){
            return false;
        }
        return true;
    }

    //获取任务检查地点
    public function get_task_addr($taskid){
        $addrlist = Db::name('patrol_task_addr')
            ->where('patrol_task_id',$taskid)
           ->column('patrol_addr_form_id');
        return $addrlist;
    }

    //获取任务检查人员
    public function get_task_user($taskid){
        $userlist = Db::name('patrol_task_user')
            ->where('patrol_task_id',$taskid)
            ->column('user_id');
        return $userlist;
    }

    //定时处理超时任务
    public function timer_action(){
        $curTime = date('Y-m-d H:i:s');
        $map[] = ['del','=',0];
        $map[] = ['status','in',[0,1]];
        $map[] = ['end_time','<',$curTime];
        $this->where($map)
            ->update(['status'=>3]);
        $ids = Db::name('task')
            ->alias('a')
            ->join('patrol_task b','a.bus_id=b.id')
            ->where('b.end_time','<',$curTime)
            ->where('a.type',2)
            ->column('a.id');
        if(!empty($ids)){
            Db::name('task')
                ->where('id','in',$ids)
                ->delete();
        }
    }
    public function addPatrolTask(){
        $curTime = date('Y-m-d H:i:s',time()+8*60*60);
        $map[] = ['a.del','=',0];
        $map[] = ['a.status','=',0];
        $map[] = ['a.start_time','<',$curTime];

        $ids = $this
            ->alias('a')
            ->join('patrol_task_user b','b.patrol_task_id=a.id')
            ->where($map)
            ->whereIn('a.patrol_mode',[1,2,3])
            ->field('a.*,b.user_id')
            ->select();
        if(!empty($ids)){
            $ids = $ids->toArray();
            $a = [];
            foreach ($ids as $k=>$v){
                $check = Db::name('task')
                    ->where('type',2)
                    ->where('org_id',$v['org_id'])
                    ->where('bus_id',$v['id'])
                    ->where('user_id',$v['user_id'])
                    ->find();
                if(empty($check)){
                    $a[]= [
                        'org_id'=>$v['org_id'],
                        'type'=>2,
                        'start_time'=>$v['start_time'],
                        'create_time'=>getTime(),
                        'bus_id'=>$v['id'],
                        'user_id'=>$v['user_id']
                    ];
                }
            }
            if(!empty($a)){
                Db::name('task')
                    ->insertAll($a);
            }
        }

        //巡检类型
        $curTime2 = date('Y-m-d H:i:s',time()+10*60*60);
        $map2[] = ['a.del','=',0];
        $map2[] = ['a.status','=',0];
        $map2[] = ['a.start_time','<',$curTime2];

        $ids2 = $this
            ->alias('a')
            ->join('patrol_task_user b','b.patrol_task_id=a.id')
            ->where($map2)
            ->where('a.patrol_mode',4)
            ->field('a.*,b.user_id')
            ->select();
        if(!empty($ids2)){
            $ids2 = $ids2->toArray();
            $a2 = [];
            foreach ($ids2 as $k=>$v){
                $check2 = Db::name('task')
                    ->where('type',2)
                    ->where('org_id',$v['org_id'])
                    ->where('bus_id',$v['id'])
                    ->where('user_id',$v['user_id'])
                    ->find();
                if(empty($check2)){
                    $a2[]= [
                        'org_id'=>$v['org_id'],
                        'type'=>2,
                        'start_time'=>$v['start_time'],
                        'create_time'=>getTime(),
                        'bus_id'=>$v['id'],
                        'user_id'=>$v['user_id']
                    ];
                }
            }
            if(!empty($a2)){
                Db::name('task')
                    ->insertAll($a2);
            }
        }
    }

}