<?php
namespace App\Service;

use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Support\Facades\Log;
use App\Models\StrategyExcel;
use App\Models\StrategySet;
use App\Models\StrategyTask;
use App\Jobs\StrategyTaskJob;

class StrategyService
{
    //验证上传的excel
    public function validUploadExcel($request,$inputName,$maxUploadSize=''){
        $path = storage_path()."/import/";
        $path = str_replace('\\','/',$path);
        
        $extension = $request->file($inputName)->getClientOriginalExtension();
        if($extension != 'xlsx' && $extension != 'xls' ){
            return ['msg'=>'非xls及xlsx格式文件', 'code'=>401];
        }
        if (!empty($maxUploadSize)){//限制最大上传文件（字节）
            $size = $request->file($inputName)->getClientSize();
            if ($size > $maxUploadSize){
                return ['msg'=>'上传文件过大', 'code'=>401];
            }
        }
        
        $fileName = date('YmdHis',time()).'.xlsx';
        
        if($request->hasFile($inputName)){
            if($request->file($inputName)->isValid()){
                $upr = $request->file($inputName)->move($path,$fileName);
                if (!$upr){
                    return ['msg'=>'文件上传失败', 'code'=>401];
                }else{
                    $res = [];
                    Excel::load($path.'/'.$fileName,function($reader) use( &$res ){
                        $reader = $reader->getSheet(0);
                        $res = $reader->toArray();
                    });
                        $data = array_filter($res);
                        if (count($data) > 1001){
                            return ['msg'=>'条数超过1000条', 'code'=>401];
                        }
                        //验证excel表头格式
                        $title = array_shift($data);
                        if ($title != ['姓名','*手机号码','值班日期']){//匹配excel表头
                            return ['msg'=>'导入失败，excel表头不一致', 'code'=>401];
                        }                        
                        return $data;
                }
            }
        }
        return ['msg'=>'excel处理失败', 'code'=>401];
    }
    //判断excel数据问题,$day_type//外呼日期类型 0每天 1日期前一天和当天   1需要验证值班日期必填
    public function validExcelData($successData,$day_type){
        $failData = [];
        $total = count($successData);
        foreach ($successData as $k=>$v){
            $dataLab = 1;
            if (strlen($v[0]) > 20){ //姓名最大20个字符，中文处理，放入失败数据中
                array_push($v, "姓名过长");  
                $failData[] = $v;
                $dataLab = 0;
            }
            if ($dataLab == 1 && !preg_match('/^1[3-8]{1}[0-9]{9}$/', $v[1])){//手机号格式验证（手机号码验证以13、14、15、16、17、18开头的11位数字），不能为空
                array_push($v, "手机号格式不正确"); 
                $failData[] = $v;
                $dataLab = 0;
            }
            if ($dataLab == 1 && $day_type == 1){//验证必填且为日期格式
                if (empty($v[2])){
                    array_push($v, "值班日期必填"); 
                    $failData[] = $v;
                    $dataLab = 0;
                }else{
                    $unixTime = strtotime($v[2]);
                    if (!$unixTime || (date('Y/n/j', $unixTime) != $v[2] && date('n/j/Y', $unixTime) != $v[2])) { //月日不带0（2020/5/3或者 5/3/2020）
                        array_push($v, "值班日期格式错误");
                        $failData[] = $v;
                        $dataLab = 0;
                    }else{
                        $v[2] = date('Y-m-d',$unixTime); //处理存储db的日期格式（2020-05-13）
                        $successData[$k] = $v;
                    }
                    
                }
            }else{//不需要验证附初始值
                $successData[$k][2] = date('Y-m-d');
            }
            if ($dataLab == 0){
                unset($successData[$k]);
            }
        }
        
        $failTotal = count($failData);
        $successTotal = count($successData);
        $failDataFile = '';
        if ($failTotal > 0){//把导出错误数据存入excel表格中供下载
            $failDataTitle = ['姓名','*手机号码','值班日期','失败原因'];
            array_unshift($failData, $failDataTitle);
            $failExcelName = "导入失败数据_".date('YmdHis');
            //dump($failExcelName);
            $failFile = $this->storeExcelStyle($failExcelName, $failData,'','import');
            //$failDataFile = $failExcelName.'.xlsx';
            if ($failFile){
                $failDataFile = $failExcelName;
            }else{ //失败数据写入失败
                Log::channel('api')->error('错误文件excel写入失败');
            }
        }
        return compact('successData','total','failData','failTotal','successTotal','failDataFile');
    }
    
    
    
