package org.xyzh.message.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.xyzh.common.dto.message.TbSysMessage;
import org.xyzh.common.dto.message.TbSysMessageUser;
import org.xyzh.common.dto.user.TbSysUser;
import org.xyzh.common.utils.EmailUtils;
import org.xyzh.common.utils.SmsUtils;
import org.xyzh.message.mapper.MessageMapper;
import org.xyzh.message.mapper.MessageUserMapper;
import org.xyzh.system.mapper.UserMapper;

import java.util.Date;
import java.util.List;

/**
 * 消息发送服务
 *
 * @description 异步发送消息的服务类
 * @filename MessageSendService.java
 * @author Claude
 * @copyright xyzh
 * @since 2025-11-13
 */

@Service
public class MessageSendService {
    private static final Logger logger = LoggerFactory.getLogger(MessageSendService.class);

    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    private MessageUserMapper messageUserMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private EmailUtils emailUtils;

    @Autowired
    private SmsUtils smsUtils;

    /**
     * 异步发送消息
     *
     * @param messageID 消息ID
     */
    @Async("messageAsyncExecutor")
    @Transactional(rollbackFor = Exception.class)
    public void sendMessageAsync(String messageID) {
        try {
            logger.info("开始发送消息：{}", messageID);

            // 1. 查询消息
            TbSysMessage message = messageMapper.selectMessageById(messageID);

            if (message == null || message.getDeleted()) {
                logger.error("消息不存在：{}", messageID);
                return;
            }

            // 2. 查询所有待发送的用户消息
            TbSysMessageUser filter = new TbSysMessageUser();
            filter.setMessageID(messageID);
            filter.setSendStatus("pending");
            filter.setDeleted(false);
            List<TbSysMessageUser> userMessages = messageUserMapper.selectPendingUserMessages(filter);

            if (userMessages.isEmpty()) {
                logger.warn("没有待发送的用户消息：{}", messageID);
                updateMessageStatus(message, "sent");
                return;
            }

            // 3. 遍历发送
            int successCount = 0;
            int failedCount = 0;

            for (TbSysMessageUser userMessage : userMessages) {
                try {
                    // 查询用户信息
                    TbSysUser user = userMapper.selectUserById(userMessage.getUserID());
                    if (user == null || user.getDeleted()) {
                        logger.warn("用户不存在：{}", userMessage.getUserID());
                        updateUserMessageStatus(userMessage.getID(), "failed", "用户不存在");
                        failedCount++;
                        continue;
                    }

                    // 根据发送方式发送消息
                    String[] methods = userMessage.getSendMethod().split(",");
                    boolean sent = false;

                    for (String method : methods) {
                        method = method.trim();
                        try {
                            switch (method) {
                                case "system":
                                    // 系统消息已在数据库中，无需额外操作
                                    sent = true;
                                    break;

                                case "email":
                                    sent = sendEmail(user, message);
                                    break;

                                case "sms":
                                    sent = sendSms(user, message);
                                    break;

                                default:
                                    logger.warn("未知的发送方式：{}", method);
                            }

                            if (sent) {
                                break; // 任意一种方式成功即可
                            }

                        } catch (Exception e) {
                            logger.error("发送消息失败 [{}] - 用户：{}, 方式：{}", messageID, user.getUsername(), method, e);
                        }
                    }

                    // 更新用户消息发送状态
                    if (sent) {
                        updateUserMessageStatus(userMessage.getID(), "success", null);
                        successCount++;
                    } else {
                        updateUserMessageStatus(userMessage.getID(), "failed", "所有发送方式均失败");
                        failedCount++;
                    }

                } catch (Exception e) {
                    logger.error("处理用户消息失败：{}", userMessage.getID(), e);
                    updateUserMessageStatus(userMessage.getID(), "failed", e.getMessage());
                    failedCount++;
                }
            }

            // 4. 更新消息统计信息
            int sentCount = successCount + failedCount;
            messageMapper.updateStatistics(messageID, sentCount, successCount, failedCount);

            // 5. 更新消息状态
            if (failedCount == userMessages.size()) {
                // 全部失败
                updateMessageStatus(message, "failed");
            } else {
                // 至少有一个成功
                updateMessageStatus(message, "sent");
            }

            logger.info("消息发送完成：{} - 成功：{}, 失败：{}", messageID, successCount, failedCount);

        } catch (Exception e) {
            logger.error("发送消息异常：{}", messageID, e);
            // 更新消息状态为失败
            try {
                TbSysMessage message = messageMapper.selectMessageById(messageID);
                if (message != null && !message.getDeleted()) {
                    message.setStatus("failed");
                    message.setLastError(e.getMessage());
                    message.setUpdateTime(new Date());
                    messageMapper.updateMessage(message);
                }
            } catch (Exception ex) {
                logger.error("更新消息状态失败", ex);
            }
        }
    }

