<?php

namespace App\Services;

use App\Amqp\Producer\CancelUnInquiryOrdersDelayDirectProducer;
use App\Amqp\Producer\CancelUnPayInquiryOrderDelayProducer;
use App\Amqp\Producer\CancelUnpayOrdersDelayDirectProducer;
use App\Constants\DoctorTitleCode;
use App\Constants\HttpEnumCode;
use App\Exception\BusinessException;
use App\Model\DiseaseClass;
use App\Model\DoctorInquiryConfig;
use App\Model\Hospital;
use App\Model\InquiryCaseProduct;
use App\Model\OrderEvaluation;
use App\Model\OrderInquiry;
use App\Model\OrderInquiryCase;
use App\Model\OrderInquiryCoupon;
use App\Model\OrderInquiryRefund;
use App\Model\PatientFamily;
use App\Model\PatientFamilyHealth;
use App\Model\PatientFamilyPersonal;
use App\Model\PatientFollow;
use App\Model\Product;
use App\Model\SystemInquiryConfig;
use App\Model\User;
use App\Model\UserCoupon;
use App\Model\UserDoctor;
use App\Model\UserPatient;
use App\Utils\Log;
use App\Utils\Mask;
use App\Utils\PcreMatch;
use Extend\Wechat\WechatPay;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Amqp\Producer;
use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use Hyperf\Snowflake\IdGeneratorInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

/**
 * 问诊
 */
