<?php

namespace App\Http\Controllers;

use App\Events\ClockoutEvent;
use App\Events\GuardAuditEvent;
use App\Events\TeamAuditEvent;
use App\Exports\Export;
use App\LaborCompany;
use App\LaborReport;
use App\LaborReportStatus;
use App\Services\common\ExportService;
use App\Services\LaborReportService;
use App\UserDutyCheck;
use App\UserWorkgroup;
use Carbon\Carbon;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Http;
use Maatwebsite\Excel\Facades\Excel;

class LaborReportController extends Controller
{
    public function __construct()
    {
        app()->singleton('laborReportService',LaborReportService::class);
    }
    /**
     * Display a listing of the resource.
     * @param  Request $request
     * @return void
     * 临时工报表
     */
    public function index(Request $request)
    {
        if(!Gate::allows('人事管理-临时工报表')){ view('personnel/index');  }
        $paginateParams=$request->input();
        $user=Auth::user();
        if (!$user)return redirect('/');
        $laravelEchoPrefix = config('database.redis.options.prefix');
        $tokenOfBroadcastEnterAndLeave='';
        if(Gate::allows('人事管理-临时工报表-可见全部组')||Gate::allows('人事管理-门卫审核')){
            $tokenOfBroadcastEnterAndLeave=LaborReport::tokenOfBroadcastEnterAndLeave();
        }
        $userWorkgroupIds=$user->getPermittingWorkgroupIds(Gate::allows('人事管理-临时工报表-可见全部组'));
        $permittingWorkgroups=UserWorkgroup::whereIn('id',$userWorkgroupIds)->get();
        if($permittingWorkgroups->isEmpty())$permittingWorkgroups="[]";
        $laborReports=app('laborReportService')->paginate($request->input());
        LaborReport::processing($laborReports);

        foreach ($laborReports as $laborReport){
            if (!$laborReport->group_user_id){
                //2小时之内组长未审核实行软删除
                $tenMinutesLater=Carbon::parse($laborReport->created_at)->subHours(-2)->format('Y-m-d H:i:s');
                if (Carbon::now()->format('Y-m-d H:i:s')>$tenMinutesLater){
                    $laborReport->delete();
                    app('LogService')->log(__METHOD__,"组长未审核该条记录将在2小时后实行软删除__".__FUNCTION__,$laborReport->toJson(),Auth::user()['id']);
                }
            }
            $addOneHourCheckedAt=Carbon::parse($laborReport->userDutyCheck['checked_at'])->subHours(-1)->format('Y-m-d H:i:s');
            if (!$laborReport->userDutyCheck['verify_user_id']&&Carbon::now()->format('Y-m-d H:i:s')>$addOneHourCheckedAt){
                $laborReport->delete();
                app('LogService')->log(__METHOD__,"进场门卫未审核该条记录将在1小时后实行软删除__".__FUNCTION__,$laborReport->toJson(),Auth::user()['id']);
            }
        }
        $totalWorkingHours=$this->getTotalWorkingHours($request->input());
        $laborCompanies=LaborCompany::query()->get();
        $userWorkGroups=UserWorkgroup::query()->select('id','name')->get();
        return view('personnel/laborReport/index',compact('laborReports','userWorkGroups','laborCompanies','laravelEchoPrefix','permittingWorkgroups','paginateParams','tokenOfBroadcastEnterAndLeave','totalWorkingHours'));
    }
    public function getTotalWorkingHours($param){
        $totalLaborReports=app('laborReportService')->get($param);
        $totalWorkingHours=0;
        foreach ($totalLaborReports as $totalLaborReport){
            $totalWorkingHours=$totalWorkingHours+$totalLaborReport->thisRoundRecordWorkingTime;
        }
        return $totalWorkingHours;
    }
    public function export(Request $request){
        if (!Gate::allows('人事管理-临时工报表')){return redirect(url('/')); }
        if ($request->checkAllSign){
            $params = $request->input();
            unset($params["checkAllSign"]);
            $laborReports=app('laborReportService')->get($params);
            LaborReport::processing($laborReports);
        }else{
            $laborReports=app('laborReportService')->get(["id"=>$request->data]);
            LaborReport::processing($laborReports);
        }
        $row = ['本次工作时长','小组','临时工','电话','身份证号','劳务所','进场时间','进组时间','退组时间','进组取整时间','退组取整时间','退场时间','审核时间','审核人','晚饭时间(分)','在线时长','进场编号','备注'];
        $list = [];
        foreach ($laborReports as $laborReport){
            $list[] = [
                $laborReport->working_duration,
                $laborReport->userWorkgroup ? $laborReport->userWorkgroup->name : null,
                $laborReport->name,
                $laborReport->mobile_phone,
                $laborReport->identity_number,
                $laborReport->laborCompany ? $laborReport->laborCompany->name : null,
                $laborReport->enter_at,
                $laborReport->check_in_at,
                $laborReport->check_out_at,
                $laborReport->round_check_in_at,
                $laborReport->round_check_out_at,
                $laborReport->exit_at,
                $laborReport->verify_at,
                $laborReport->user ? $laborReport->user->name : null,
                (string)$laborReport->relax_time,
                $laborReport->online_duration,
                $laborReport->enter_number,
                $laborReport->remark,
            ];
        }
        return app(ExportService::class)->json($row,$list,"临时工报表记录");
    }

