<?php

namespace App\Api\Controllers;

use App\Http\Controllers\BaseApiController;
use App\Models\DiagnosiModel;
use App\Models\DoctorModel;
use App\Models\InquiryModel;
use App\Models\PatientModel;
use App\Models\PharmacistModel;
use App\Models\PharmacyDrugModel;
use App\Models\PharmacyModel;
use App\Models\PrescriptionLogModel;
use App\Models\PrescriptionModel;
use App\Models\User;
use App\Services\SmsService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Overtrue\EasySms\EasySms;

// 问诊人控制器
class PrescriptionController extends BaseApiController
{
    public function test()
    {
        // 分派医师 医师当日开方未达到上限以及是否在时间段的搜索出来
        // $site_config = DB::table('admin_settings')->where('slug', 'site_config')->value('value');
        // $site_config = json_decode($site_config, true);
        // $pharmacy = PharmacyDrugModel::where('pharmacy_id',1)->get();
        $doctors = DoctorModel::query()->where('status', 1)->get();
        $randomDoctor = $doctors->random();

        return $this->success($randomDoctor);
    }

    // 处方列表
    public function prescriptionList(Request $request)
    {
        $authInfo = auth('api')->user();
        Log::info('用户信息=>'.json_encode($authInfo));
        $query = PrescriptionModel::query();
        // TODO 判断当前登录的用户角色
        // $userInfo = User::with(['doctor', 'pharmacist'])->find($authInfo->id);
        if ($authInfo->last_login_type == User::LOGIN_TYPE_USER) {
            $query = $query->where('user_id', $authInfo->id);
        } elseif ($authInfo->last_login_type == User::LOGIN_TYPE_DOCTOR) { // 医师
            $doctor = DoctorModel::query()->where('user_id', $authInfo->id)->first();
            $query = $query->where('doctor_id', $doctor->id);
        } elseif ($authInfo->last_login_type == User::LOGIN_TYPE_PHARMACY) { // 药店
            $pharmacy = PharmacyModel::query()->where('user_id', $authInfo->id)->first();
            $query = $query->where('pharmacy_id', $pharmacy->id);
        }

        // 客开 0 店开 1
        $open_source = $request->input('open_source');
        if (isset($open_source) && in_array($open_source, [0, 1])) {
            $query = $query->where('open_source', $open_source);
        }

        // 时间段
        $start_time = $request->input('start_time');
        if ($start_time) {
            $start_time = $start_time.' 00:00:00';
            $query->where('created_at', '>=', $start_time);
        }
        $end_time = $request->input('end_time');
        if ($end_time) {
            $end_time = $end_time.' 23:59:59';
            $query->where('created_at', '<=', $end_time);
        }

        // 状态
        $status = $request->input('status');
        if (isset($status) && in_array($status, [0, 1, 2])) {
            $query->where('status', $status);
        }

        // 分页
        $page = $request->input('page', 1);
        $perPage = $request->input('per_page', 10);
        $prescription = $query->orderBy('id', 'desc')->paginate($perPage, ['*'], 'page', $page);

        // $prescription = $query->paginate(10);
        return $this->success($prescription);
    }

    // 处方详情
    public function detail(Request $request)
    {
        $prescription_id = $request->input('prescription_id');
        if (empty($prescription_id)) {
            return $this->failed('ID不能为空');
        }
        $prescription = PrescriptionModel::query()->where('id', $prescription_id)->first();

        return $this->success($prescription);
    }

