<?php

declare(strict_types=1);

namespace App\Amqp\Consumer;

use App\Model\LogMessagePush;
use App\Model\MessageNotice;
use App\Model\OrderInquiry;
use App\Model\User;
use App\Services\ImService;
use App\Utils\Log;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Amqp\Result;
use Hyperf\Amqp\Annotation\Consumer;
use Hyperf\Amqp\Message\ConsumerMessage;
use PhpAmqpLib\Message\AMQPMessage;

/**
 * 站内消息推送
 */
#[Consumer(exchange: 'amqp.direct', routingKey: 'SendStationMessage', queue: 'send.station.message.queue',nums: 1)]
class SendStationMessageConsumer extends ConsumerMessage
{
    /**
     * @param $data
     * @param AMQPMessage $message
     * @return string
     * @throws GuzzleException
     */
    public function consumeMessage($data, AMQPMessage $message): string
    {
        Log::getInstance()->info("开始执行 站内消息推送 队列：" . json_encode($data, JSON_UNESCAPED_UNICODE));

        // 验证推送参数
        $res = $this->checkPushParams($data);
        if (!$res){
            Log::getInstance()->error("站内消息推送失败：入参错误");
            return Result::DROP;
        }

        // 验证用户信息
        $params = array();
        $params['user_id'] = $data['user_id'];
        $user = User::getOne($params);
        if(empty($user)){
            Log::getInstance()->error("站内消息推送失败：推送用户信息错误");
            return Result::DROP;
        }

        if ($data['notice_type'] == 1){
            // 医生服务通知
            $message_type = 3;
        }elseif ($data['notice_type'] == 2){
            // 医生系统公告
            $message_type = 4;
        }elseif ($data['notice_type'] == 3){
            // 患者系统消息
            $message_type = 5;
        }else{
            Log::getInstance()->error("站内消息推送失败：消息类型错误");
            $this->saveErrorPushLog($user['user_type'],$data,"消息类型错误");
            return Result::DROP;
        }

        try {
            // 发送消息
            $ImService = new ImService();

            // 自定义消息
            $cloud_custom_data = array();
            $cloud_custom_data['order_inquiry_id'] = "";
            $cloud_custom_data['is_system'] = 1;
            $cloud_custom_data['inquiry_type'] = "";
            $cloud_custom_data['message_rounds'] = 0;
            $cloud_custom_data['patient_family_data'] = [];

            // 消息内容
            $message_content_data = array();
            $message_content_data['message_type'] = $message_type;
            $message_content_data['content'] = $data['notice_brief_type'] ?: "消息推送";
            $message_content_data['desc'] = $data['notice_content'] ?? "";
            $message_content = [
                'Data' => json_encode($message_content_data,JSON_UNESCAPED_UNICODE),
            ];

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

            // 新增成功通知消息表
            $this->saveMessageNotice($user->toArray(),$data);

            Log::getInstance()->info("站内消息推送成功");
            $this->saveSuccessPushLog($user['user_type'],$data);

        } catch (\Exception $e) {
            Log::getInstance()->error("站内消息推送执行失败：" . $e->getMessage());

            $this->saveErrorPushLog($user['user_type'],$data,$e->getMessage());

            // 新增失败通知消息表
            $this->saveMessageNotice($user->toArray(),$data,0,$e->getMessage());
        }

        return Result::ACK;
    }

    /**
     * 验证推送参数
     * @param $push_data
     * @return bool
     */
    private function checkPushParams($push_data): bool
    {
        // 用户id（接受者）
        if (!isset($push_data['user_id'])){
            return false;
        }

        // 消息类型（1:医生服务通知 2:医生系统公告 3:患者系统消息）
        if (!isset($push_data['notice_type'])){
            return false;
        }


        // 患者系统消息存在
        if ($push_data['notice_type'] == 3){
            // 系统消息类型（患者端系统消息存在 1:服务消息 2:福利消息 3:退款消息 4:物流消息）
            if (!isset($push_data['notice_system_type'])){
                return false;
            }
        }

        // 医生服务通知存在
        if ($push_data['notice_type'] == 1){
            // 问诊类型（医生端服务通知存在 1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药）
            if (!isset($push_data['notice_system_type'])){
                return false;
            }
        }

        // 消息标题
        if (!isset($push_data['notice_title']) && !isset($push_data['notice_brief_type'])){
            return false;
        }

        return true;
    }