    //门卫打卡审核
    public function guardClockAudit(Request $request){
        if(!Gate::allows('人事管理-门卫审核')){ return ["success"=>false,"data"=>"您无此权限操作!"];  }
        $id=$request->input('id');
        $userDutyCheckId=$request->input('user_duty_check_id');
        $laborReportStatus=new LaborReportStatus([
            'labor_report_id'=>$id,
            'status'=>'已入场',
        ]);
        $laborReportStatus->save();
        app('LogService')->log(__METHOD__,"门卫打卡审核修改当前临时工报表状态".__FUNCTION__,json_encode($laborReportStatus),Auth::user()['id']);
        $userDutyCheck=UserDutyCheck::find($userDutyCheckId);
        $userDutyCheck->verify_user_id=Auth::user()['id'];
        $userDutyCheck->update();
        app('LogService')->log(__METHOD__,"门卫打卡审核".__FUNCTION__,json_encode($userDutyCheck),Auth::user()['id']);
        event(new GuardAuditEvent($userDutyCheck));
        return ["success"=>true,"data"=>$userDutyCheck->verify_user_id];
    }
    //打卡组长审核
    public function groupClockAudit(Request $request){
        if(!Gate::allows('人事管理-组长审核')){ return ["success"=>false,"data"=>"您无此权限操作!"];  }
        $id=$request->input('id');
        $laborReport=LaborReport::find($id);
        $laborReport->group_user_id=Auth::user()['id'];
        $laborReport->verify_at=date('Y-m-d H:i:s');
        $laborReport->update();
        $laborReport->verifyPerson=Auth::user()['name'];
        app('LogService')->log(__METHOD__,"打卡组长审核".__FUNCTION__,json_encode($laborReport),Auth::user()['id']);
        event(new TeamAuditEvent($laborReport));
        return ["success"=>true,"data"=>$laborReport];
    }
    //打卡组长审核(特定组添加备注)
    public function addRemarkAndGroupClock(Request $request){
        if(!Gate::allows('人事管理-组长审核')){ return ["success"=>false,"data"=>"您无此权限操作!"];  }
        $id=$request->input('id');
        $remark=$request->input('remark');
        if(!$remark){ return ["success"=>false,"data"=>"您还未添加任何备注,请返回添加备注！"];  }
        $laborReport=LaborReport::find($id);
        $laborReport->group_user_id=Auth::user()['id'];
        $laborReport->verify_at=date('Y-m-d H:i:s');
        $laborReport->update();
        /**
         * @var LaborReportService $laborReportService
         */
        $laborReportService=app(LaborReportService::class);
        $laborReportService->addOrUpdateRemark($remark,$id);
        $laborReport->verifyPerson=Auth::user()['name'];
        app('LogService')->log(__METHOD__,"打卡组长审核并添加相应备注".__FUNCTION__,json_encode($laborReport),Auth::user()['id']);
        event(new TeamAuditEvent($laborReport));
        return ["success"=>true,"data"=>$laborReport];
    }

