<?php

namespace App\Http\Controllers\API\Admin\YeWu;

use App\Http\Controllers\Controller;
use App\Services\Admin\YeWu\PlanListService;
use App\Services\Admin\YeWu\RosterService;
use DateTime;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Tools;

class PlanListController extends Controller
{
    //生成计划明细
    public function Create(Request $request,RosterService $rosterService)
    {
        $userid = $request->get('userid');//中间件产生的参数
        $userInfo = DB::table('users')->where(['id' => $userid])->get();
        $department_id = $userInfo[0]->department_id;
        $dateRange = request('dateRange');
        $planModelIds = request('ids');
        $HolidayEnable = request('HolidayEnable');
        $date_type = request('date_type');

        try {
            // 调用服务层
            $result = $rosterService->generatePlans(
                $dateRange,
                $planModelIds,
                $userid,
                $date_type,
                $HolidayEnable
            );

            return \Yz::Return(true, '执行完成，共计生成计划 ' . $result['count'] . ' 条', $result);

        } catch (\Exception $e) {
            // 捕获服务层抛出的异常，格式化返回给前端
            return \Yz::echoError1($e->getMessage());
        }
    }

    public function GetList(Request $request)
    {
        $userid = $request->get('userid');//中间件产生的参数
        $group = $request->get('role');//中间件产生的参数
        $searchInfo = request('searchInfo');
        $page = request('page');
        $pageSize = request('pageSize');
        $department_id = 0;
        $department_info=false;
        $list = DB::table('s_source_roster_detail')
            ->leftJoin('s_department_resources', 's_source_roster_detail.resources_id', '=', 's_department_resources.id')
            //  ->leftJoin('s_devices', 's_source_roster_detail.device_id', '=', 's_devices.id')
            ->leftJoin('s_period', 's_source_roster_detail.period_id', '=', 's_period.id')
            ->select('s_source_roster_detail.*', 's_department_resources.department_resources_name', 's_period.period_name')
            ->where(['s_source_roster_detail.is_del' => 0]);
        if (!empty($searchInfo['department_id'])) {//以前判断的是管理员group==1 改为 (任何角色都能查看了)
            if (!empty($searchInfo['department_id'])) {
                $department_info=DB::table('s_department')->where(['id' => $searchInfo['department_id']])->first();
                $list = $list->where('s_source_roster_detail.department_id', $searchInfo['department_id']);
            }

        } else {
            $userInfo = DB::table('users')->where(['id' => $userid])->get();
            $department_id = $userInfo[0]->department_id;
            $department_info=DB::table('s_department')->where(['id' => $department_id])->first();
            $list = $list->where(['s_source_roster_detail.department_id' => $department_id]);
        }
        if (!empty($searchInfo['resources_id'])) {
            $list = $list->where('s_source_roster_detail.resources_id', $searchInfo['resources_id']);
        }
        if (!empty($searchInfo['device_id'])) {
            //$list = $list->where('s_source_roster_detail.device_id', 'like','%,'.$searchInfo['device_id'].',%'  );
            $list = $list->whereRaw("FIND_IN_SET({$searchInfo['device_id']}, s_source_roster_detail.device_id)");
        }
        if (!empty($searchInfo['xingqi'])) {
            $list = $list->where('s_source_roster_detail.weekname', $searchInfo['xingqi']);
        }
        if (isset($searchInfo['status'])) {
            $list = $list->where('s_source_roster_detail.status', $searchInfo['status']);
        }
        if (count($searchInfo['dateRange']) == 2) {
            $list = $list->whereBetween('s_source_roster_detail.date', $searchInfo['dateRange']);
        }

        $count = $list;
        $count = $count->count();
        $list = $list->orderBy('id', 'desc')->limit($pageSize)->skip(($page - 1) * $pageSize) // 跳过前9999条记录
        ->take($pageSize)->get();
        $ids = [];
        foreach ($list as $key => $value) {
            $list[$key]->department_name = !!$department_info?$department_info->department_name:'' ;
            $list[$key]->countsInfo = [];
            $ids[] = $value->id;
        }
        //匹配渠道数量
        $countsInfo = DB::table('s_source_roster_detail_count')
            ->leftJoin('s_appointment_type', 's_source_roster_detail_count.appointment_type_id', '=', 's_appointment_type.id')
            ->select('s_source_roster_detail_count.*', 's_appointment_type.name','s_appointment_type.jiancheng')
            ->whereIn('roster_detail_id', $ids)->get();

        if (count($countsInfo) > 0) {
            foreach ($list as $key => $value) {
                foreach ($countsInfo as $k => $v) {
                    if ($value->id == $v->roster_detail_id) {
                        $list[$key]->countsInfo[] = $v;
                    }
                }
            }
        }
        //匹配设备（服务组）
        $devices = DB::table('s_devices')->get();
        foreach ($list as $key => $value) {
            $list[$key]->devices = [];
            $array_device_id = explode(",", $value->device_id);
            foreach ($devices as $k => $v) {
                if (in_array($v->id, $array_device_id)) {
                    $list[$key]->devices[] = $v;
                }
            }
        }

        return \Yz::Return(true, '获取成功', ['list' => $list, 'count' => $count]);
    }