    /**
     * 发送邮件
     *
     * @param user 用户
     * @param message 消息
     * @return 是否成功
     */
    private boolean sendEmail(TbSysUser user, TbSysMessage message) {
        try {
            if (user.getEmail() == null || user.getEmail().trim().isEmpty()) {
                logger.warn("用户 {} 没有邮箱地址", user.getUsername());
                return false;
            }

            // 构建HTML邮件内容
            String htmlContent = buildEmailHtml(message);

            // 发送邮件
            boolean result = emailUtils.sendHtmlEmail(
                user.getEmail(),
                message.getTitle(),
                htmlContent
            );

            if (result) {
                logger.info("邮件发送成功 - 用户：{}, 邮箱：{}", user.getUsername(), user.getEmail());
            } else {
                logger.warn("邮件发送失败 - 用户：{}, 邮箱：{}", user.getUsername(), user.getEmail());
            }

            return result;

        } catch (Exception e) {
            logger.error("发送邮件异常 - 用户：{}", user.getUsername(), e);
            return false;
        }
    }

    /**
     * 发送短信
     *
     * @param user 用户
     * @param message 消息
     * @return 是否成功
     */
    private boolean sendSms(TbSysUser user, TbSysMessage message) {
        try {
            if (user.getPhone() == null || user.getPhone().trim().isEmpty()) {
                logger.warn("用户 {} 没有手机号", user.getUsername());
                return false;
            }

            // 短信内容（限制长度）
            String smsContent = message.getTitle();
            if (message.getContent() != null && message.getContent().length() < 50) {
                smsContent += "：" + message.getContent();
            }

            // 发送短信
            boolean result = smsUtils.sendSms(user.getPhone(), smsContent, "xx");

            if (result) {
                logger.info("短信发送成功 - 用户：{}, 手机：{}", user.getUsername(), user.getPhone());
            } else {
                logger.warn("短信发送失败 - 用户：{}, 手机：{}", user.getUsername(), user.getPhone());
            }

            return result;

        } catch (Exception e) {
            logger.error("发送短信异常 - 用户：{}", user.getUsername(), e);
            return false;
        }
    }

    /**
     * 构建邮件HTML内容
     */
    private String buildEmailHtml(TbSysMessage message) {
        StringBuilder html = new StringBuilder();
        html.append("<!DOCTYPE html>");
        html.append("<html>");
        html.append("<head>");
        html.append("<meta charset=\"UTF-8\">");
        html.append("<style>");
        html.append("body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }");
        html.append(".container { max-width: 600px; margin: 20px auto; padding: 20px; border: 1px solid #ddd; border-radius: 5px; }");
        html.append(".header { background-color: #c8232c; color: white; padding: 15px; border-radius: 5px 5px 0 0; }");
        html.append(".content { padding: 20px; background-color: #f9f9f9; }");
        html.append(".footer { text-align: center; padding: 15px; font-size: 12px; color: #999; }");
        html.append(".priority-urgent { border-left: 4px solid #ff0000; }");
        html.append(".priority-important { border-left: 4px solid #ff9900; }");
        html.append(".priority-normal { border-left: 4px solid #00aa00; }");
        html.append("</style>");
        html.append("</head>");
        html.append("<body>");
        html.append("<div class=\"container priority-").append(message.getPriority()).append("\">");
        html.append("<div class=\"header\">");
        html.append("<h2>").append(message.getTitle()).append("</h2>");
        html.append("</div>");
        html.append("<div class=\"content\">");
        html.append(message.getContent());
        html.append("</div>");
        html.append("<div class=\"footer\">");
        html.append("<p>发送人：").append(message.getSenderName()).append(" (").append(message.getSenderDeptName()).append(")</p>");
        html.append("<p>发送时间：").append(message.getActualSendTime() != null ? message.getActualSendTime().toString() : "").append("</p>");
        html.append("<p>此邮件由系统自动发送，请勿回复。</p>");
        html.append("</div>");
        html.append("</div>");
        html.append("</body>");
        html.append("</html>");
        return html.toString();
    }

    /**
     * 更新消息状态
     */
    private void updateMessageStatus(TbSysMessage message, String status) {
        try {
            message.setStatus(status);
            if ("sent".equals(status)) {
                message.setActualSendTime(new Date());
            }
            message.setUpdateTime(new Date());
            messageMapper.updateMessage(message);
        } catch (Exception e) {
            logger.error("更新消息状态失败", e);
        }
    }

    /**
     * 更新用户消息发送状态
     */
    private void updateUserMessageStatus(String id, String status, String failReason) {
        try {
            messageUserMapper.updateSendStatus(id, status, failReason);
        } catch (Exception e) {
            logger.error("更新用户消息状态失败", e);
        }
    }
}