    //组长点击退组
    public function groupExport(Request $request){
        if(!Gate::allows('人事管理-组长审核')){ return ["success"=>false,"data"=>"您无此权限操作！"];  }
        $id=$request->input('id');
        $laborReport=LaborReport::query()->find($id);
        $laborReportStatus=new LaborReportStatus([
            'labor_report_id'=>$id,
            'status'=>'已退组',
        ]);
        $laborReportStatus->save();
        app('LogService')->log(__METHOD__,"报表记录退组对应状态".__FUNCTION__,json_encode($laborReportStatus),Auth::user()['id']);
        $check_out_at=Carbon::now()->format('Y-m-d H:i:s');
        $check_in_at=$laborReport->check_in_at;
        $laborReport->check_out_at=$check_out_at;
        $online_duration=round(Carbon::parse($check_out_at)->diffInSeconds(Carbon::parse($check_in_at))/3600,2);
        $round_time=round(Carbon::parse($laborReport->round_check_out_at)->diffInSeconds(Carbon::parse($laborReport->round_check_in_at))/3600,2);
        $laborReport->working_duration=$this->minusLunchTime($laborReport,$round_time);
        if ($laborReport['enter_at']){
            $enter_at=$laborReport['enter_at'];
            $laborReport->online_duration=round(Carbon::parse($check_out_at)->diffInSeconds(Carbon::parse($enter_at))/3600,2);
        }else{
            $laborReport->online_duration=$online_duration;
        }
        $laborReport->update();
        $laborReport->is_exportGroup=$laborReport->getIsExportGroupAttribute();
        app('LogService')->log(__METHOD__,"退组".__FUNCTION__,json_encode($laborReport),Auth::user()['id']);
        event(new ClockoutEvent($laborReport));
        return ["success"=>true,"data"=>$laborReport];
    }

    //晚19点后组长点击退场，判断是否有晚餐情况
    public function groupExportEnsure(Request $request){
        if(!Gate::allows('人事管理-组长审核')){ return ["success"=>false,"data"=>"您无此权限操作！"];  }
        $id=$request->input('id');
        $relax_time=$request->input('relax_time');
        if(!$relax_time){ return ["success"=>false,"data"=>"未选择确切晚饭时间,请重新选择!"];  }
        $laborReport=LaborReport::find($id);
        $laborReportStatus=new LaborReportStatus([
            'labor_report_id'=>$id,
            'status'=>'已退组',
        ]);
        $laborReportStatus->save();
        app('LogService')->log(__METHOD__,"报表记录退组对应状态".__FUNCTION__,json_encode($laborReportStatus),Auth::user()['id']);
        $check_out_at=Carbon::now()->format('Y-m-d H:i:s');
        $check_in_at=$laborReport->check_in_at;
        $laborReport->check_out_at=$check_out_at;
        $online_duration=round(Carbon::parse($check_out_at)->diffInSeconds(Carbon::parse($check_in_at))/3600,2);
        $round_time=round(Carbon::parse($laborReport->round_check_out_at)->diffInSeconds(Carbon::parse($laborReport->round_check_in_at))/3600,2);
        if ($relax_time){
            $laborReport->relax_time=$relax_time;
            $laborReport->working_duration=$this->minusLunchTime($laborReport,$round_time)-$relax_time/60;//减去晚饭时间
        }else{
            $laborReport->working_duration=$this->minusLunchTime($laborReport,$round_time);
        }
        if ($laborReport->enter_at){
            $enter_at=$laborReport['enter_at'];
            $laborReport->online_duration=round(Carbon::parse($check_out_at)->diffInSeconds(Carbon::parse($enter_at))/3600,2);
        }else{
            $laborReport->online_duration=$online_duration;
        }
        $laborReport->update();
        $laborReport->is_exportGroup=$laborReport->getIsExportGroupAttribute();
        app('LogService')->log(__METHOD__,"退组".__FUNCTION__,json_encode($laborReport),Auth::user()['id']);
        event(new ClockoutEvent($laborReport));
        return ["success"=>true,"data"=>$laborReport];
    }