    /**
     * 记录成功日志
     * @param string|int $user_type 用户类型
     * @param array $push_data 需发送的站内消息数据
     * @return void
     */
    private function saveSuccessPushLog(string|int $user_type,array $push_data): void
    {
        $data = array();
        $data['to_user_id'] = $push_data['user_id'];
        $data['user_type'] = $user_type;
        $data['type'] = 1;
        $data['status'] = 1;
        $data['content'] = json_encode($push_data,JSON_UNESCAPED_UNICODE);
        $log_message_push = LogMessagePush::addLogMessagePush($data);
        if (empty($log_message_push)){
            Log::getInstance()->error("站内消息推送成功，增加推送日志失败：" . json_encode($data,JSON_UNESCAPED_UNICODE));
        }
    }

    /**
     * 记录成功日志
     * @param string|int $user_type 用户类型
     * @param array $push_data 需发送的站内消息数据
     * @param string $fail_reason 失败原因
     * @return void
     */
    private function saveErrorPushLog(string|int $user_type,array $push_data,string $fail_reason): void
    {
        $data = array();
        $data['to_user_id'] = $push_data['user_id'];
        $data['user_type'] = $user_type;
        $data['type'] = 1;
        $data['status'] = 2;
        $data['fail_reason'] = $fail_reason ?: "";
        $data['content'] = json_encode($push_data,JSON_UNESCAPED_UNICODE);
        $log_message_push = LogMessagePush::addLogMessagePush($data);
        if (empty($log_message_push)){
            Log::getInstance()->error("站内消息推送成功，增加推送日志失败：" . json_encode($data,JSON_UNESCAPED_UNICODE));
        }
    }

    /**
     * 新增通知消息表
     * @param array $user
     * @param array $push_data
     * @param string $send_fail_reason
     * @param int $send_status
     * @return void
     */
    private function saveMessageNotice(array $user,array $push_data,int $send_status = 1,string $send_fail_reason = ""): void
    {

        $notice_data = array();
        $notice_data['user_id'] = $user['user_id'];
        $notice_data['user_type'] = $user['user_type'];
        $notice_data['notice_type'] = $push_data['notice_type'];
        if (isset($push_data['notice_system_type'])){
            $notice_data['notice_system_type'] = $push_data['notice_system_type'] ;
        }

        $notice_data['read_status'] = 0;

        if (isset($push_data['from_name'])){
            $notice_data['from_name'] = $push_data['from_name'] ;
        }

        $notice_data['notice_send_time'] = date('Y-m-d H:i:s',time());

        if (isset($push_data['notice_title'])){
            $notice_data['notice_title'] = $push_data['notice_title'] ;
        }

        if (isset($push_data['notice_brief_type'])){
            $notice_data['notice_brief_type'] = $push_data['notice_brief_type'] ;
        }

        if (isset($push_data['notice_content'])){
            $notice_data['notice_content'] = $push_data['notice_content'] ;
        }

        $notice_data['send_status'] = $send_status;
        $notice_data['send_fail_reason'] = $send_fail_reason;
        if (isset($push_data['button_type'])){
            $notice_data['button_type'] = $push_data['button_type'] ;
        }

        if (isset($push_data['link_type'])){
            $notice_data['link_type'] = $push_data['link_type'] ;
        }

        if (isset($push_data['link_params'])){
            $notice_data['link_params'] = $push_data['link_params'] ;
        }

        if (isset($push_data['show_type'])){
            $notice_data['show_type'] = $push_data['show_type'];
        }

        if (isset($push_data['show_params'])){
            $notice_data['show_params'] = $push_data['show_params'];
        }

        $message_notice = MessageNotice::addMessageNotice($notice_data);
        if (empty($message_notice)){
            Log::getInstance()->error("站内消息推送成功，记录通知消息表失败：" . json_encode($notice_data,JSON_UNESCAPED_UNICODE));
        }
    }
}