class InquiryService extends BaseService
{
    /**
     * 创建问诊订单
     * @return array
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function addInquiryOrder(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];
        $request_params = $this->request->all();

        // 检测家庭成员是否存在
        $params = array();
        $params['family_id'] = $request_params['family_id'];
        $params['patient_id'] = $user_info['client_user_id'];
        $params['status'] = 1;
        $patient_family = PatientFamily::getOne($params);
        if (empty($patient_family)) {
            return fail(HttpEnumCode::HTTP_ERROR, "患者信息错误");
        }

        // 检测是否存在同类型未完成的问诊订单
        $PatientOrderService = new PatientOrderService();
        $order_inquiry_id = $PatientOrderService->getNotFinishedOrdeInquiry($user_info['client_user_id']);
        if (!empty($order_inquiry_id)) {
            return fail(HttpEnumCode::HTTP_ERROR, "当前患者存在进行中的问诊订单");
        }

        // 是否为孕妇
        if (!empty($request_params['is_pregnant'])) {
            return fail(HttpEnumCode::HTTP_ERROR, "请您到线下问诊");
        }

        // 是否存在禁忌
        if (!empty($request_params['is_taboo'])) {
            return fail(HttpEnumCode::HTTP_ERROR, "无法为您开具药物");
        }

        // 检测所患疾病是否正确
        $params = array();
        $params['disease_class_id'] = $request_params['disease_class_id'];
        $params['disease_class_status'] = 1;
        $disease_class = DiseaseClass::getOne($params);
        if (empty($disease_class)) {
            return fail(HttpEnumCode::HTTP_ERROR, "疾病信息填写错误");
        }

        // 获取当前问诊医生信息
        // 专家问诊-公益问诊
        if ($request_params['inquiry_type'] == 3 || $request_params['inquiry_type'] == 1) {
            if (empty($request_params['doctor_id'])) {
                return fail(HttpEnumCode::HTTP_ERROR, "未选择医生");
            }

            $params = array();
            $params['doctor_id'] = $request_params['doctor_id'];
            $doctor = UserDoctor::getOne($params);
            if (empty($doctor)) {
                return fail(HttpEnumCode::HTTP_ERROR, "未知医生");
            }

            if ($doctor['idcard_status'] != 1) {
                return fail(HttpEnumCode::HTTP_ERROR, "当前医生无法接诊，请重新选择");
            }

            if ($doctor['iden_auth_status'] != 1) {
                return fail(HttpEnumCode::HTTP_ERROR, "当前医生无法接诊，请重新选择");
            }
        }

        // 获取问诊价格
        $DoctorInquiryService = new DoctorInquiryService();
        $inquiry_price = $DoctorInquiryService->getDoctorInquiryPrice($request_params['inquiry_type'], $request_params['inquiry_mode'], $request_params['doctor_id'] ?: "");

        // 获取可用优惠卷
        $CouponService = new CouponService();
        $user_coupon = $CouponService->getUserUsableCouponOne($user_info['user_id'], $request_params['inquiry_type']);

        // 确定支付渠道
        // 支付渠道（1:小程序支付 2:微信扫码支付）
        if ($request_params['client_type'] == 1) {
            $inquiry_pay_channel = 1;
        } elseif ($request_params['client_type'] == 2) {
            $inquiry_pay_channel = 2;
        }

        Db::beginTransaction();

        $generator = $this->container->get(IdGeneratorInterface::class);

        try {
            // 实际付款金额
            $coupon_amount_total = $user_coupon['coupon']['coupon_price'] ?? 0;
            $payment_amount_total = $inquiry_price - $coupon_amount_total;
            if ($payment_amount_total < 0) {
                $payment_amount_total = 0;
            }

            // 生成问诊订单
            $data = array();
            $data['user_id'] = $user_info['user_id'];
            $data['patient_id'] = $user_info['client_user_id'];
            $data['doctor_id'] = $request_params['doctor_id'] ?? "";
            $data['family_id'] = $request_params['family_id'];
            $data['inquiry_type'] = $request_params['inquiry_type'];
            $data['inquiry_mode'] = $request_params['inquiry_mode'];
            $data['inquiry_status'] = 1;// 1:待支付
            $data['inquiry_pay_channel'] = $inquiry_pay_channel ?? 0;// 支付渠道（1:小程序支付 2:微信扫码支付）
            $data['inquiry_no'] = $generator->generate();// 订单编号
            $data['amount_total'] = $inquiry_price;// 订单金额
            $data['coupon_amount_total'] = $coupon_amount_total;// 优惠卷总金额
            $data['payment_amount_total'] = $payment_amount_total;// 实际付款金额
            $data['patient_name'] = $patient_family['card_name'];// 患者姓名-就诊人
            $data['patient_name_mask'] = $patient_family['card_name_mask'];// 患者姓名-就诊人(掩码)
            $data['patient_sex'] = $patient_family['sex'];// 患者性别-就诊人（0:未知 1:男 2:女）
            $data['patient_age'] = $patient_family['age'];// 患者年龄-就诊人
            $order_inquiry = OrderInquiry::addOrderInquiry($data);
            if (empty($order_inquiry)) {
                Db::rollBack();
                return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败");
            }

            // 处理复诊凭证
            if (!empty($request_params['diagnose_images'])) {
                // 医师资格证
                $diagnose_images = implode(',', $request_params['diagnose_images']);
                $diagnose_images = PcreMatch::pregRemoveOssWebsite($diagnose_images);
            }

            // 增加患者问诊病例
            $data = array();
            $data['user_id'] = $user_info['user_id'];
            $data['patient_id'] = $user_info['client_user_id'];
            $data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];// 订单-问诊id
            $data['family_id'] = $patient_family['family_id']; // 家庭成员id
            $data['relation'] = $patient_family['relation']; // 与患者关系（1:本人 2:父母 3:爱人 4:子女 5:亲戚 6:其他 ）
            $data['name'] = $patient_family['card_name']; // 患者名称
            $data['sex'] = $patient_family['sex'] ?? 0; // 患者性别（0:未知 1:男 2:女）
            $data['age'] = $patient_family['age'] ?? null; // 患者年龄
            $data['height'] = $request_params['height'] ?? $patient_family['height'] ?: null; // 身高（cm）
            $data['weight'] = $request_params['weight'] ?? $patient_family['weight'] ?: null;; // 体重（kg）
            $data['disease_class_id'] = $disease_class['disease_class_id']; // 疾病分类id-系统
            $data['disease_class_name'] = $disease_class['disease_class_name']; // 疾病名称-系统
            $data['diagnosis_date'] = $request_params['diagnosis_date'] ?: null; // 确诊日期
            $data['disease_desc'] = $request_params['disease_desc'] ?: null; // 病情描述（主诉）
            $data['diagnose_images'] = $diagnose_images ?? ""; // 复诊凭证(多个使用逗号分隔)
            $data['is_allergy_history'] = $request_params['is_allergy_history'] ?: 0; // 是否存在过敏史（0:否 1:是）
            $data['allergy_history'] = $request_params['allergy_history'] ?? null; // 过敏史描述
            $data['is_family_history'] = $request_params['is_family_history'] ?: 0; // 是否存在家族病史（0:否 1:是）
            $data['family_history'] = $request_params['family_history'] ?? null; // 家族病史描述
            $data['is_pregnant'] = $request_params['is_pregnant'] ?: 0; // 是否备孕、妊娠、哺乳期（0:否 1:是）
            $data['is_taboo'] = $request_params['is_taboo'] ?? 0; // 是否存在禁忌药物（0:否 1:是）问诊购药时存在
            $order_inquiry_case = OrderInquiryCase::addOrderInquiryCase($data);
            if (empty($order_inquiry_case)) {
                Db::rollBack();
                return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败");
            }

            // 增加问诊优惠卷表
            if (!empty($user_coupon)) {
                $data = array();
                $data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];// 订单-问诊id
                $data['user_coupon_id'] = $user_coupon['user_coupon_id'];
                $data['coupon_name'] = $user_coupon['coupon']['coupon_name'];
                $data['coupon_use_price'] = $user_coupon['coupon']['coupon_price'];
                $order_inquiry_coupon = OrderInquiryCoupon::addOrderInquiryCoupon($data);
                if (empty($order_inquiry_coupon)) {
                    Db::rollBack();
                    return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败");
                }
            }

            // 意向用药处理
            if ($request_params['inquiry_type'] == 4 && !empty($request_params['product'])) {
                foreach ($request_params['product'] as $item) {
                    $params = array();
                    $params['product_id'] = $item['product_id'];
                    $product = Product::getWithAmountOne($params);
                    if (empty($product)) {
                        Db::rollBack();
                        return fail(HttpEnumCode::HTTP_ERROR, "意向药品错误");
                    }

                    // 用药意向是否和过敏史重叠
                    if (!empty($request_params['allergy_history'])) {
                        $res = strpos($request_params['allergy_history'], $product['product_name']);
                        if ($res !== false) {
                            Db::rollBack();
                            return fail(HttpEnumCode::HTTP_ERROR, "过敏史中存在意向用药，请您仔细检查");
                        }
                    }

                    // 新增病例商品表
                    $data = array();
                    $data['inquiry_case_id'] = $order_inquiry_case['inquiry_case_id'];
                    $data['product_id'] = $item['product_id'];
                    $data['case_product_num'] = $item['product_num'];
                    $inquiry_case_product = InquiryCaseProduct::addInquiryCaseProduct($data);
                    if (empty($inquiry_case_product)) {
                        Db::rollBack();
                        return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败");
                    }
                }
            }

            // 修改优惠卷使用状态
            if (!empty($user_coupon)) {
                $data = array();
                $data['user_coupon_status'] = 1;
                $data['coupon_use_date'] = date('Y-m-d H:i:s', time());

                $params = array();
                $params['user_coupon_id'] = $user_coupon['user_coupon_id'];
                UserCoupon::edit($params, $data);
            }

            // 增加至取消订单延迟队列
            $data = array();
            $data['order_no'] = $order_inquiry['inquiry_no'];
            $data['order_type'] = 1;

            $message = new CancelUnpayOrdersDelayDirectProducer($data);
            $message->setDelayMs(1000 * 60 * 30);
            $producer = $this->container->get(Producer::class);
            $res = $producer->produce($message);
            if (!$res) {
                Db::rollBack();
                return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败");
            }

            // 加入未接诊取消订单延迟队列
            if (!empty($request_params['doctor_id']) && ($request_params['inquiry_type'] == 1 || $request_params['inquiry_type'] == 3)){
                $data = array();
                $data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
                $message = new CancelUnInquiryOrdersDelayDirectProducer($data);
                $message->setDelayMs(1000 * 60 * 60 * 24);
                $producer = $this->container->get(Producer::class);
                $res = $producer->produce($message);
                if (!$res) {
                    Db::rollBack();
                    return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败");
                }
            }

            Db::commit();
        } catch (\Exception $e) {
            Db::rollBack();
            return fail(HttpEnumCode::HTTP_ERROR, $e->getMessage());
        }

        $result = array();
        $result['inquiry_no'] = (string)$order_inquiry['inquiry_no']; // 订单编号
        $result['order_inquiry_id'] = (string)$order_inquiry['order_inquiry_id']; // 订单主键id

        return success($result);
    }

    /**
     * 获取患者问诊病例
     * @return array
     */
    public function getPatientInquiryCase(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];
        $order_inquiry_id = $this->request->input('order_inquiry_id');