    //保存内容到excel文件并下载,$exportType  excel文件操作类型  0存储数据直接保存， 1直接导出数据 ， 2保存并导出数据
    public function storeExcelStyle($excelName,$datas,$endLen='',$path='',$exportType=0){
        try{
            $arr = range('A','Z');
            if (!empty($endLen)){
                $endLen = $endLen - 1;
                if(isset($arr[$endLen])){
                    $arr = range('A',$arr[$endLen]);
                }
            }
            
            $e = Excel::create(iconv('UTF-8', 'GBK', $excelName),function($excel) use ($datas,$arr){
                $excel->sheet('score', function($sheet) use ($datas,$arr){
                    $col =array();
                    $sheet->rows($datas);
                    foreach($arr as $v){
                        $col[$v]=12;
                    }
                    $sheet->setWidth($col);                    
                    foreach ($arr as $k=> $v){
                        $objRichText = new \PHPExcel_RichText();
                        if(!empty($datas[0][$k])){
                            if (strpos($datas[0][$k], '*') === 0){
                                $objPayable = $objRichText->createTextRun('*');
                                $objPayable->getFont()->setColor( new \PHPExcel_Style_Color( \PHPExcel_Style_Color::COLOR_RED ) );//设置颜色
                            }
                            $objRichText->createText(ltrim($datas[0][$k],'*'));
                            $sheet->setCellValue($arr[$k].'1',$objRichText);
                        }
                        
                    }
                    
                });
            });
            
            if ($exportType == 1){
                if (empty($path)){//默认路径storage/exports
                    $e->export('xlsx');
                }else{//自定义路径 storage/$path
                    $e->export('xlsx', storage_path($path));
                }
            }elseif ($exportType == 2){
                if (empty($path)){//默认路径storage/exports
                    $e->store('xlsx')->export('xlsx');
                }else{//自定义路径 storage/$path
                    $e->store('xlsx', storage_path($path))->export('xlsx', storage_path($path));
                }
            }else{
                if (empty($path)){//默认路径storage/exports
                    $e->store('xlsx');
                }else{//自定义路径 storage/$path
                    $e->store('xlsx', storage_path($path));
                }
            }
            
            
            return true;
        }catch(\Exception $e){
            Log::channel('api')->error($e->getFile().'-'.$e->getLine().'-'.$e->getMessage());
            return false;
        }
    }
    
    //添加策略处理excel数据入库
    public function insertStrategyExcel($strategySn,$data){
        if (count($data) > 0){
            $insertData = [];
            $now = date('Y-m-d H:i:s');
            foreach ($data as $k=>$v){
                $insertTemp = [];
                $insertTemp['strategy_sn'] = $strategySn;
                $insertTemp['name'] = $v[0] == null ? '' : $v[0];
                $insertTemp['phone'] = (int)$v[1];
                $insertTemp['duty_date'] = $v[2] == null ? '' : $v[2];
                $insertTemp['created_at'] = $now;
                $insertTemp['updated_at'] = $now;
                $insertData[] = $insertTemp;
            }
            //dd($insertData);
            $insertExcelReturn = StrategyExcel::insert($insertData);   
            if ($insertExcelReturn){//创建任务数据，这一步剥离出来，不然接口返回太慢，方案==，使用队列处理
                $jobParams = ['strategySn'=>$strategySn];
                // /opt/lampp/bin/php /opt/lampp/xiaoa/xiaoa-aic/artisan queue:work --queue=StrategyTask --sleep=3 --tries=0 --daemon --timeout=90
                $job = (new StrategyTaskJob($jobParams))->onQueue('StrategyTask');
                dispatch($job);
                //$this->createTaskDataJob($strategySn);
                return true;
            }
        }
        return false;
    }
    
