<?php

declare(strict_types=1);

namespace App\Amqp\Consumer;

use App\Constants\HttpEnumCode;
use App\Exception\BusinessException;
use App\Model\LogSms;
use App\Utils\Log;
use Extend\Alibaba\Dysms;
use Hyperf\Amqp\Result;
use Hyperf\Amqp\Annotation\Consumer;
use Hyperf\Amqp\Message\ConsumerMessage;
use Hyperf\Redis\Redis;
use PhpAmqpLib\Message\AMQPMessage;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

/**
 * 短信推送
 */
#[Consumer(exchange: 'amqp.direct', routingKey: 'SendSmsMessage', queue: 'send.sms.message.queue', nums: 1)]
class SendSmsMessageConsumer extends ConsumerMessage
{
    /**
     * @param $data
     * @param AMQPMessage $message
     * @return string
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function consumeMessage($data, AMQPMessage $message): string
    {
        Log::getInstance()->error("开始执行 短信推送 队列：" . json_encode($data, JSON_UNESCAPED_UNICODE));

        if (!isset($data['template_code']) || !isset($data['template_param'])){
            Log::getInstance()->error("短信推送失败：发送参数错误");
            return Result::DROP;// 销毁
        }

        // 验证发送参数
        $res = $this->checkTemplateParam($data['template_code'],$data['template_param']);
        if (!$res){
            Log::getInstance()->error("短信推送失败：发送参数错误");
            return Result::DROP;// 销毁
        }

        $redis = $this->container->get(Redis::class);
        $redis_key = "sms_" . $data['phone'] . $data['template_code'];

        try {
            $result = $redis->get($redis_key);
            if (!empty($result)){
                if ( $result > 2){
                    // 超出规定时间内最大获取次数
                    Log::getInstance()->error("短信推送失败：超出最大发送重试次数");
                    return Result::DROP;// 销毁
                }
            }

            // 发送短信
            Dysms::sendSms($data['phone'],$data['template_param'],$data['template_code'],$data['scene_desc']);

            // 删除缓存
            if (!empty($result)){
                $redis->del($redis_key);
            }
        } catch (\Exception $e) {
            Log::getInstance()->error("短信推送失败：" . $e->getMessage());

            // 增加发送次数
            $redis->incr($redis_key);
            return Result::REQUEUE; // 重回队列
        }

        Log::getInstance()->info("短信推送成功");
        return Result::ACK;
    }

    /**
     * 验证短信发送参数
     * @param string $template_code
     * @param array $template_param
     * @return bool
     */
    private function checkTemplateParam(string $template_code, array $template_param): bool
    {
        switch ($template_code) {
            case 'SMS_271990126':
                // 医生修改简介审核通过
                break;
            case 'SMS_271540920':
                // 处方审核通过通知患者
                if (!isset($template_param['name'])) {
                    return false;
                }
            case 'SMS_271905266':
                // 医师还未接诊
                if (!isset($template_param['name']) || !isset($template_param['type'])) {
                    return false;
                }
                break;
            case 'SMS_272140100':
                // 药品收货-用药提醒
                if (!isset($template_param['name']) || !isset($template_param['usage']) || !isset($template_param['frequency']) || !isset($template_param['amount']) || !isset($template_param['tell'])) {
                    return false;
                }
                break;
            case 'SMS_271575911':
                // 多点执业认证通过
                break;
            case 'SMS_271955088':
                // 医生接诊通知给患者
                if (!isset($template_param['type']) || !isset($template_param['name']) || !isset($template_param['duration'])) {
                    return false;
                }
                break;
            case 'SMS_271905264':
                // 处方审核拒绝通过医师
                if (!isset($template_param['name'])) {
                    return false;
                }
                break;
            case 'SMS_271980127':
                // 药品已发货
                if (!isset($template_param['name']) || !isset($template_param['code'])) {
                    return false;
                }
                break;
            case 'SMS_272180110':
                // 患者问诊费退款
                if (!isset($template_param['type'])) {
                    return false;
                }
                break;
            case 'SMS_272145102':
                // 医生没有及时回消息
                if (!isset($template_param['name']) || !isset($template_param['type'])) {
                    return false;
                }
                break;
            case 'SMS_272120097':
                // 处方审核通过通知医生
                if (!isset($template_param['name'])) {
                    return false;
                }
                break;
            case 'SMS_272030021':
                // 多点执业认证拒绝
                break;
            case 'SMS_271925089':
                // 医师身份认证通过
                break;
            case 'SMS_271915200':
                // 医师服务费结算
                if (!isset($template_param['name']) || !isset($template_param['time'])) {
                    return false;
                }
                break;
            case 'SMS_272015117':
                // 医生接到新问诊
                if (!isset($template_param['type'])) {
                    return false;
                }
                break;
            case 'SMS_271955204':
                // 患者药品费用退款
                if (!isset($template_param['name']) || !isset($template_param['status'])) {
                    return false;
                }
                break;
            case 'SMS_271905155':
                // 医师身份认证拒绝
                break;
            case 'SMS_271950089':
                // 问诊即将结束通知患者
                if (!isset($template_param['name']) || !isset($template_param['type']) || !isset($template_param['time'])) {
                    return false;
                }
                break;
            case 'SMS_272165092':
                // 医生修改简介审核拒绝
                break;
            default:
                // 非法模版
                return false;
                break;
        }

        return true;
    }


}