        // 获取用户数据
        $params = array();
        $params['user_id'] = $user_info['user_id'];
        $user = User::getOne($params);
        if (empty($user)) {
            return fail();
        }

        // 获取订单数据
        $params = array();
        $params['order_inquiry_id'] = $order_inquiry_id;
        if ($user['user_type'] == 1) {
            $params['patient_id'] = $user_info['client_user_id'];
        } elseif ($user['user_type'] == 2) {
            $params['doctor_id'] = $user_info['client_user_id'];
        }
        $order_inquiry = OrderInquiry::getOne($params);
        if (empty($order_inquiry)) {
            return fail();
        }

        // 获取病例信息
        $params = array();
        $params['order_inquiry_id'] = $order_inquiry_id;
        $params['status'] = 1;
        $order_inquiry_case = OrderInquiryCase::getOne($params);
        if (empty($order_inquiry_case)) {
            return fail();
        }

        // 获取患者家庭成员信息表-基本信息
        $params = array();
        $params['family_id'] = $order_inquiry_case['family_id'];
        $patient_family = PatientFamily::getOne($params);

        $order_inquiry_case['height'] = $order_inquiry_case['height'] ?: $patient_family['height'] ?: NULL;
        $order_inquiry_case['weight'] = $order_inquiry_case['weight'] ?: $patient_family['weight'] ?: NULL;
        $order_inquiry_case['job_name'] = $patient_family['job_name'] ?? "";
        $order_inquiry_case['nation_name'] = $patient_family['nation_name'] ?? "";
        $order_inquiry_case['marital_status'] = $patient_family['marital_status'] ?? 0;

        // 获取患者家庭成员信息表-健康情况
        $params = array();
        $params['family_id'] = $order_inquiry_case['family_id'];
        $patient_family_health = PatientFamilyHealth::getOne($params);
        $order_inquiry_case['diagnosis_hospital'] = $patient_family_health['diagnosis_hospital'] ?? "";
        $order_inquiry_case['drugs_name'] = $patient_family_health['drugs_name'] ?? "";

        // 获取患者家庭成员信息表-个人情况
        $params = array();
        $params['family_id'] = $order_inquiry_case['family_id'];
        $patient_family_personal = PatientFamilyPersonal::getOne($params);

