<?php

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

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class PlanModelController extends Controller
{
    public function GetList(Request $request)
    {
        $userid = $request->get('userid');
        $group = $request->get('role');
        $searchInfo = request('searchInfo');
        $page = request('page');
        $pageSize = request('pageSize');

        $searchInfo['date_type'] = $searchInfo['date_type'] ?? 1;

        $department_id = 0;

        // 1. 确定 department_id
        if ($group == 1) {
            if (!empty($searchInfo['department_id'])) {
                $department_id = $searchInfo['department_id'];
            }
        } else {
            $userInfo = DB::table('users')->where(['id' => $userid])->get();
            if ($userInfo->isNotEmpty()) {
                $department_id = $userInfo[0]->department_id;
            }
        }

        // 2. 构建主查询
        // 注意：这里必须保留 leftJoin 's_department_resources'，因为我们需要用它里面的 time_mode 字段做条件判断
        $listQuery = DB::table('s_source_roster')
            ->leftJoin('s_department_resources', 's_source_roster.resources_id', '=', 's_department_resources.id')
            ->leftJoin('s_period', 's_source_roster.period_id', '=', 's_period.id')
            ->select(
                's_source_roster.*',
                's_department_resources.department_resources_name',
                's_department_resources.time_mode',
                's_department_resources.time_range',
                's_period.period_name'
            )
            ->where([
                's_source_roster.is_del' => 0,
                's_source_roster.date_type' => $searchInfo['date_type']
            ]);

        // 限制科室 ID (如果 department_id 为 0，通常意味着没权限或无数据，可根据业务决定是否跳过此 where)
        if ($department_id > 0) {
            $listQuery->where('s_source_roster.department_id', $department_id);
        } else {
            // 如果 department_id 为 0 且不是管理员模式，可能查不到数据，这里保持原逻辑或直接返回空
            // 如果业务允许查全库，可注释掉上面的 if，但通常这里有权限控制
            if ($group != 1) {
                return \Yz::Return(true, '操作成功', ['list' => [], 'count' => 0]);
            }
        }

        if ($searchInfo['date_type'] == 2) {
            // 规则 A: date_type = 2 时，无论 time_mode 是多少，强制只查 type = 0
            $listQuery->where('s_source_roster.type', 0);

        } else {
            // 规则 B: date_type != 2 (例如 1) 时，根据 time_mode 动态匹配
            $listQuery->where(function ($query) {
                // 情况 1: time_mode = 1 -> 允许 type 1 或 2
                $query->where(function ($sub) {
                    $sub->where('s_department_resources.time_mode', 1)
                        ->whereIn('s_source_roster.type', [1, 2]);
                })
                    // 情况 2: time_mode = 0 -> 只允许 type 0
                    ->orWhere(function ($sub) {
                        $sub->where('s_department_resources.time_mode', 0)
                            ->where('s_source_roster.type', 0);
                    });

                // 可选：如果 time_mode 为 NULL (资源未关联到)，是否要显示？
                // 通常如果不匹配任何规则则不显示，上述逻辑已自然过滤掉 NULL 情况。
                // 如果需要显示未关联资源的 type=0 数据，可以追加:
                // ->orWhere(function($sub) { $sub->whereNull('s_department_resources.time_mode')->where('s_source_roster.type', 0); })
            });
        }

        // 4. 其他筛选条件
        if (!empty($searchInfo['resources_id'])) {
            $listQuery = $listQuery->where('s_source_roster.resources_id', $searchInfo['resources_id']);
        }
        if (isset($searchInfo['type'])) {
            $listQuery = $listQuery->where('s_source_roster.type', $searchInfo['type']);
        }

        if (!empty($searchInfo['device_id'])) {
            // 修复 SQL 注入风险，使用参数绑定
            $listQuery = $listQuery->whereRaw("FIND_IN_SET(?, s_source_roster.device_id)", [$searchInfo['device_id']]);
        }

        if (!empty($searchInfo['xingqi'])) {
            $listQuery = $listQuery->where('s_source_roster.weekname', $searchInfo['xingqi']);
        }

        if (isset($searchInfo['status'])) {
            $listQuery = $listQuery->where('s_source_roster.status', $searchInfo['status']);
        }

        // 5. 统计总数
        $count = $listQuery->count();

        // 6. 排序
        $listQuery = $listQuery->orderBy('s_source_roster.resources_id');
        $listQuery = $listQuery->orderByRaw("FIELD(`weekname`, '星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日') ASC");
        $listQuery = $listQuery->orderBy('s_source_roster.begin_time');

        // 7. 获取数据
        //dd($listQuery->toSql());
        $list = $listQuery->get();


        $ids = [];
        foreach ($list as $key => $value) {
            // 处理患者类型标签
            $patient_arr = explode(',', $value->patient_type ?? '');
            $p_type = config('app.globals.患者类型');
            $type_label = array_map(function($key) use ($p_type) {
                return $p_type[$key] ?? null;
            }, $patient_arr);
            $list[$key]->patient_type_label = $type_label;

            $list[$key]->countsInfo = [];
            $ids[] = $value->id;

            $list[$key]->time_range = json_decode($value->time_range ?? '[]', true);
        }

        // 9. 匹配渠道数量
        $countsInfo = [];
        if (!empty($ids)) {
            $countsInfo = DB::table('s_source_roster_count')
                ->leftJoin('s_appointment_type', 's_source_roster_count.appointment_type_id', '=', 's_appointment_type.id')
                ->select('s_source_roster_count.*', 's_appointment_type.name', 's_appointment_type.jiancheng')
                ->whereIn('roster_id', $ids)
                ->get();
        }

        if (count($countsInfo) > 0) {
            foreach ($list as $key => $value) {
                foreach ($countsInfo as $k => $v) {
                    if ($value->id == $v->roster_id) {
                        $list[$key]->countsInfo[] = $v;
                    }
                }
            }
        }

        // 10. 匹配设备（服务组）
        $allDevices = DB::table('s_devices')->get()->keyBy('id');

        foreach ($list as $key => $value) {
            $list[$key]->devices = [];
            if (!empty($value->device_id)) {
                $array_device_id = explode(",", $value->device_id);
                foreach ($array_device_id as $devId) {
                    $devId = trim($devId);
                    if (isset($allDevices[$devId])) {
                        $list[$key]->devices[] = $allDevices[$devId];
                    }
                }
            }
        }

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

    public function Save(Request $request)
    {
        $userid = $request->get('userid');//中间件产生的参数
        $date_type = request('date_type');
        $planInfo = request('planInfo');
        $bitian = array('max_total', 'qudao_total', 'period_id', 'begin_time', 'end_time', 'end_reservation_time', 'resources_id', 'devices', 'patientType');
        $bitian_zh = array('当日总量', '渠道数量', '时间段', '开始时间', '结束时间', '停止预约时间', '资源', '设备', '患者类型');
        if($date_type==1){//如果是普通类型计划 1普通2节假日
            $bitian[]='xingqi';
            $bitian_zh[]='星期';
        }
        foreach ($bitian as $key => $field) { //必填项不能为空
            if (array_key_exists($field, $planInfo) && $planInfo[$field] !== '' && $planInfo[$field] !== null && $planInfo[$field] !== [] && $planInfo[$field] !== 0) {
            } else {
                return \Yz::echoError1($bitian_zh[$key] . ' 不能为空');
            }
        }
        if($planInfo['end_reservation_time']>$planInfo['end_time']) return \Yz::echoError1('停止预约时间不能超过结束时间');
        $userInfo = DB::table('users')->where(['id' => $userid])->first();
        if (!isset($userInfo->department_id)) return \Yz::echoError1('该用户未绑定科室');
        $department_id = $userInfo->department_id;
        $type=isset($planInfo['type']) ?$planInfo['type']:0;
        $resourceInfo=DB::table('s_department_resources')->where(['id' => $planInfo['resources_id']])->first();
        if($resourceInfo->time_mode==1 and $type==0){
            return \Yz::echoError1('请选择时令');
        }
        if($resourceInfo->time_mode==0 and $type != 0){
            return \Yz::echoError1('时令配置异常，请刷新页面重试');
        }

        DB::beginTransaction();
        $data = [
            'type'=>$type,
            'department_id' => $department_id,
            'weekname' => '',
            'resources_id' => $planInfo['resources_id'],
            'device_id' => isset($planInfo['devices']) ? implode(',', $planInfo['devices']) : '',
            'period_id' => $planInfo['period_id'], //时间段id
            'patient_type' => isset($planInfo['patientType']) ? implode(',', $planInfo['patientType']) : '',//病人类型
            'begin_time' => $planInfo['begin_time'],
            'end_time' => $planInfo['end_time'],
            'end_reservation_time' => $planInfo['end_reservation_time'],
            'time_unit' => $planInfo['time_unit'],
            'status' => $planInfo['status'],
            'adduser' => $userid,
            'date_type' => $date_type,
        ];
        $param=[
            'type'=>$type,
            'department_id' => $department_id,
            'resources_id' => $planInfo['resources_id'],
            'is_del' => 0,
            'date_type' => $date_type,
        ];
        if($date_type==1){
            foreach ($planInfo['xingqi'] as $key => $value) {
                $data['weekname'] = $value;
                //判断记录是否存在
                $param['weekname'] = $value;
                $check=$this->Check($planInfo,$param,$value);
                if(!$check['status']){
                    DB::rollBack();
                    return \Yz::echoError1($check['msg']);
                }
                if ($planInfo['id'] == 0) {//新增
                    $roster_id = DB::table('s_source_roster')->insertGetId($data);
                    if ($roster_id) {
                        foreach ($planInfo['qudao_total'] as $k => $v) {
                            $i_c = DB::table('s_source_roster_count')->insert([
                                'roster_id' => $roster_id,
                                'appointment_type_id' => $v['id'],
                                'max_total' => $planInfo['max_total'],
                                'count' => $v['count'],
                            ]);
                            if (!$i_c) {
                                DB::rollBack();
                                return \Yz::echoError1('保存失败');
                            }
                        }
                    } else {
                        DB::rollBack();
                        return \Yz::echoError1('保存失败');
                    }
                }

            }
        }elseif ($date_type==2){
            $check=$this->Check($planInfo,$param,"当前选定的");
            if(!$check['status']){
                DB::rollBack();
                return \Yz::echoError1($check['msg']);
            }
            if ($planInfo['id'] == 0) {//新增
                $roster_id = DB::table('s_source_roster')->insertGetId($data);
                if ($roster_id) {
                    foreach ($planInfo['qudao_total'] as $k => $v) {
                        $i_c = DB::table('s_source_roster_count')->insert([
                            'roster_id' => $roster_id,
                            'appointment_type_id' => $v['id'],
                            'max_total' => $planInfo['max_total'],
                            'count' => $v['count'],
                        ]);
                        if (!$i_c) {
                            DB::rollBack();
                            return \Yz::echoError1('保存失败');
                        }
                    }
                } else {
                    DB::rollBack();
                    return \Yz::echoError1('保存失败');
                }
            }

        }
        if($planInfo['id'] > 0) {//修改
            $data['id'] = $planInfo['id'];

            $i = DB::table('s_source_roster')->where(['id' => $planInfo['id'], 'is_del' => 0])->update($data);

            foreach ($planInfo['qudao_total'] as $k => $v) {
                $i_c = DB::table('s_source_roster_count')->where(['roster_id' => $planInfo['id'], 'appointment_type_id' => $v['appointment_type_id']])->update([
                    'max_total' => $planInfo['max_total'],
                    'count' => $v['count'],
                ]);

            }
            if ($i or $i_c) {
            } else {
                DB::rollBack();
                return \Yz::echoError1('保存失败');
            }
        }

        DB::commit();
        return \Yz::Return(true, '保存成功', []);
    }
    //检测提交的信息是否有效
    function Check($planInfo,$param,$shiduan)
    {
        $is_ex = DB::table('s_source_roster')->where($param);
        if ($planInfo['id'] > 0) {
            $is_ex = $is_ex->where('id', '<>', $planInfo['id']);
        }

        $start = $planInfo['begin_time'];
        $end = $planInfo['end_time'];
        $is_ex = $is_ex->where(function ($query) use ($start, $end) {
            // 情况1：开始时间在查询区间内
            $query->whereBetween('begin_time', [$start, $end])
                ->orWhereBetween('end_time', [$start, $end]);
            // 情况2：查询区间的开始时间在数据库记录的开始和结束时间之间
            // 注意：对于时间类型的比较，直接使用字符串比较可能不够精确，特别是跨天情况，以下逻辑需根据实际情况调整
            $query->orWhere(function ($query) use ($start, $end) {
                $query->where('begin_time', '<=', $start)
                    ->where('end_time', '>=', $end);
            });
        })->get();
        //遍历判断设备是否有重叠，有则返回错误
        foreach ($is_ex as $k => $v) {
            $db_device_ids = explode(',', $v->device_id);
            $overlap = array_intersect($planInfo['devices'], $db_device_ids);
            if (count($overlap) > 0) {
                return ['status'=>false,'msg'=>$shiduan . '时段服务组关联重复,计划id为:' . $v->id];
            }
        }
        return ['status'=>true,'msg'=>''];
    }

    //获取模板信息详情
    public function GetDetailInfo()
    {
        $id = request('id');
        $info = DB::table('s_source_roster')->where(['id' => $id])->first();
        if (!!$info) {
            $info->devices = array_map('intval', explode(',', $info->device_id));
            $info->patientType = explode(',', $info->patient_type);
            $info->qudao_total = DB::table('s_source_roster_count')
                ->select('s_source_roster_count.*', 's_appointment_type.name')
                ->leftJoin('s_appointment_type', 's_source_roster_count.appointment_type_id', '=', 's_appointment_type.id')
                ->where(['roster_id' => $id])->get();
            $ratio = DB::table('s_appointment_type_ratio')
                ->where(['department_id' => $info->department_id])->get();
            foreach ($info->qudao_total as $key => $value) {
                foreach ($ratio as $k => $v) {
                    if ($value->appointment_type_id == $v->appointment_type_id) {
                        $info->qudao_total[$key]->ratio = $v->ratio;
                    }
                }
            }
            return \Yz::Return(true, '操作成功', $info);
        } else {
            return \Yz::echoError1('数据不存在');
        }

    }

    //获取自己的预约类型比例
    public function GetAppointmentRatio(Request $request)
    {
        $userid = $request->get('userid');//中间件产生的参数
        $userInfo = DB::table('users')->where(['id' => $userid])->first();
        if (!!$userInfo) {
            $appointment_type = DB::table('s_appointment_type')->where(['status' => 1, 'is_del' => 0])->get();
            $department_id = $userInfo->department_id;
            $ratio = DB::table('s_appointment_type_ratio')
                ->where(['department_id' => $department_id])->get();

            foreach ($appointment_type as $key => $value) {
                $appointment_type[$key]->ratio = 0;
                foreach ($ratio as $k => $v) {
                    if ($value->id == $v->appointment_type_id) {
                        $appointment_type[$key]->ratio = $v->ratio;
                        $appointment_type[$key]->link = json_decode($v->link,true);
                    }
                }
            }
            return \Yz::Return(true, '操作成功', $appointment_type);
        }
    }

    //保存预约类型比例
    public function SaveAppointmentRatio(Request $request)
    {
        $userid = $request->get('userid');//中间件产生的参数
        $userInfo = DB::table('users')->where(['id' => $userid])->first();
        if (!!$userInfo) {
            $department_id = $userInfo->department_id;
            $ratioInfo = request('ratioInfo');
            $u = false;
            DB::table('s_appointment_type_ratio')->where(['department_id' => $department_id])->delete();

            foreach ($ratioInfo as $key => $value) {
                $u = DB::table('s_appointment_type_ratio')->insert([
                    'department_id' => $department_id,
                    'appointment_type_id' => $value['id'],
                    'ratio' => $value['ratio'],
                    'link'=>isset($value['link'])?json_encode($value['link'],JSON_UNESCAPED_UNICODE):null,
                ]);
            }
            if ($u) {
                return \Yz::Return(true, '操作成功', []);
            } else {
                return \Yz::echoError1('保存失败,无数据更新');
            }

        }
    }

    //删除计划模板
    public function Del(Request $request)
    {
        $userid = $request->get('userid');//中间件产生的参数
        $ids = request('ids');
        $userInfo = DB::table('users')->where(['id' => $userid])->first();
        if (!!$userInfo) {
            $appointment_type = DB::table('s_appointment_type')->where(['status' => 1, 'is_del' => 0])->get();
            $department_id = $userInfo->department_id;
            $d = DB::table('s_source_roster')
                ->where(['department_id' => $department_id])->whereIn('id', $ids)->update([
                    'is_del' => 1,
                ]);
            if ($d) {
                return \Yz::Return(true, '操作成功', []);
            } else {
                return \Yz::echoError1('操作失败');
            }

        }
    }

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

        if (empty($roster_id)) {
            return \Yz::echoError1('模板ID不能为空');
        }

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

        DB::beginTransaction();

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

                // 查询对应的记录（模板表 s_source_roster_count）
                $countRecord = DB::table('s_source_roster_count')
                    ->where([
                        'roster_id' => $roster_id,
                        'appointment_type_id' => $appointment_type_id
                    ])
                    ->first();

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

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

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

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

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