    public function GetDetail()
    {
        $id = request('id');
        $info = DB::table('s_source_roster_detail')->where(['id' => $id, 'is_del' => 0])->first();
        $info->patientType = explode(',', $info->patient_type);
        $info->department_name = DB::table('s_department')->where('id', $info->department_id)->first()->department_name;
        $info->resources_name = DB::table('s_department_resources')->where('id', $info->resources_id)->first()->department_resources_name;
        $info->devices = DB::table('s_devices')->whereIn('id', explode(',', $info->device_id))->get();
        $info->coutsInfo = DB::table('s_source_roster_detail_count')
            ->leftJoin('s_appointment_type', 's_source_roster_detail_count.appointment_type_id', '=', 's_appointment_type.id')
            ->leftJoin('s_appointment_type_ratio', 's_appointment_type.id', '=', 's_appointment_type_ratio.appointment_type_id')
            ->select('s_source_roster_detail_count.*', 's_appointment_type.name', 's_appointment_type_ratio.ratio')
            ->where(['s_source_roster_detail_count.roster_detail_id' => $id, 's_appointment_type_ratio.department_id' => $info->department_id])->get();
        $info->max_total = 0;
        if (count($info->coutsInfo) > 0) {
            $info->max_total = $info->coutsInfo[0]->max_total;
        }
        return \Yz::Return(true, '获取成功', $info);
    }

    public function ChangeInfo(Request $request)
    {
        $userid = $request->get('userid');//中间件产生的参数
        $group = $request->get('role');//中间件产生的参数
        $PlanDetaiInfo = request('PlanDetaiInfo');
        $userInfo = DB::table('users')->where(['id' => $userid])->get();
        $department_id = $userInfo[0]->department_id;
        $check = DB::table('s_source_roster_detail')->where(['id' => $PlanDetaiInfo['id']])
            ->where('department_id', $department_id)
            ->where('is_del', 0)
            ->first();
        if (!$check) return \Yz::echoError1('没有权限');
        $u1 = DB::table('s_source_roster_detail')->where(['id' => $PlanDetaiInfo['id']])->update([
            'status' => $PlanDetaiInfo['status']
        ]);
        $i = 0;
        foreach ($PlanDetaiInfo['coutsInfo'] as $key => $value) {
            $u2 = DB::table('s_source_roster_detail_count')->where(['id' => $value['id']])->update([
                'count' => $value['count']==null?0:$value['count'],
                'max_total' => $value['max_total'],
            ]);
            if ($u2) $i++;
        }
        if ($u1 or $i > 0) {
            return \Yz::Return(true, '保存成功', []);
        } else {
            return \Yz::echoError1('没有数据更新');
        }
    }

