package com.qqchen.deploy.backend.notification.service.impl;

import com.qqchen.deploy.backend.framework.enums.ResponseCode;
import com.qqchen.deploy.backend.framework.exception.BusinessException;
import com.qqchen.deploy.backend.framework.utils.JsonUtils;
import com.qqchen.deploy.backend.notification.dto.BaseSendNotificationRequest;
import com.qqchen.deploy.backend.notification.dto.EmailSendNotificationRequest;
import com.qqchen.deploy.backend.notification.dto.SendNotificationRequest;
import com.qqchen.deploy.backend.notification.dto.WeworkSendNotificationRequest;
import com.qqchen.deploy.backend.notification.entity.NotificationChannel;
import com.qqchen.deploy.backend.notification.entity.NotificationTemplate;
import com.qqchen.deploy.backend.notification.entity.config.BaseTemplateConfig;
import com.qqchen.deploy.backend.notification.entity.config.EmailTemplateConfig;
import com.qqchen.deploy.backend.notification.entity.config.WeworkTemplateConfig;
import com.qqchen.deploy.backend.notification.enums.EmailContentTypeEnum;
import com.qqchen.deploy.backend.notification.enums.WeworkMessageTypeEnum;
import com.qqchen.deploy.backend.notification.repository.INotificationChannelRepository;
import com.qqchen.deploy.backend.notification.repository.INotificationTemplateRepository;
import com.qqchen.deploy.backend.notification.service.INotificationSendService;
import com.qqchen.deploy.backend.notification.service.INotificationService;
import com.qqchen.deploy.backend.notification.service.INotificationTemplateService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

/**
 * 通知服务实现类
 *
 * @author qqchen
 * @since 2025-11-12
 */
@Slf4j
@Service
public class NotificationServiceImpl implements INotificationService {

    @Resource
    private INotificationTemplateService notificationTemplateService;

    @Resource
    private INotificationSendService notificationSendService;

    @Resource
    private INotificationChannelRepository notificationChannelRepository;

    @Resource
    private INotificationTemplateRepository notificationTemplateRepository;

    @Override
    public void send(SendNotificationRequest request) {
        // 1. 获取通知渠道
        NotificationChannel channel = notificationChannelRepository.findById(request.getChannelId())
            .orElseThrow(() -> new BusinessException(ResponseCode.NOTIFICATION_CHANNEL_NOT_FOUND));

        // 2. 获取通知模板
        NotificationTemplate template = notificationTemplateRepository.findById(request.getNotificationTemplateId())
            .orElseThrow(() -> new BusinessException(ResponseCode.NOTIFICATION_TEMPLATE_NOT_FOUND));

        // 3. 验证模板和渠道类型是否匹配
        if (!template.getChannelType().equals(channel.getChannelType())) {
            throw new BusinessException(ResponseCode.INVALID_PARAM);
        }

        // 4. 验证模板和渠道是否启用
        if (!template.getEnabled()) {
            throw new BusinessException(ResponseCode.NOTIFICATION_TEMPLATE_DISABLED);
        }
        if (!channel.getEnabled()) {
            throw new BusinessException(ResponseCode.NOTIFICATION_CHANNEL_DISABLED);
        }

        // 5. 根据渠道类型自动创建对应的发送请求对象
        BaseSendNotificationRequest sendRequest = createSendRequestByChannel(channel, template);

        // 6. 渲染模板内容
        String content = notificationTemplateService.renderTemplate(template.getContentTemplate(), request.getTemplateParams());

        // 7. 渲染标题（如果有）
        String title = notificationTemplateService.renderTitleById(request.getNotificationTemplateId(), request.getTemplateParams());

        // 8. 设置渲染后的内容和标题
        sendRequest.setContent(content);
        sendRequest.setTitle(title);

        // 9. 发送通知
        notificationSendService.send(channel, sendRequest);
    }

    /**
     * 根据渠道类型自动创建对应的发送请求对象
     * 业务方无需关心此逻辑，由通知服务内部处理
     */
    private BaseSendNotificationRequest createSendRequestByChannel(
        NotificationChannel channel, 
        NotificationTemplate template) {
        
        switch (channel.getChannelType()) {
            case WEWORK -> {
                WeworkSendNotificationRequest request = new WeworkSendNotificationRequest();
                // 从模板配置中获取消息类型
                request.setMessageType(getWeworkMessageType(template));
                return request;
            }
            case EMAIL -> {
                EmailSendNotificationRequest request = new EmailSendNotificationRequest();
                // 从模板配置中获取收件人（如果有的话）
                request.setToReceivers(getEmailReceivers(template));
                return request;
            }
            default -> throw new BusinessException(ResponseCode.ERROR, 
                new Object[]{"不支持的渠道类型: " + channel.getChannelType()});
        }
    }

    /**
     * 从模板配置中获取企业微信消息类型
     */
    private WeworkMessageTypeEnum getWeworkMessageType(NotificationTemplate template) {
        try {
            if (template.getTemplateConfig() != null) {
                WeworkTemplateConfig config = JsonUtils.fromMap(
                    template.getTemplateConfig(), WeworkTemplateConfig.class);
                if (config != null && config.getMessageType() != null) {
                    return config.getMessageType();
                }
            }
        } catch (Exception e) {
            log.warn("解析企业微信模板配置失败，使用默认消息类型: {}", e.getMessage());
        }
        // 默认使用TEXT类型
        return WeworkMessageTypeEnum.TEXT;
    }

    /**
     * 从模板配置中获取邮件收件人
     */
    private List<String> getEmailReceivers(NotificationTemplate template) {
        // 邮件收件人由调用方在 templateParams 中指定，或者在渠道配置中配置
        // 这里返回默认收件人，实际使用时由具体业务场景传递
        return java.util.Arrays.asList("admin@company.com");
    }

}