    //跟进策略任务数据生成待新建任务的excel数据,（两种情况 一、有新数据时当时生成，二、每月1号生成）$operaterType类型 1为每月1号生成，0是按照当前日期计算
    public function createTaskDataJob($strategySn){
        //set_time_limit(0);
        
        if (empty($strategyInfo)){
            $strategyInfo = StrategySet::where('strategy_sn',$strategySn)->first()->toArray();
        }        
        $cmonth = date('n');//当前月份（不带0）
        $data = StrategyExcel::where([['strategy_sn',$strategySn],['last_handle_month','<>',$cmonth]])->get();
        $batch = 500; //单批处理多少条
        $total = count($data);
        $now = date('Y-m-d H:i:s');
        $taskData = [];
        //一天呼叫两次类型，拆分时间，拆分项目
        $call_time = explode("#", $strategyInfo['call_time_set']);
        $project_sn = explode("#", $strategyInfo['project_sn']);
        
        $tempi = 0;        
        if ($strategyInfo['day_type'] == 0){//每天拨打            
            $startDay = date('Y-m-d'); //执行当天时间            
            //这个月最后一天日期
            $endDay = date('Y-m-d',strtotime("-1 day",strtotime("+1 month",strtotime(date('Y-m-01')))));
            
            for ($i=$startDay;$i<=$endDay;$i=date("Y-m-d",strtotime("+1 day",strtotime($i)))){
                foreach ($data as $k=>$v){
                    $tempi ++;
                    $taskData[] = [
                        'strategy_sn'=>$strategySn,
                        'name'=>$v->name,
                        'phone'=>$v->phone,
                        'duty_date'=>$v->duty_date,
                        'import_date'=>$v->created_at,
                        'parent_sn'=>$strategyInfo['parent_sn'],
                        'call_number'=>$strategyInfo['call_number'],
                        'project_sn'=>$project_sn[0],//$strategyInfo['project_sn'],
                        'call_date'=>$i,
                        'call_time'=>$call_time[0],//$strategyInfo['call_time'],
                        'created_at'=>$now
                    ];
                    
                    if(count($taskData) == $batch || $total == $batch || $tempi == $total){
                        if (!empty($taskData)){
                            StrategyTask::insert($taskData);
                            $taskData = [];
                        }
                    }
                    
                }
            }
        }else{
            $doubleTotal = $total*2;
            foreach ($data as $k=>$v){
                $tempi = $tempi+2;                
                $yesterday = date('Y-m-d',strtotime("-1 day",strtotime($v->duty_date)));
                $taskData[] = [
                    'strategy_sn'=>$strategySn,
                    'name'=>$v->name,
                    'phone'=>$v->phone,
                    'duty_date'=>$v->duty_date,
                    'import_date'=>$v->created_at,
                    'parent_sn'=>$strategyInfo['parent_sn'],
                    'call_number'=>$strategyInfo['call_number'],
                    'project_sn'=>$project_sn[0],
                    'call_date'=>$yesterday,
                    'call_time'=>$call_time[0],
                    'created_at'=>$now
                ];
           
                $taskData[] = [
                    'strategy_sn'=>$strategySn,
                    'name'=>$v->name,
                    'phone'=>$v->phone,
                    'duty_date'=>$v->duty_date,
                    'import_date'=>$v->created_at,
                    'parent_sn'=>$strategyInfo['parent_sn'],
                    'call_number'=>$strategyInfo['call_number'],
                    'project_sn'=>$project_sn[1],
                    'call_date'=>$v['duty_date'],
                    'call_time'=>$call_time[1],
                    'created_at'=>$now
                ];
                
                if(count($taskData) == $batch || $doubleTotal == $batch || $tempi == $doubleTotal){
                     if (!empty($taskData)){
                         StrategyTask::insert($taskData);
                         $taskData = [];
                     }
                }
            }
        }
        //将处理的策略月份修改为最新
        StrategyExcel::where([['strategy_sn',$strategySn],['last_handle_month','<>',$cmonth]])->update(['last_handle_month'=>$cmonth]);
                
    }
    
    
}