        $order_inquiry_case['drink_wine_status'] = $patient_family_personal['drink_wine_status'] ?? 1;
        $order_inquiry_case['smoke_status'] = $patient_family_personal['smoke_status'] ?? 1;
        $order_inquiry_case['chemical_compound_status'] = $patient_family_personal['chemical_compound_status'] ?? 1;
        $order_inquiry_case['chemical_compound_describe'] = $patient_family_personal['chemical_compound_describe'] ?? "";
        $order_inquiry_case['is_operation'] = $patient_family_personal['is_operation'] ?? 0;
        $order_inquiry_case['operation'] = $patient_family_personal['operation'] ?? "";

        // 获取用药意向
        $product = [];
        $fields = [
            'inquiry_case_id',
            'product_id',
            'case_product_num',
        ];
        $params = array();
        $params['inquiry_case_id'] = $order_inquiry_case['inquiry_case_id'];
        $inquiry_case_product = InquiryCaseProduct::getWithProductList($params, $fields);
        if (!empty($inquiry_case_product)) {
            foreach ($inquiry_case_product as &$item) {
                if (!empty($item['Product'])) {
                    $product[] = $item['Product']['product_name'] . ' ' . $item['Product']['product_spec'] . '(' . $item['case_product_num'] . $item['Product']['packaging_unit'] . ')';
                }
            }
        }

        $order_inquiry_case['product'] = $product;
        unset($inquiry_case_product);

        // 复诊凭证
        if (!empty($order_inquiry_case['diagnose_images'])) {
            $diagnose_images = explode(',', $order_inquiry_case['diagnose_images']);
            foreach ($diagnose_images as &$item) {
                $item = addAliyunOssWebsite($item);
            }

            $order_inquiry_case['diagnose_images'] = $diagnose_images;
        }

