package com.sikey.wa04.api.websocket.client.handler;

import cn.hutool.json.JSONUtil;
import com.sikey.wa04.business.application.service.message.MessagingSubscribeService;
import com.sikey.wa04.business.domain.adapter.MessageAdapter;
import com.sikey.wa04.business.domain.entity.message.Message;
import com.sikey.wa04.business.domain.entity.message.MessageId;
import com.sikey.wa04.business.domain.entity.message.MessageReceivedLog;
import com.sikey.wa04.business.infrastructure.aop.Tracer;
import com.sikey.wa04.common.dto.message.*;
import com.sikey.wa04.common.enums.MessageStatus;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 * 收到 MQ 消息
 *
 * @author luoyangwei
 * @date 2024年10月12日17:07:41
 */
@Slf4j
@Component
@RabbitListener(queues = "publish_queue")
public class MessageQueueHandler {

    @Resource
    private MessagingSubscribeService messagingSubscribeService;

    @Resource
    private MessageAdapter messageAdapter;

    /**
     * 接收聊天文本消息
     *
     * @param chatTextMessage 聊天文本消息
     * @param headers         消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveChatTextMessage(@Payload ChatTextMessage chatTextMessage, @Headers Map<String, Object> headers) {
        log.info("Received chat text message: {}, {}", JSONUtil.toJsonPrettyStr(chatTextMessage), headers);
        Message message = convertMessage(chatTextMessage);
        // 是否群聊
        message.setGroup(chatTextMessage.getIsGroup());
        // 群组id
        message.setGroupId(chatTextMessage.getGroupId());
       // log.info("Received chat text message，群组id：{}, message：{}", chatTextMessage.getGroupId(), chatTextMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收聊天视频消息
     *
     * @param chatVideoMessage 聊天视频消息
     * @param headers          消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveChatVideoMessage(@Payload ChatVideoMessage chatVideoMessage, @Headers Map<String, Object> headers) {
        log.info("Received chat video message: {}, {}", JSONUtil.toJsonPrettyStr(chatVideoMessage), headers);
        Message message = convertMessage(chatVideoMessage);
        // 是否群聊
        message.setGroup(chatVideoMessage.getIsGroup());
        // 群组id
        message.setGroupId(chatVideoMessage.getGroupId());
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收聊天语音消息
     *
     * @param chatVoiceMessage 聊天语音消息
     * @param headers          消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveChatVoiceMessage(@Payload ChatVoiceMessage chatVoiceMessage, @Headers Map<String, Object> headers) {
        log.info("Received chat voice message: {}, {}", JSONUtil.toJsonPrettyStr(chatVoiceMessage), headers);
        Message message = convertMessage(chatVoiceMessage);
        // 是否群聊
        message.setGroup(chatVoiceMessage.getIsGroup());
        // 群组id
        message.setGroupId(chatVoiceMessage.getGroupId());
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收聊天图片消息
     *
     * @param chatImageMessage 聊天图片消息
     * @param headers          消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveChatImageMessage(@Payload ChatImageMessage chatImageMessage, @Headers Map<String, Object> headers) {
        log.info("Received chat image message: {}, {}", JSONUtil.toJsonPrettyStr(chatImageMessage), headers);
        Message message = convertMessage(chatImageMessage);
        // 是否群聊
        message.setGroup(chatImageMessage.getIsGroup());
        // 群组id
        message.setGroupId(chatImageMessage.getGroupId());
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收聊天表情消息
     *
     * @param chatEmojiMessage 聊天表情消息
     * @param headers          消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveChatEmojiMessage(@Payload ChatEmojiMessage chatEmojiMessage, @Headers Map<String, Object> headers) {
        log.info("Received chat emoji message: {}, {}", JSONUtil.toJsonPrettyStr(chatEmojiMessage), headers);
        Message message = convertMessage(chatEmojiMessage);
        // 是否群聊
        message.setGroup(chatEmojiMessage.getIsGroup());
        // 群组id
        message.setGroupId(chatEmojiMessage.getGroupId());
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收视频通话呼入消息
     *
     * @param videoCallInNoticeMessage 视频通话呼入消息
     * @param headers                  消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveVideoCallInMessage(@Payload VideoCallInNoticeMessage videoCallInNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received video call in message: {}, {}", JSONUtil.toJsonPrettyStr(videoCallInNoticeMessage), headers);
        Message message = convertMessage(videoCallInNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收视频通话呼出消息
     *
     * @param videoCallOutNoticeMessage 视频通话呼出消息
     * @param headers                   消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveVideoCallOutMessage(@Payload VideoCallOutNoticeMessage videoCallOutNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received video call out message: {}, {}", JSONUtil.toJsonPrettyStr(videoCallOutNoticeMessage), headers);
        Message message = convertMessage(videoCallOutNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收询问设备位置通知消息
     *
     * @param askLocationPointNoticeMessage 询问设备位置通知消息
     * @param headers                       消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveAskLocationPointMessage(@Payload AskLocationPointNoticeMessage askLocationPointNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received ask location point message: {}, {}", JSONUtil.toJsonPrettyStr(askLocationPointNoticeMessage), headers);
        Message message = convertMessage(askLocationPointNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收位置点变更通知消息
     *
     * @param locationPointChangeNoticeMessage 位置点变更通知消息
     * @param headers                          消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveLocationPointChangeNoticeMessage(@Payload LocationPointChangeNoticeMessage locationPointChangeNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received location point change notice message: {}, {}", JSONUtil.toJsonPrettyStr(locationPointChangeNoticeMessage), headers);
        Message message = convertMessage(locationPointChangeNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收添加好友通知消息
     *
     * @param addFriendNoticeMessage 添加好友通知消息
     * @param headers                消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveAddFriendNoticeMessage(@Payload AddFriendNoticeMessage addFriendNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received add friend notice message: {}, {}", JSONUtil.toJsonPrettyStr(addFriendNoticeMessage), headers);
        Message message = convertMessage(addFriendNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收闹钟变更通知消息
     *
     * @param alarmClockChangeNoticeMessage 闹钟变更通知消息
     * @param headers                       消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveAlarmNoticeMessage(@Payload AlarmClockChangeNoticeMessage alarmClockChangeNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received alarm notice message: {}, {}", JSONUtil.toJsonPrettyStr(alarmClockChangeNoticeMessage), headers);
        Message message = convertMessage(alarmClockChangeNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收联系人变更通知消息
     *
     * @param contactChangeNoticeMessage 联系人变更通知消息
     * @param headers                    消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveContactChangeNotice(@Payload ContactChangeNoticeMessage contactChangeNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received contact change notice message: {}, {}", JSONUtil.toJsonPrettyStr(contactChangeNoticeMessage), headers);
        Message message = convertMessage(contactChangeNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收设备绑定状态变动通知消息
     *
     * @param deviceBindStateChangeNoticeMessage 设备绑定状态变动通知消息
     * @param headers                            消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveDeviceBindNoticeMessage(@Payload DeviceBindStateChangeNoticeMessage deviceBindStateChangeNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received device bind notice message: {}, {}", JSONUtil.toJsonPrettyStr(deviceBindStateChangeNoticeMessage), headers);
        Message message = convertMessage(deviceBindStateChangeNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收消息中心变动通知消息
     *
     * @param messageCenterChangeNoticeMessage 消息中心变动通知消息
     * @param headers                          消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveMessageCenterChangeNoticeMessage(@Payload MessageCenterChangeNoticeMessage messageCenterChangeNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received message center change notice message: {}, {}", JSONUtil.toJsonPrettyStr(messageCenterChangeNoticeMessage), headers);
        Message message = convertMessage(messageCenterChangeNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收拒接陌生人变动通知消息
     *
     * @param rejectStrangerChangeNoticeMessage 拒接陌生人变动通知消息
     * @param headers                           消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveRejectStrangerChangeNoticeMessage(@Payload RejectStrangerChangeNoticeMessage rejectStrangerChangeNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received reject stranger change notice message: {}, {}", JSONUtil.toJsonPrettyStr(rejectStrangerChangeNoticeMessage), headers);
        Message message = convertMessage(rejectStrangerChangeNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收上课禁用变更通知消息
     *
     * @param schoolDisableChangeNoticeMessage 上课禁用变更通知消息
     * @param headers                          消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveSchoolDisableChangeNoticeMessage(@Payload SchoolDisableChangeNoticeMessage schoolDisableChangeNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received school disable change notice message: {}, {}", JSONUtil.toJsonPrettyStr(schoolDisableChangeNoticeMessage), headers);
        Message message = convertMessage(schoolDisableChangeNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }


    /**
     * 接收手表关机通知消息
     *
     * @param wristwatchShutdownNoticeMessage 手表关机通知消息
     * @param headers                         消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveWristwatchShutdownNoticeMessage(@Payload WristwatchShutdownNoticeMessage wristwatchShutdownNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received wristwatch shutdown notice message: {}, {}", JSONUtil.toJsonPrettyStr(wristwatchShutdownNoticeMessage), headers);
        Message message = convertMessage(wristwatchShutdownNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收手表开机通知消息
     *
     * @param wristwatchStartupNoticeMessage 手表开机通知消息
     * @param headers                        消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveWristwatchStartupNoticeMessage(@Payload WristwatchStartupNoticeMessage wristwatchStartupNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received wristwatch startup notice message: {}, {}", JSONUtil.toJsonPrettyStr(wristwatchStartupNoticeMessage), headers);
        Message message = convertMessage(wristwatchStartupNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收远程控制重启通知消息
     *
     * @param remoteControlRebootNoticeMessage 远程控制重启通知消息
     * @param headers                          消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveRemoteControlRebootNoticeMessage(@Payload RemoteControlRebootNoticeMessage remoteControlRebootNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received remote control reboot notice message: {}, {}", JSONUtil.toJsonPrettyStr(remoteControlRebootNoticeMessage), headers);
        Message message = convertMessage(remoteControlRebootNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收远程控制关机通知消息
     *
     * @param remoteControlShutdownNoticeMessage 远程控制关机通知消息
     * @param headers                            消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveRemoteControlShutdownNoticeMessage(@Payload RemoteControlShutdownNoticeMessage remoteControlShutdownNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received remote control shutdown notice message: {}, {}", JSONUtil.toJsonPrettyStr(remoteControlShutdownNoticeMessage), headers);
        Message message = convertMessage(remoteControlShutdownNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收远程控制恢复出厂设置通知消息
     *
     * @param noticeMessage     远程控制恢复出厂设置通知消息
     * @param headers           消息头
     */
    @Tracer
    @RabbitHandler
    public void receiveRemoteControlRestoreFactorySettingsNoticeMessage(@Payload RemoteControlRestoreFactorySettingsNoticeMessage noticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received remote control restore factory settings notice message: {}, {}", JSONUtil.toJsonPrettyStr(noticeMessage), headers);
        Message message = convertMessage(noticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收设置应用管理应用开关的通知消息
     *
     * @param appManageAppSwitchNoticeMessage 远程控制关机通知消息
     * @param headers                            消息头
     */
    @Tracer
    @RabbitHandler
    public void appManageAppSwitchNoticeMessage(@Payload AppManageAppSwitchNoticeMessage appManageAppSwitchNoticeMessage, @Headers Map<String, Object> headers) {
        log.info("Received app manage app switch notice message: {}, {}", JSONUtil.toJsonPrettyStr(appManageAppSwitchNoticeMessage), headers);
        Message message = convertMessage(appManageAppSwitchNoticeMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收离开安全围栏告警通知APP消息
     *
     * @param reqMessage    离开安全围栏告警通知APP消息
     * @param headers       消息头
     */
    @Tracer
    @RabbitHandler
    public void locationExitSafetyFenceNoticeAppMessage(@Payload LocationExitSafetyFenceNoticeAppMessage reqMessage, @Headers Map<String, Object> headers) {
        log.info("Received location exit safety fence notice app message: {}, {}", JSONUtil.toJsonPrettyStr(reqMessage), headers);
        Message message = convertMessage(reqMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 接收进入危险围栏告警通知APP消息
     *
     * @param reqMessage    进入危险围栏告警通知APP消息
     * @param headers       消息头
     */
    @Tracer
    @RabbitHandler
    public void locationEnterDangerFenceNoticeAppMessage(@Payload LocationEnterDangerFenceNoticeAppMessage reqMessage, @Headers Map<String, Object> headers) {
        log.info("Received location enter danger fence notice app message: {}, {}", JSONUtil.toJsonPrettyStr(reqMessage), headers);
        Message message = convertMessage(reqMessage);
        messagingSubscribeService.consumeMessage(message);
    }

    /**
     * 转换消息
     *
     * @param basicMessage 基础消息
     * @return 消息
     */
    private Message convertMessage(BasicMessage basicMessage) {
        MessageId messageId = new MessageId(basicMessage.getMsgId());
        Message message = messageAdapter.find(messageId);
        message.setReceiverId(List.of(basicMessage.getRecvId()));
        message.setReceivedLogs(
                List.of(new MessageReceivedLog().setReceiverId(basicMessage.getRecvId()).setStatus(MessageStatus.DEFAULT)));
        return message;
    }
}