    // 开方
    public function create(Request $request)
    {
        $authInfo = auth('api')->user();
        Log::info('开方请求参数：'.json_encode($request->all()));
        $pharmacy_id = $request->input('pharmacy_id', 0);
        $patient_id = $request->input('patient_id');
        $diagnosis_id = $request->input('diagnosis_id');
        $inquirys = $request->input('inquirys'); // [['inquiry_id'=>1,'answer'=>1]]
        $drugs = $request->input('drugs'); // [['pharmacy_drug_id'=>2,'num'=>1]]
        $pharmacy = null;
        $open_source = 0;
        // 获取当前用户信息,如果是药店则无需传pharmacy_id参数
        if ($authInfo->last_login_type == User::LOGIN_TYPE_PHARMACY) {
            $pharmacy = PharmacyModel::where('user_id', $authInfo->id)->first();
            $pharmacy_id = $pharmacy->id;
            $open_source = 1;
        } elseif ($authInfo->last_login_type == User::LOGIN_TYPE_USER) {
            return $this->failed('用户端暂时无法开处方');
            $pharmacy = PharmacyModel::find($pharmacy_id);
            if (! $pharmacy) {
                return $this->failed('药店信息不存在');
            }
        } else {
            return $this->failed('pharmacy_id不能为空');
        }

        // 生成处方
        $prescription = new PrescriptionModel;
        $prescription->status = PrescriptionModel::PRESCRIPTION_STATUS_PENDING;
        $prescription->user_id = $authInfo->id; // 获取当前用户ID
        // 问诊人信息
        $patient = PatientModel::find($patient_id);
        $prescription->patient_id = $patient_id; // 问诊人编号
        $prescription->patient_name = $patient->name; // 问诊人姓名
        $prescription->patient_age = getAgeByIdCard($patient->id_card); // 问诊人年龄
        $prescription->patient_gender = $patient->gender; // 问诊人性别
        // 诊断信息
        $prescription->diagnosis_id = $diagnosis_id;
        $diagnosis = DiagnosiModel::find($diagnosis_id);
        $prescription->diagnosis_name = $diagnosis->name;
        // 问诊问题
        $inquiry_info = [];
        $is_abnormal = 0; // 是否异常处方单，只有一个问题回答是就是异常
        foreach ($inquirys as $inquiry) {
            $inquiry = InquiryModel::find($inquiry['inquiry_id']);
            $inquiry_info[] = [
                'inquiry_id' => $inquiry['inquiry_id'],
                'question' => $inquiry->question,
                'answer' => $inquiry['answer'] == 1 ? 1 : 0, // [1 => '是', 0 => '否']
            ];
            // 检查是否有一个answer是1
            if ($inquiry['answer'] == 1) {
                $is_abnormal = 1; // 如果有一个answer是1，设置$is_abnormal为1
            }
        }
        $prescription->inquiry_info = $inquiry_info;
        // 用药信息
        $drug_info = [];
        foreach ($drugs as $drug) {
            $pharmacyDrugQueryInfo = PharmacyDrugModel::with(['drug', 'dosage'])->find($drug['pharmacy_drug_id']);
            $drug_info[] = [
                'pharmacy_drug_id' => $drug['pharmacy_drug_id'],
                'drug_id' => $pharmacyDrugQueryInfo->drug_id,
                'drug_name' => $pharmacyDrugQueryInfo->drug->name,
                'spec' => $pharmacyDrugQueryInfo->drug->spec,
                'unit' => $pharmacyDrugQueryInfo->unit,
                'dosage_id' => 0, // $pharmacyDrugQueryInfo->dosage_id,
                'dosage_desc' => '等待药师录入', // $pharmacyDrugQueryInfo->dosage->dosage_desc,
                'num' => $drug['num'],
            ];
        }
        $prescription->drug_info = $drug_info;

        // 获取全局开方配置
        $site_config = admin_setting_array('site_config');
        $prescription_limit = $site_config['prescription_limit'];
        $prescription_period_status = $site_config['prescription_period_status'];
        $prescription_period_start = $site_config['prescription_period_start'];
        $prescription_period_end = $site_config['prescription_period_end'];
        $prescription_limit_buy_7 = $site_config['prescription_limit_buy_7'];

        // 分派医师  医师当日开方未达到上限以及是否在时间段的搜索出来

        if ($prescription_period_status == '1') {
            // 获取当前时间
            $currentTime = Carbon::now();
            // 解析开始和结束时间
            $startTime = Carbon::createFromFormat('H:i', $prescription_period_start);
            $endTime = Carbon::createFromFormat('H:i', $prescription_period_end);
            // 判断当前时间是否在范围内
            if (! $currentTime->between($startTime, $endTime)) {
                return $this->failed('当前时间不在开方时间段内');
            }
        }

        if (intval($prescription_limit) > 0) {
            $startOfDay = Carbon::now()->startOfDay();
            $endOfDay = Carbon::now()->endOfDay();
            $doctorIds = DoctorModel::query()->where('status', DoctorModel::STATUS_TRUE)->pluck('id')->toArray();
            Log::info('医师ids：'.json_encode($doctorIds));
            $prescriptionCounts = PrescriptionModel::select('doctor_id', DB::raw('COUNT(*) as prescription_count'))
                ->whereIn('doctor_id', $doctorIds)
                ->whereBetween('created_at', [$startOfDay, $endOfDay])
                ->groupBy('doctor_id')
                ->pluck('prescription_count', 'doctor_id');

            Log::info('医师开方统计：'.json_encode($prescriptionCounts));
            if (count($prescriptionCounts) > 0) {
                foreach ($doctorIds as $key => $doctorId) {
                    if (isset($prescriptionCounts[$doctorId])) {
                        // 判断是否达到上限
                        if (intval($prescriptionCounts[$doctorId]) >= intval($prescription_limit)) {
                            unset($doctorIds[$key]);
                        }
                    }
                }
                // foreach ($prescriptionCounts as $doctorId => $count) {
                //     if (intval($count) >= intval($prescription_limit)) {
                //         unset($doctorIds[$doctorId]);
                //     }
                //     if( count($doctorIds) == 0 ) break;
                // }
            }
            // 筛选未达到上限的医师
            // $availableDoctors = collect($doctorIds)->filter(function ($doctorId) use ($prescriptionCounts, $prescription_limit) {
            //     return $prescriptionCounts->get($doctorId, 0) < $prescription_limit;
            // })->values()->all();
            Log::info('有效的医师：'.json_encode($doctorIds));
            // 随机取一个随机医师
            $randomQuery = DoctorModel::query()->where('status', DoctorModel::STATUS_TRUE);
            if (count($doctorIds) > 0) {
                $randomQuery->whereIn('id', $doctorIds);
            } else {
                return $this->failed('医师开方数超过限制');
            }
            $randomDoctor = $randomQuery->inRandomOrder()->first();
            // $randomDoctor = DoctorModel::whereIn('id', $availableDoctors)
            //     ->where('status', DoctorModel::STATUS_TRUE)
            //     ->inRandomOrder()
            //     ->first();
        } else {
            $randomDoctor = DoctorModel::inRandomOrder()->where('status', DoctorModel::STATUS_TRUE)->first();
        }

        if (! $randomDoctor) {
            return $this->failed('暂无可开方医师');
        }
        // 记录开方医师信息
        Log::info('医师：'.json_encode($randomDoctor));
        $prescription->doctor_id = $randomDoctor->id;
        $prescription->doctor_name = $randomDoctor->name;
        $prescription->doctor_online_hospital_name = $randomDoctor->online_hospital_name;
        $prescription->doctor_department = $randomDoctor->department;
        $prescription->doctor_title = $randomDoctor->doctor_title;
        $prescription->doctor_license_no = $randomDoctor->license_no;
        $prescription->doctor_signed_pic = $randomDoctor->getRawOriginal('signed_pic');
        $prescription->doctor_introduction = $randomDoctor->introduction;
        // 药店信息
        $prescription->pharmacy_id = $pharmacy->id;
        $prescription->pharmacy_name = $pharmacy->name;
        // 分派药师,先搜索是否存在默认药师，如果不存在则随机抽取一个
        $pharmacist = PharmacistModel::where('status', 1)
            ->where('pharmacy_id', $pharmacy_id)
            ->where(function ($query) {
                $query->where('is_default', 1)
                    ->orWhere('is_default', 0);
            })
            ->inRandomOrder()
            ->first();

        if (! $pharmacist) {
            return $this->failed('药师信息不存在');
        }
        Log::info('药师：'.json_encode($pharmacist));
        $prescription->pharmacist_id = $pharmacist->id;
        $prescription->pharmacist_name = $pharmacist->name;
        $prescription->pharmacist_license_number = $pharmacist->license_number;
        $prescription->pharmacist_signed_pic = $pharmacist->getRawOriginal('signed_pic');

        // 生成处方单信息
        $prescription_at = Carbon::now()->subMinutes(12);
        $review_at = Carbon::now()->subMinutes(10);
        // 默认为15分钟前的时间
        $prescription->created_at = Carbon::now()->subMinutes(15);
        $prescription->updated_at = Carbon::now()->subMinutes(15);
        $prescription->prescription_at = $prescription_at;
        $prescription->review_at = $review_at;
        $prescription->is_abnormal = $is_abnormal;
        $prescription->open_source = $open_source;
        $prescription_number = 0;
        if ($prescription->save()) {
            $prescription_number = $prescription->id;
        } else {
            return $this->failed('生成处方单失败');
        }

        // 判断是否为医师自动开方
        // $prescription_auto = $site_config['prescription_auto'];
        if ($randomDoctor->is_auto == 1) {
            $prescription->status = PrescriptionModel::PRESCRIPTION_STATUS_REVIEWING;
            $prescription->save();
            // 生成医师开方日志
            $doctorLog = new PrescriptionLogModel;
            $doctorLog->pharmacy_id = $pharmacy_id;
            $doctorLog->pharmacy_name = $pharmacy->name;
            $currentTime = $prescription_at;
            $doctorLog->log_info = $randomDoctor->name.'在'.$prescription_at.'为'.$patient->name.'（'.$patient->mobile.'）开具处方单（处方单编号：'.$prescription_number.'）';
            $doctorLog->save();
        } elseif ($randomDoctor->is_auto == 0) {
            // 手动开方发送医师通知短信
            if (env('SMS_CHANNEL') == 'chengliye') {
                $templateName = 'doctor_notification';
                $templateData = [];
                $smsService = new SmsService();
                $response = $smsService->sendSms($randomDoctor->mobile, $templateName, $templateData);
                Log::info(json_encode($response));
            } elseif (env('SMS_CHANNEL') == 'qcloud') { // 腾讯短信
                $easySms = new EasySms(config('easysms'));
                $response = $easySms->send($randomDoctor->mobile, [
                    'content' => '您有一条处方需要开方。',
                    'template' => '2316306',
                    'data' => [],
                ]);
                Log::info(json_encode($response));
            }
        }

        // 药店自动审方（必须处方单待审方）
        if ($pharmacy->is_auto == 1 && $prescription->status == PrescriptionModel::PRESCRIPTION_STATUS_REVIEWING) {
            $prescription->status = PrescriptionModel::PRESCRIPTION_STATUS_SUCCESS;
            $prescription->save();
            // 生成药师审方日志
            $pharmacistLog = new PrescriptionLogModel;
            $pharmacistLog->pharmacy_id = $pharmacy_id;
            $pharmacistLog->pharmacy_name = $pharmacy->name;
            $currentTime = $review_at;
            $pharmacistLog->log_info = $pharmacist->name.'在'.$review_at.'为'.$patient->name.'（'.$patient->mobile.'）审方(处方单编号：'.$prescription_number.')';
            $pharmacistLog->save();
        } elseif ($pharmacy->is_auto == 0) {
            // 手动审方发送药店通知短信
            if (env('SMS_CHANNEL') == 'chengliye') {
                $templateName = 'pharmacist_notification';
                $templateData = [];
                $smsService = new SmsService();
                $response = $smsService->sendSms($pharmacy->mobile, $templateName, $templateData);
                Log::info(json_encode($response));
            } elseif (env('SMS_CHANNEL') == 'qcloud') { // 腾讯短信
                $easySms = new EasySms(config('easysms'));
                $response = $easySms->send($pharmacy->mobile, [
                    'content' => '您有一条处方需要审方。',
                    'template' => '2316307',
                    'data' => [],
                ]);
                Log::info(json_encode($response));
            }
        }

        return $this->success($prescription_number);

    }

    // 处方作废
    public function invalid(Request $request)
    {
        $authInfo = auth('api')->user();
        // 获取药店信息
        $pharmacy = PharmacyModel::where('user_id', $authInfo->id)->first();
        // 只有药店端可进行处方作废
        $prescription_id = $request->input('prescription_id');
        $prescription = PrescriptionModel::where('id', $prescription_id)
            ->where('pharmacy_id', $pharmacy->id)
            ->first();

        if ($prescription) {
            $prescription->is_voided = 1;
            if ($prescription->save()) {
                return $this->success('处方作废成功');
            }
        }

        return $this->failed('处方作废失败');

    }
}