    //工作时长减午饭休息时间
    public function minusLunchTime($laborReport,$hour){
        $checkInTime=$laborReport->check_in_at;
        $checkOutTime=$laborReport->check_out_at;
        $checkOutTime=Carbon::parse($checkOutTime)->format('H');
        $checkInTime=Carbon::parse($checkInTime);
        if ($checkInTime->lessThanOrEqualTo($checkInTime->clone()->setHours(11)->setMinutes(30))&&(int)$checkOutTime>=13){
            $hour=$hour-1;
        }
        return $hour;
    }
    public function updateLaborCompany(Request $request){
        if(!Gate::allows('人事管理-临时工报表-修改劳务所')){ return ["success"=>false,"data"=>"您无此权限操作！"];  }
        $param=$request->input();
        $enter_number=$request->enter_number;
        app('laborReportService')->修改劳务所($param);
        $laborReport=LaborReport::query()->where('enter_number',$enter_number)->first();
        if ($laborReport->labor_company_id==$request->input('laborCompanyId')){
            $labor_company=LaborCompany::query()->find($request->input('laborCompanyId'))->value('name');
            return ['success'=>true,'data'=>$laborReport,'labor_company'=>$labor_company];
        }else{
            return ['success'=>true,'data'=>'修改劳务所失败'];
        }
    }
    public function 删除($id){
        if(!Gate::allows('人事管理-临时工报表-删除')){return['success'=>false,'data'=>'没有权限'];}
        if(is_null($id)){return ['success'=>false,'data'=>'传入id为空'];}
        $laborReport=app('laborReportService')->删除($id);
        if ($laborReport>0)return ['success'=>true,'data'=>$laborReport];
        return ['success'=>true,'data'=>'删除报表失败'];
    }

    //回收站
    function recycle(Request $request){
        if(!Gate::allows('人事管理-临时工报表-删除')){ return redirect('/');  }
        $paginateParams=$request->input();
        $laborReports=LaborReport::query()->with(['user','userDutyCheck','userWorkgroup','laborCompany'])->onlyTrashed()->paginate($request->paginate??50);
        return view('personnel.laborReport.recycle',compact('laborReports','paginateParams'));
    }

    //回收站恢复
    function recover(Request $request){
        if(!Gate::allows('人事管理-临时工报表-删除')){ return redirect('/');  }
        $checkData=$request->checkData;
        app('LogService')->log(__METHOD__,"回收站恢复临时工报表记录_".__FUNCTION__,json_encode($request->input()),Auth::user()['id']);
        return ['success'=>LaborReport::withTrashed()->whereIn('id',$checkData)->restore()];
    }
    public function changeLaborReportRemark(Request $request){
        if(!Gate::allows('人事管理-临时工报表-编辑备注')){return ['success'=>'false','fail_info'=>'没有权限'];}
        $laborReportId = $request->input('id');
        $laborReportRemark = $request->input('remark');
        if(is_null($laborReportId) ){
            return ['success'=>false,'fail_info'=>'参数异常'];
        }
        $laborReport=LaborReport::find($laborReportId);
        /**
         * @var LaborReportService $laborReportService
         */
        $laborReportService=app(LaborReportService::class);
        $laborReportService->addOrUpdateRemark($laborReportRemark,$laborReportId);
        app('LogService')->log(__METHOD__,'添加或者修改临时工报表备注'.__FUNCTION__,json_encode($request->toArray()),Auth::user()['id']);
        return ['success'=>true,'status'=>$laborReport];
    }
}