        return success($order_inquiry_case->toArray());
    }

    /**
     * 检测快速、购药订单分配医生状态
     * @return array
     */
    public function getInquiryAssign(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];
        $order_inquiry_id = $this->request->route('order_inquiry_id');

        $params = array();
        $params['order_inquiry_id'] = $order_inquiry_id;
        $params['patient_id'] = $user_info['client_user_id'];
        $order_inquiry = OrderInquiry::getOne($params);
        if (empty($order_inquiry)) {
            return fail();
        }

        if (empty($order_inquiry['doctor_id'])) {
            return success();
        }

        // 检测订单类型
        if ($order_inquiry['inquiry_type'] != 2 && $order_inquiry['inquiry_type'] != 4) {
            return fail(HttpEnumCode::HTTP_ERROR, "订单类型不允许检测");
        }

        // 检测订单退款状态
        if (!in_array($order_inquiry['inquiry_refund_status'], [0, 4, 5])) {
            // 问诊订单退款状态（0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭）
            return fail(HttpEnumCode::HTTP_ERROR, "订单已退款");
        }

        // 获取医生数据
        $params = array();
        $params['doctor_id'] = $order_inquiry['doctor_id'];
        $user_doctor = UserDoctor::getOne($params);
        if (empty($user_doctor)) {
            return fail(HttpEnumCode::SERVER_ERROR);
        }

        $result = array();
        $result['doctor_id'] = $order_inquiry['doctor_id'];
        $result['user_id'] = $user_doctor['user_id'];

        return success($result);
    }

    /**
     * 新增问诊评价
     * @return array
     */
    public function addInquiryEvaluation(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];
        $doctor_id = $this->request->input('doctor_id');
        $order_inquiry_id = $this->request->input('order_inquiry_id');
        $reply_quality = $this->request->input('reply_quality');
        $service_attitude = $this->request->input('service_attitude');
        $reply_progress = $this->request->input('reply_progress'); //
        $content = $this->request->input('content');

        $params = array();
        $params['order_inquiry_id'] = $order_inquiry_id;
        $params['patient_id'] = $user_info['client_user_id'];
        $order_inquiry = OrderInquiry::getOne($params);
        if (empty($order_inquiry)) {
            return fail();
        }

        // 检测订单状态
        if ($order_inquiry['inquiry_status'] != 5) {
            // 问诊订单状态（1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消）
            return fail(HttpEnumCode::HTTP_ERROR, "请问诊完成后进行评价");
        }

        // 检测是否评价过
        $params = array();
        $params['doctor_id'] = $doctor_id;
        $params['patient_id'] = $user_info['client_user_id'];
        $params['order_inquiry_id'] = $order_inquiry_id;;
        $order_evaluation = OrderEvaluation::getOne($params);
        if (!empty($order_evaluation)) {
            // 已评价
            return success();
        }

        // 获取用户数据
        $params = array();
        $params['patient_id'] = $user_info['client_user_id'];
        $user_patient = UserPatient::getOne($params);

        // 整理数据
        $reply_quality = $reply_quality * 20;
        $service_attitude = $service_attitude * 20;
        $reply_progress = $reply_progress * 20;

        // 计算平均值 （百分制，回复质量占4、服务态度占3、回复速度占3，计算公式：每个得分 * 占比 相加）
        $avg_score = $reply_quality * 0.4 + $service_attitude * 0.3 + $reply_progress * 0.3;

        $data = array();
        $data['doctor_id'] = $doctor_id;
        $data['patient_id'] = $user_info['client_user_id'];
        $data['order_inquiry_id'] = $order_inquiry_id;
        $data['name_mask'] = Mask::maskNameStr($user_patient['user_name']);
        $data['reply_quality'] = $reply_quality;
        $data['service_attitude'] = $service_attitude;
        $data['reply_progress'] = $reply_progress;
        $data['avg_score'] = $avg_score;
        $data['type'] = 1;
        $data['content'] = $content;
        $order_evaluation = OrderEvaluation::addOrderEvaluation($data);
        if (empty($order_evaluation)) {
            return fail();
        }

        return success();
    }

    /**
     * 获取问诊最低价格
     * @return array
     */
    public function getInquiryLowestPrice(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];

        // 快速
        $quick_inquiry_price = 0;
        $params = array();
        $params['inquiry_type'] = 2;
        $params['inquiry_mode'] = 1;
        $system_inquiry_config = SystemInquiryConfig::getOne($params);
        if (!empty($system_inquiry_config)) {
            $quick_inquiry_price = $system_inquiry_config['inquiry_price'];
        }

        // 问诊购药
        $medicine_inquiry_price = 0;
        $params = array();
        $params['inquiry_type'] = 4;
        $params['inquiry_mode'] = 1;
        $system_inquiry_config = SystemInquiryConfig::getOne($params);
        if (!empty($system_inquiry_config)) {
            $medicine_inquiry_price = $system_inquiry_config['inquiry_price'];
        }

        // 专家问诊
        $expert_inquiry_price = 0;
        $params = array();
        $params['inquiry_type'] = 1;
        $params['inquiry_mode'] = 1;
        $expert_inquiry_price = DoctorInquiryConfig::getMinInquiryPriceMinOne($params);
        if (empty($expert_inquiry_price) || $expert_inquiry_price == 0) {
            $params = array();
            $params['inquiry_type'] = 1;
            $params['inquiry_mode'] = 1;
            $system_inquiry_config = SystemInquiryConfig::getOne($params);
            if (!empty($system_inquiry_config)) {
                $expert_inquiry_price = $system_inquiry_config['min_inquiry_price'];
            }
        }

        // 公益问诊
        $params = array();
        $params['inquiry_type'] = 1;
        $params['inquiry_mode'] = 1;
        $welfare_inquiry_price = DoctorInquiryConfig::getMinInquiryPriceMinOne($params);

        if (empty($welfare_inquiry_price) || $welfare_inquiry_price == 0) {
            $params = array();
            $params['inquiry_type'] = 1;
            $params['inquiry_mode'] = 1;
            $system_inquiry_config = SystemInquiryConfig::getOne($params);
            if (!empty($system_inquiry_config)) {
                $inquiry_price = explode(',', $system_inquiry_config['inquiry_price']);
                $welfare_inquiry_price = $inquiry_price[0] ?? 0;
            }
        }

        $result = array();
        $result['quick_inquiry_price'] = $quick_inquiry_price;
        $result['medicine_inquiry_price'] = $medicine_inquiry_price;
        $result['expert_inquiry_price'] = $expert_inquiry_price;
        $result['welfare_inquiry_price'] = $welfare_inquiry_price;

        return success($result);
    }

    /**
     * 获取问诊订单消息内页基础数据
     * @return array
     */
    public function getInquiryMessageBasic(): array
    {
        $user_info = $this->request->getAttribute("userInfo") ?? [];
        $order_inquiry_id = $this->request->route('order_inquiry_id');

        $params = array();
        $params['order_inquiry_id'] = $order_inquiry_id;
        $order_inquiry = OrderInquiry::getOne($params);
        if (empty($order_inquiry)) {
            return fail(HttpEnumCode::HTTP_ERROR,"订单错误");
        }

        if ($user_info['user_type'] == 1){
            if ($order_inquiry['patient_id'] != $user_info['client_user_id']){
                return fail(HttpEnumCode::SERVER_ERROR);
            }
        }

        if ($user_info['user_type'] == 2){
            if ($order_inquiry['doctor_id'] != $user_info['client_user_id']){
                return fail(HttpEnumCode::SERVER_ERROR);
            }
        }

        $params = array();
        $params['doctor_id'] = $order_inquiry['doctor_id'];
        $user_doctor = UserDoctor::getOne($params);
        if (empty($user_doctor)) {
            return fail();
        }

        $times_number = 0; // 沟通次数
        $duration = 0; // 沟通时长
        $follow = false; // 关注状态
        $is_evaluation = false; // 评价状态

        if ($user_info['user_type'] == 1){

            // 沟通次数，沟通时长
            $params = array();
            $params['inquiry_type'] = $order_inquiry['inquiry_type'];
            $params['inquiry_mode'] = $order_inquiry['inquiry_mode'];
            $system_inquiry_config = SystemInquiryConfig::getOne($params);
            if (!empty($system_inquiry_config)){
                $times_number = $system_inquiry_config['times_number'];
                $duration = $system_inquiry_config['duration'];
            }

            // 关注状态
            $params = array();
            $params['patient_id'] = $user_info['client_user_id'];
            $params['doctor_id'] = $order_inquiry['doctor_id'];
            $follow = PatientFollow::getExists($params);

            // 评价状态
            $params = array();
            $params['doctor_id'] = $order_inquiry['doctor_id'];
            $params['patient_id'] = $user_info['client_user_id'];
            $params['order_inquiry_id'] = $order_inquiry_id;;
            $is_evaluation = OrderEvaluation::getExists($params);
        }



        $result = array();
        $result['doctor_user_id'] = $user_doctor['user_id'];
        $result['patient_user_id'] = $order_inquiry['user_id'];
        $result['doctor_id'] = $order_inquiry['doctor_id'];
        $result['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
        $result['patient_family_name'] = $order_inquiry['patient_name'];
        $result['patient_family_sex'] = $order_inquiry['patient_sex'];
        $result['patient_family_age'] = $order_inquiry['patient_age'];
        $result['inquiry_type'] = $order_inquiry['inquiry_type'];
        $result['inquiry_status'] = $order_inquiry['inquiry_status'];
        $result['times_number'] = $times_number;
        $result['duration'] = $duration;
        $result['follow'] = $follow;
        $result['is_evaluation'] = $is_evaluation;
        $result['reception_time'] = $order_inquiry['reception_time'] ?: null; // 接诊时间

        return success($result);
    }

    /**
     * 获取医生未接诊订单数量
     * @param string $doctor_id 医生id
     * @return int
     */
    public function getDoctorNotAcceptedInquiryNum(string $doctor_id): int
    {
        $params = array();
        $params['doctor_id'] = $doctor_id;
        $params['inquiry_status'] = 3; // 待接诊
        $params['inquiry_refund_status'] = 0; // 无退款

        $order_inquiry_count = OrderInquiry::getCount($params);
        if (!empty($order_inquiry_count) || $order_inquiry_count != 0) {
            $not_accepted_inquiry_num = $order_inquiry_count;
        } else {
            $not_accepted_inquiry_num = $order_inquiry_count;
        }

        return $not_accepted_inquiry_num;
    }

    /**
     * 获取医生接诊中订单数量
     * @param string $doctor_id 医生id
     * @param string $inquiry_type 订单类型（1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药）
     * @return int
     */
    public function getDoctorAcceptingInquiryNum(string $doctor_id, string $inquiry_type = ""): int
    {
        $params = array();
        $params['doctor_id'] = $doctor_id;
        if (!empty($inquiry_type)) {
            $params['inquiry_type'] = $inquiry_type; // 订单类型（1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药）
        }
        $params['inquiry_status'] = 4; // 已接诊
        $params['inquiry_refund_status'] = 0; // 无退款

        $order_inquiry_count = OrderInquiry::getCount($params);
        if (!empty($order_inquiry_count) || $order_inquiry_count != 0) {
            $accepting_inquiry_num = $order_inquiry_count;
        } else {
            $accepting_inquiry_num = $order_inquiry_count;
        }

        return $accepting_inquiry_num;
    }

    /**
     * 获取医生当日接诊的订单金额
     * 状态：已接诊-已完成
     * @param string $doctor_id
     * @param string $date
     * @return float
     */
    public function getDoctorDayAmountTotal(string $doctor_id, string $date): float
    {
        // 获取当天开始时间
        $start_date = date('Y-m-d 00:00:00', strtotime($date));

        // 获取当天结束时间
        $end_date = date('Y-m-d 23:59:59', strtotime($date));

        // 获取医生当日接诊订单金额
        $params = array();
        $params['doctor_id'] = $doctor_id;
        $params['inquiry_refund_status'] = 0; // 问诊订单退款状态（0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭）
        $params['inquiry_pay_status'] = 2; // 支付状态（1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款）
        $params['settlement_status'] = 0; // 订单与医生结算状态（0:未结算 1:已结算）

        $reception_time = [$start_date, $end_date];

        $inquiry_status_params = [4, 5]; // 问诊订单状态（1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消）

        $amount_total_sum = OrderInquiry::getOrderInquiryAmountTotalSum($params, $reception_time, $inquiry_status_params);

        return $amount_total_sum ?: 0;
    }

    /**
     * 获取患者某一状态下的问诊订单数量
     * @param string $patient_id 患者id
     * @param int $inquiry_status 问诊订单状态（1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消）
     * @return int
     */
    public function getPatientInquiryWithStatus(string $patient_id, int $inquiry_status): int
    {
        $params = array();
        $params['patient_id'] = $patient_id;
        $params['inquiry_status'] = $inquiry_status;
        return OrderInquiry::getCount($params);
    }

    /**
     * 问诊订单退款接口
     * 务必外层接收异常，回滚事务
     * @param string $order_inquiry_id
     * @param string $refund_reason 退款原因
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|GuzzleException
     */
    public function inquiryRefund(string $order_inquiry_id, string $refund_reason)
    {
        // 获取订单数据
        $params = array();
        $params['order_inquiry_id'] = $order_inquiry_id;
        $order_inquiry = OrderInquiry::getOne($params);
        if (empty($order_inquiry)) {
            throw new BusinessException("订单数据为空");
        }

        // 检测问诊订单状态
        if (!in_array($order_inquiry['inquiry_status'], [2, 3, 4, 5, 7])) {
            // 问诊订单状态（1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消）
            throw new BusinessException("订单状态错误");
        }

        // 检测订单退款状态
        if (in_array($order_inquiry['inquiry_refund_status'], [2, 3, 5])) {
            // 问诊订单退款状态（0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭）
            throw new BusinessException("订单退款状态错误");
        }

        // 检测支付状态
        if ($order_inquiry['inquiry_pay_status'] != 2) {
            // 支付状态（1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款）
            throw new BusinessException("订单支付状态错误");
        }

        // 发起退款
        $WechatPay = new WechatPay(1, 1);

        $generator = $this->container->get(IdGeneratorInterface::class);

        // 系统退款编号
        $inquiry_refund_no = $generator->generate();

        $options = array();
        $options['transaction_id'] = $order_inquiry['escrow_trade_no'];
        $options['out_refund_no'] = (string)$inquiry_refund_no;
        $options['reason'] = $refund_reason;
        $options['amount'] = [
            'refund' => (int)($order_inquiry['payment_amount_total'] * 100),
            'total' => (int)($order_inquiry['payment_amount_total'] * 100),
            'currency' => "CNY",
        ];

        $result = $WechatPay->refund($options);

        // 处理订单退款状态
        // 问诊订单退款状态（0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭）
        if ($result['status'] == "SUCCESS") {
            // 退款成功
            $inquiry_refund_status = 3;
        } elseif ($result['status'] == "CLOSED") {
            // 退款关闭
            $inquiry_refund_status = 5;
        } elseif ($result['status'] == "PROCESSING") {
            // 退款处理中
            $inquiry_refund_status = 2;
        } elseif ($result['status'] == "ABNORMAL") {
            // 退款异常,此情况不处理，进行短信通知
            throw new BusinessException("订单退款状态异常");
        } else {
            throw new BusinessException("订单退款状态错误");
        }

        // 新增退款表
        $data = array();
        $data['patient_id'] = $order_inquiry['patient_id'];
        $data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
        $data['inquiry_no'] = $order_inquiry['inquiry_no'];
        $data['inquiry_refund_no'] = $inquiry_refund_no;
        $data['refund_id'] = $result['refund_id'];
        $data['inquiry_refund_status'] = $inquiry_refund_status;
        $data['refund_total'] = $order_inquiry['payment_amount_total'];
        $data['refund_reason'] = $refund_reason;

        if ($inquiry_refund_status == 3 && !empty($result['success_time'])) {
            $data['success_time'] = date("Y-m-d H:i:s", strtotime($result['success_time'])); // 退款成功时间
        }

        $order_inquiry_refund = OrderInquiryRefund::addOrderInquiryRefund($data);
        if (empty($order_inquiry_refund)) {
            throw new BusinessException("添加退款表失败");
        }

        // 修改问诊订单表状态
        $data = array();
        $data['inquiry_refund_status'] = $inquiry_refund_status;

        $params = array();
        $params['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
        OrderInquiry::edit($params, $data);


        // 存在问诊医生时，需发送退款消息
        if (!empty($order_inquiry['doctor_id'])){
            // 获取医生数据
            $params = array();
            $params['doctor_id'] = $order_inquiry['doctor_id'];
            $user_doctor = UserDoctor::getOne($params);
            if (empty($user_doctor)){
                throw new BusinessException("医生数据错误");
            }

            // 发送问诊消息
            $ImService = new ImService();

            // 发送消息
            $cloud_custom_data = array();
            $cloud_custom_data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
            $cloud_custom_data['is_system'] = 1;
            $cloud_custom_data['inquiry_type'] = $order_inquiry['inquiry_type'];
            $cloud_custom_data['message_rounds'] = 0;
            $cloud_custom_data['patient_family_data']['patient_name'] = $order_inquiry['patient_name'];
            $cloud_custom_data['patient_family_data']['patient_sex'] = $order_inquiry['patient_sex'];
            $cloud_custom_data['patient_family_data']['patient_age'] = $order_inquiry['patient_age'];

            // 消息内容
            $message_content_data = array();
            $message_content_data['message_type'] = 1;
            $message_content_data['title'] = "问诊已结束";
            $message_content_data['desc'] = "线上咨询不能代替问诊，医生的回复仅为建议。";
            $message_content = [
                'Data' => json_encode($message_content_data,JSON_UNESCAPED_UNICODE),
            ];

            $ImService->sendMessage($user_doctor['user_id'], $order_inquiry['user_id'], $message_content, "TIMCustomElem", $cloud_custom_data);
        }
    }

    /**
     * 取消未支付的问诊订单
     * @param string|int $order_no 系统订单编号
     * @param string|int $cancel_reason 取消订单原因（1:医生未接诊 2:主动取消 3:无可分配医生 4:客服取消 5:支付超时）
     * @param string|int $cancel_remarks 取消订单备注
     * @return array
     */
    public function cancelUnpayInquiryOrder(string|int $order_no, string|int $cancel_reason, string|int $cancel_remarks): array
    {
        $result = array();
        $result['status'] = 1;
        $result['message'] = "成功";

        // 获取订单数据
        $params = array();
        $params['inquiry_no'] = $order_no;
        $order_inquiry = OrderInquiry::getOne($params);
        if (empty($order_inquiry)) {
            $result['status'] = 0;
            $result['message'] = "取消未支付的问诊订单失败：未查询到对应订单数据";
            return $result;
        }

        // 检测订单状态
        if ($order_inquiry['inquiry_status'] == 7) {
            // 问诊订单状态（1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消）
            $result['status'] = 2;
            $result['message'] = "取消未支付的问诊订单：订单已取消";
            return $result;
        }

        if ($order_inquiry['inquiry_status'] != 1) {
            // 问诊订单状态（1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消）
            $result['status'] = 0;
            $result['message'] = "取消未支付的问诊订单：订单状态为" . $order_inquiry['inquiry_status'] . "无法执行";
            return $result;
        }

        if (!in_array($order_inquiry['inquiry_refund_status'], [0, 4, 5])) {
            // 问诊订单退款状态（0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭）
            $result['status'] = 0;
            $result['message'] = "取消未支付的问诊订单：订单正在退款中";
            return $result;
        }

        if ($order_inquiry['inquiry_pay_status'] == 2) {
            // 支付状态（1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款）
            $result['status'] = 2;
            $result['message'] = "取消未支付的问诊订单：订单已支付";
            return $result;
        }

        // 检测订单删除状态
        if ($order_inquiry['is_delete'] == 1) {
            // 删除状态（0:否 1:是）
            $result['status'] = 2;
            $result['message'] = "取消未支付的问诊订单：订单已被删除";
            return $result;
        }

        // 取消问诊订单
        $data = array();
        $data['inquiry_status'] = 7;
        $data['inquiry_pay_status'] = 5;
        $data['cancel_time'] = date("Y-m-d H:i:s", time());
        $data['cancel_reason'] = $cancel_reason; // 取消订单原因（1:医生未接诊 2:主动取消 3:无可分配医生 4:客服取消 5:支付超时）
        $data['cancel_remarks'] = $cancel_remarks; // 取消订单备注
        $data['updated_at'] = date("Y-m-d H:i:s", time());

        $params = array();
        $params['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
        OrderInquiry::edit($params, $data);

        // 处理订单优惠卷
        if (!empty($order_inquiry['coupon_amount_total']) && $order_inquiry['coupon_amount_total'] > 0) {
            // 获取用户优惠卷信息
            $params = array();
            $params['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
            $order_inquiry_coupon = OrderInquiryCoupon::getOne($params);
            if (!empty($order_inquiry_coupon)) {
                // 恢复优惠卷
                $data = array();
                $data['user_coupon_status'] = 0;
                $data['coupon_use_date'] = date('Y-m-d H:i:s', time());

                $params = array();
                $params['user_coupon_id'] = $order_inquiry_coupon['user_coupon_id'];
                UserCoupon::edit($params, $data);
            }
        }

        return $result;
    }

    /**
     * 检测当前医生是否和患者存在未完成问诊订单
     * @param string $patient_id
     * @param string $doctor_id
     * @return array
     */
    public function checkPatientDoctorProgressInquiry(string $patient_id, string $doctor_id): array
    {
        $params = array();
        if (!empty($patient_id)) {
            $params[] = ['patient_id', '=', $patient_id];
        }

        if (!empty($family_id)) {
            $params[] = ['family_id', '=', $family_id];
        }

        $params = array();
        $params[] = ['patient_id', '=', $patient_id];
        $params[] = ['doctor_id', '=', $doctor_id];

        $inquiry_status_params = [1, 3, 4];// 问诊订单状态（1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消）
        $order_inquiry = OrderInquiry::getInquiryStatusOne($params, $inquiry_status_params);
        if (empty($order_inquiry)) {
            return [];
        }

        return $order_inquiry->toArray();
    }

    /**
     * 检测问诊订单执行退款次数
     * @param string $order_inquiry_id
     * @return bool
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function checkInquiryRefundCount(string $order_inquiry_id): bool
    {
        try {
            $redis = $this->container->get(Redis::class);

            $redis_key = "inquiryRefund" . $order_inquiry_id;
            $redis_value = $redis->get($redis_key);
            if(empty($redis_value)){
                $redis->set($redis_key, 1,60 * 60 * 24 * 5);
                return true;
            }

            // 问诊订单执行退款次数过多
            if ($redis_value > 3) {
                // 加入短信队列,通知管理员

                return false;
            }

            $redis->incr($redis_key);
        } catch (\Exception $e) {
            throw new BusinessException("检测问诊订单执行退款次数失败：" . $e->getMessage());
        }

        return true;
    }
}