    public function Del(Request $request)
    {
        $userid = $request->get('userid');//中间件产生的参数
        $userInfo = DB::table('users')->where(['id' => $userid])->get();
        $department_id = $userInfo[0]->department_id;
        $ids = request('ids');
        $u1 = DB::table('s_source_roster_detail')->where(['department_id' => $department_id])->whereIn('id', $ids)->update([
            'is_del' => 1
        ]);
        if ($u1) {
            return \Yz::Return(true, '删除成功', []);
        } else {
            return \Yz::echoError1('删除失败');
        }
    }

    //获取可用的计划，用于计划占用
    public function GetEnablePlan()
    {
        $regnum = request('regnum');
        $entrustid = request('entrustid');
        $episodeid = request('episodeid');
        $appointment_type = request('appointment_type'); //预约类型
        $appointment_date = request('date'); //预约日期
        $service = new PlanListService();
        return $service->GetEnablePlan($regnum, $entrustid, $episodeid, $appointment_type, $appointment_date);
    }

    //获取最近可用的，计划 日期
    public function NearestEnablePlanDate()
    {
        $dateRange=config('app.globals.可用号源查询范围');
        $regnum = request('regnum');
        $entrustids = request('entrustid');
        $episodeid = request('episodeid');
        $appointment_type = request('appointment_type'); //预约类型
        $appointment_date = request('date'); //预约日期
        $service = new PlanListService();

        $date_arr = [];


        $startDate = new DateTime();
        // 设定结束日期为当前日期加7天
        $endDate = new DateTime();
        $endDate->modify('+' . $dateRange . ' day');
        // 循环遍历每一天
        $currentDate = $startDate;
        while ($currentDate <= $endDate) {
            $nowdate = $currentDate->format('Y-m-d');
            $s = $service->GetEnablePlan($regnum, $entrustids, $episodeid, $appointment_type, $nowdate);
            if ($s['status']) {
                $list = $s['data']['plan_list'];
                if (count($list) > 0) {
                    $date_arr[] = $s['data']['appointment_date'];
                }
            }
            if (count($date_arr) >= 2) {
                break;
            }
            // 每次循环增加一天
            $currentDate->modify('+1 day');
        }
        return \Yz::Return(true, '查询完成', ['list' => $date_arr]);


    }

    //开始预约占用名额
    public function YuYue()
    {
        date_default_timezone_set('PRC');
        $nowdatetime = date("Y-m-d H:i:s");
        $do_userid=request('do_user');
        $is_emergency = request('is_emergency');//是否加急
        $planid = request('planid');
        $appointment_type = request('appointment_type');//渠道id
        $mainlistid = request('mainlistid');//主表id
        $do_type = request('dotype');//操作类型,1预约，2改约
        if (!isset($do_type)) return \Yz::echoError1('参数：操作类型 不能为空');

        $service = new PlanListService();
        return $service->YuYue($planid, $appointment_type, $mainlistid, $do_type,$is_emergency,$do_userid);
    }
    //自动预约
    public function AutoYuYue()
    {
        $dateRange=config('app.globals.可用号源查询范围');
        $regnum = request('regnum');
        $entrustids = request('entrustid');
        $episodeid = request('episodeid');
        $appointment_type = request('appointment_type'); //预约类型
        $TodayDateTime = date("Y-m-d H:i:s");
        $service = new PlanListService();

        $startDate = new DateTime();
        // 设定结束日期为当前日期加7天
        $endDate = new DateTime();
        $endDate->modify('+' . $dateRange . ' day');
        // 循环遍历每一天
        $currentDate = $startDate;
        $enable_plan=false;
        while ($currentDate <= $endDate) {
            $nowdate = $currentDate->format('Y-m-d');
            $s = $service->GetEnablePlan($regnum, $entrustids, $episodeid, $appointment_type, $nowdate);
            if ($s['status']) {
                $list = $s['data']['plan_list'];
                if (count($list) > 0) {
                   foreach ($list as $k => $v) {
                       if($v->count-$v->used_count>0 and $TodayDateTime< $v->date.' '.$v->end_reservation_time){
                           $enable_plan=$v;
                           break;
                       }
                   }
                   if(!!$enable_plan){
                       break;
                   }
                }
            }

            // 每次循环增加一天
            $currentDate->modify('+1 day');
        }
        if(!!$enable_plan){
            $mainlistids=DB::table('s_list')->whereIn('entrust_id',$entrustids)->pluck('id')->toArray();
            $service = new PlanListService();
            return $service->YuYue($enable_plan->id, $appointment_type, $mainlistids, 1);
        }else{
            return \Yz::echoError1('最近'.$dateRange.'日无可用号源');
        }
    }

    public function CancelYuYue(Request $request)
    {
        $MainListId = request('MainListId');
        $reg_num = request('reg_num');
        $password = request('password');
        $userid = $request->get('userid');//中间件产生的参数
        $do_userid=request('do_user');
        $query = DB::table('users')->where(['id' => $userid])->get();
        if (password_verify($password, $query[0]->pwd)) {
            $service = new PlanListService();
            return $service->CancelYuYue($MainListId, $reg_num,$do_userid);
        } else {
            return \Yz::echoError1('密码不正确');
        }
    }

    //查询已预约明细
    public function GetUsedList()
    {
        $planid = request('planid');
        $qudaoid = request('qudaoid');
        $list = DB::table('s_list')
            ->leftJoin('s_department_resources', 's_list.reservation_sources', '=', 's_department_resources.id')
            ->select('s_list.*', 's_department_resources.department_resources_name')
            ->where(['s_list.roster_id' => $planid, 's_list.is_del' => 0, 's_list.is_nullify' => 0])->whereIn('s_list.list_status', [1, 2, 3]);
        if (!empty($qudaoid)) {
            $list = $list->where(['s_list.appointment_type_id' => $qudaoid]);
        }
        $list = $list->get();
        $qudao = DB::table('s_appointment_type')->get();
        foreach ($list as $key => $item) {
            foreach ($qudao as $q) {
                if ($q->id == $item->appointment_type_id) {
                    $item->qudao_name = $q->name;
                }
            }

        }
        return \Yz::Return(true, '查询完成', $list);
    }
    public function TongJi()
    {
        $SearchInfo = request('SearchInfo');
        $canshu=[];
        $sql=' ';
        if(!empty($SearchInfo['dateRange'])){
            $canshu[] = $SearchInfo['dateRange'][0]; // 开始日期
            $canshu[] = $SearchInfo['dateRange'][1]; // 结束日期
            $sql.=" and a.date >= ? and a.date <= ?";
        }
        $planCount = DB::select("SELECT
	aa.department_name,
	sum(bb.count) as count,
	sum(bb.used_count) as used_count
FROM
	(
	SELECT
		b.department_name,
		a.*
	FROM
		s_source_roster_detail AS a
		LEFT JOIN s_department AS b ON a.department_id = b.id
	WHERE
		a.is_del = 0 ".$sql."
	) AS aa
	LEFT JOIN (
		select roster_detail_id, sum(count) as count,sum(used_count) as used_count from s_source_roster_detail_count group by roster_detail_id
	) AS bb ON aa.id = bb.roster_detail_id group by aa.department_name",$canshu);

        $allCount=0;
        $allUsedCount=0;
        foreach ($planCount as $key => $item) {
            $allCount+=$item->count;
            $allUsedCount+=$item->used_count;
            $item->used_rate=number_format(($item->used_count/$item->count)*100,2).'%';
        }
        $planInfo=[
            'list'=>$planCount,
            'allCount'=>$allCount,
            'allUsedCount'=>$allUsedCount,

        ];
        return \Yz::Return(true, '查询完成', $planInfo);
    }

    //批量生成所有有效模板的排班明细
    public function BatchGenerateByDateRange(Request $request, RosterService $rosterService)
    {
        $dateRange = request('dateRange');
        $HolidayEnable = request('HolidayEnable', 1);
        $userid = 0;

        try {
            // 1. 查询所有资源,按 time_mode 分组
            $resources = DB::table('s_department_resources')
                ->where(['is_del' => 0])
                ->get()
                ->groupBy('time_mode');

            $results = [];
            $totalCount = 0;

            // 2. 遍历不同 time_mode 的资源
            foreach ($resources as $timeMode => $resourceGroup) {
                $resourceIds = $resourceGroup->pluck('id')->toArray();

                // 3. 根据 time_mode 查询对应的模板
                $templatesQuery = DB::table('s_source_roster')
                    ->leftJoin('s_department_resources', 's_source_roster.resources_id', '=', 's_department_resources.id')
                    ->select(
                        's_source_roster.*',
                        's_department_resources.department_resources_name',
                        's_department_resources.time_mode',
                        's_department_resources.time_range'
                    )
                    ->whereIn('s_source_roster.resources_id', $resourceIds)
                    ->where(['s_source_roster.status' => 1, 's_source_roster.is_del' => 0]);

                if ($timeMode == 1) {
                    // 时令资源: 只查询 type=1 或 2 的模板
                    $templatesQuery->whereIn('s_source_roster.type', [1, 2]);
                } else {
                    // 普通资源: 只查询 type=0 的模板
                    $templatesQuery->where('s_source_roster.type', 0);
                }

                $allModels = $templatesQuery->get();

                if ($allModels->isEmpty()) {
                    continue; // 该 time_mode 下没有模板,跳过
                }

                // 4. 时令模板根据资源的 time_range 进行匹配
                if ($timeMode == 1) {
                    $validTemplates = collect();
                    $startDate = new DateTime($dateRange[0]);
                    $endDate = new DateTime($dateRange[1]);
                    $currentDate = clone $startDate;

                    while ($currentDate <= $endDate) {
                        foreach ($allModels as $model) {
                            $resource = $resourceGroup->where('id', $model->resources_id)->first();

                            // 检查日期是否在时令范围内
                            if ($this->isDateInSeasonalRange($currentDate, $model->type, $resource)) {
                                if (!$validTemplates->contains('id', $model->id)) {
                                    $validTemplates->push($model);
                                }
                            }
                        }
                        $currentDate->modify('+1 day');
                    }

                    $allModels = $validTemplates;

                    if ($allModels->isEmpty()) {
                        continue; // 没有匹配的时令模板,跳过
                    }
                }

                // 5. 按资源分组,按 date_type 细分,循环调用 generatePlans
                $groupedByResource = $allModels->groupBy('resources_id');

                foreach ($groupedByResource as $resourcesId => $models) {
                    $groupedByDateType = $models->groupBy('date_type');
                    $resourceCount = 0;

                    try {
                        foreach ($groupedByDateType as $dateType => $typeModels) {
                            $typeModelIds = $typeModels->pluck('id')->toArray();

                            $result = $rosterService->generatePlans(
                                $dateRange,
                                $typeModelIds,
                                $userid,
                                $dateType,
                                $HolidayEnable
                            );
                            $resourceCount += $result['count'];
                        }

                        $results[] = [
                            'resources_id' => $resourcesId,
                            'resources_name' => $models->first()->department_resources_name ?? '',
                            'status' => 'success',
                            'count' => $resourceCount
                        ];
                        $totalCount += $resourceCount;

                    } catch (\Exception $e) {
                        $results[] = [
                            'resources_id' => $resourcesId,
                            'resources_name' => $models->first()->department_resources_name ?? '',
                            'status' => 'failed',
                            'error' => $e->getMessage(),
                            'count' => 0
                        ];
                    }
                }
            }

            // 6. 统计结果
            $successCount = collect($results)->where('status', 'success')->count();
            $failedCount = collect($results)->where('status', 'failed')->count();

            return \Yz::Return(
                true,
                "批量生成完成，共 {$totalCount} 条 (成功: {$successCount} 资源, 失败: {$failedCount} 资源)",
                [
                    'total_count' => $totalCount,
                    'success_count' => $successCount,
                    'failed_count' => $failedCount,
                    'details' => $results
                ]
            );

        } catch (\Exception $e) {
            return \Yz::echoError1($e->getMessage());
        }
    }

    /**
     * 时令日期匹配：判断日期是否在时令范围内
     * - 如果资源 time_mode != 1 或模板 type == 0，不需要时令校验，返回 true
     * - 否则检查日期是否在对应季节的周期范围内
     */
    private function isDateInSeasonalRange($currentDate, $modelType, $resource)
    {
        // 不需要时令校验
        if ($resource->time_mode != 1 || $modelType == 0) {
            return true;
        }

        $currentMMDD = $currentDate->format('m-d');

        // 解析 time_range
        $time_range = json_decode($resource->time_range, true);

        if (!$time_range || !is_array($time_range)) {
            return false;
        }

        // 遍历所有季节周期
        foreach ($time_range as $season) {
            // 转换类型进行匹配（字符串 "1"/"2" vs 整数 1/2）
            if ((string)($season['type'] ?? '') === (string)$modelType) {
                // 检查是否在任意周期范围内
                if (isset($season['periods']) && is_array($season['periods'])) {
                    foreach ($season['periods'] as $period) {
                        $start = $period['start'] ?? '';
                        $end = $period['end'] ?? '';

                        if (!empty($start) && !empty($end) &&
                            $currentMMDD >= $start && $currentMMDD <= $end) {
                            return true; // 匹配成功
                        }
                    }
                }
            }
        }

        return false; // 不在时令范围内
    }

    //保存占位数量
    public function SaveLockedCount(Request $request)
    {
        $userid = $request->get('userid');
        $roster_detail_id = request('roster_detail_id');
        $locked_counts = request('locked_counts');

        if (empty($roster_detail_id)) {
            return \Yz::echoError1('计划明细ID不能为空');
        }

        if (empty($locked_counts) || !is_array($locked_counts)) {
            return \Yz::echoError1('占位数量不能为空');
        }

        DB::beginTransaction();

        try {
            $changes = []; // 记录有变更的渠道

            foreach ($locked_counts as $item) {
                $appointment_type_id = $item['appointment_type_id'];
                $locked_count = $item['locked_count'];

                // 查询对应的记录
                $countRecord = DB::table('s_source_roster_detail_count')
                    ->where([
                        'roster_detail_id' => $roster_detail_id,
                        'appointment_type_id' => $appointment_type_id
                    ])
                    ->first();

                if (!$countRecord) {
                    DB::rollBack();
                    return \Yz::echoError1('未找到对应的渠道数量记录');
                }

                // 验证占位数量不能超过剩余可用数量
                $remaining = $countRecord->count - $countRecord->used_count;
                if ($locked_count > $remaining) {
                    DB::rollBack();
                    return \Yz::echoError1('占位数量不能大于剩余可用数量');
                }

                if ($locked_count < 0) {
                    DB::rollBack();
                    return \Yz::echoError1('占位数量不能为负数');
                }

                // 记录变更前的值
                $old_locked_count = $countRecord->locked_count;

                // 只有值有变化时才记录
                if ($old_locked_count != $locked_count) {
                    $changes[] = [
                        'appointment_type_id' => $appointment_type_id,
                        'old_locked_count' => $old_locked_count,
                        'new_locked_count' => $locked_count
                    ];

                    // 更新占位数量
                    DB::table('s_source_roster_detail_count')
                        ->where([
                            'roster_detail_id' => $roster_detail_id,
                            'appointment_type_id' => $appointment_type_id
                        ])
                        ->update([
                            'locked_count' => $locked_count,
                            'updated_at' => date('Y-m-d H:i:s')
                        ]);
                }
            }

            // 有变更时记录日志
            if (!empty($changes)) {
                DB::table('s_source_roster_detail_log')->insert([
                    'roster_detail_id' => $roster_detail_id,
                    'type' => '修改占位数量',
                    'content' => json_encode($changes, JSON_UNESCAPED_UNICODE),
                    'userid' => $userid
                ]);
            }

            DB::commit();
            return \Yz::Return(true, '保存成功', []);

        } catch (\Exception $e) {
            DB::rollBack();
            return \Yz::echoError1('保存失败：' . $e->getMessage());
        }
    }
}
