package com.aegis.notification.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.aegis.common.exception.ServiceException;
import com.aegis.common.utils.SecurityUtils;
import com.aegis.common.utils.StringUtils;
import com.aegis.framework.manager.AsyncManager;
import com.aegis.notification.domain.Notification;
import com.aegis.notification.domain.NotificationTemplate;
import com.aegis.notification.manager.factory.AsyncNotificationFactory;
import com.aegis.notification.mapper.NotificationMapper;
import com.aegis.notification.mapper.NotificationTemplateMapper;
import com.aegis.notification.service.INotificationService;
import com.aegis.notification.service.channel.INotificationChannel;
import com.aegis.common.core.domain.entity.SysUser;
import com.aegis.system.service.ISysUserService;

/**
 * 通知服务实现类
 * 
 * @author aegis
 */
@Service
public class NotificationServiceImpl implements INotificationService {
    
    @Autowired
    private NotificationMapper notificationMapper;
    
    @Autowired
    private NotificationTemplateMapper templateMapper;
    
    @Autowired
    private List<INotificationChannel> channels; // Spring自动注入所有渠道实现
    
    @Autowired
    private ISysUserService userService;
    
    /**
     * 发送通知（单个接收者）
     */
    @Override
    @Transactional
    public Long sendNotification(Long receiverId, String title, String content, 
                                String channel, String businessType, Long businessId) {
        // 获取接收者信息
        SysUser receiver = userService.selectUserById(receiverId);
        if (receiver == null) {
            throw new ServiceException("接收者用户不存在");
        }
        
        // 创建通知对象
        Notification notification = new Notification();
        notification.setReceiverId(receiverId);
        notification.setReceiverName(receiver.getUserName());
        notification.setTitle(title);
        notification.setContent(content);
        notification.setChannel(StringUtils.isEmpty(channel) ? "station" : channel);
        notification.setBusinessType(businessType);
        notification.setBusinessId(businessId);
        notification.setStatus("pending");
        notification.setPriority("normal");
        notification.setDelFlag("0");
        
        // 设置发送者信息（如果有登录用户）
        try {
            String username = SecurityUtils.getUsername();
            SysUser sender = userService.selectUserByUserName(username);
            if (sender != null) {
                notification.setSenderId(sender.getUserId());
                notification.setSenderName(sender.getUserName());
            }
        } catch (Exception e) {
            // 系统通知，没有发送者
        }
        
        notification.setCreateBy(SecurityUtils.getUsername());
        
        // 先保存通知记录（状态为pending）
        notificationMapper.insertNotification(notification);
        
        // 异步发送通知
        AsyncManager.me().execute(AsyncNotificationFactory.sendNotification(notification, channels));
        
        return notification.getId();
    }
    
    /**
     * 发送通知（批量接收者）
     */
    @Override
    @Transactional
    public List<Long> sendBatchNotification(List<Long> receiverIds, String title, 
                                             String content, String channel, 
                                             String businessType, Long businessId) {
        List<Long> notificationIds = new ArrayList<>();
        for (Long receiverId : receiverIds) {
            Long notificationId = sendNotification(receiverId, title, content, 
                                                   channel, businessType, businessId);
            notificationIds.add(notificationId);
        }
        return notificationIds;
    }
    
    /**
     * 使用模板发送通知
     */
    @Override
    @Transactional
    public Long sendNotificationByTemplate(Long receiverId, String templateCode, 
                                          Map<String, Object> variables, 
                                          String channel, String businessType, Long businessId) {
        // 查询模板
        NotificationTemplate template = templateMapper.selectNotificationTemplateByCode(templateCode);
        if (template == null) {
            throw new ServiceException("通知模板不存在：" + templateCode);
        }
        
        if (!"0".equals(template.getStatus())) {
            throw new ServiceException("通知模板已停用：" + templateCode);
        }
        
        // 使用模板和变量生成标题和内容
        String title = replaceVariables(template.getTitleTemplate(), variables);
        String content = replaceVariables(template.getContentTemplate(), variables);
        
        // 使用模板配置的渠道（如果未指定）
        String finalChannel = StringUtils.isEmpty(channel) ? template.getChannel() : channel;
        
        // 发送通知
        Notification notification = new Notification();
        notification.setReceiverId(receiverId);
        notification.setTemplateId(template.getId());
        notification.setTitle(title);
        notification.setContent(content);
        notification.setChannel(finalChannel);
        notification.setBusinessType(StringUtils.isEmpty(businessType) ? template.getBusinessType() : businessType);
        notification.setBusinessId(businessId);
        notification.setStatus("pending");
        notification.setPriority("normal");
        notification.setDelFlag("0");
        
        // 获取接收者信息
        SysUser receiver = userService.selectUserById(receiverId);
        if (receiver != null) {
            notification.setReceiverName(receiver.getUserName());
        }
        
        // 设置发送者信息（如果有登录用户）
        try {
            String username = SecurityUtils.getUsername();
            SysUser sender = userService.selectUserByUserName(username);
            if (sender != null) {
                notification.setSenderId(sender.getUserId());
                notification.setSenderName(sender.getUserName());
            }
        } catch (Exception e) {
            // 系统通知，没有发送者
        }
        
        notification.setCreateBy(SecurityUtils.getUsername());
        
        // 先保存通知记录（状态为pending）
        notificationMapper.insertNotification(notification);
        
        // 异步发送通知
        AsyncManager.me().execute(AsyncNotificationFactory.sendNotification(notification, channels));
        
        return notification.getId();
    }
    
    /**
     * 替换模板变量
     */
    private String replaceVariables(String template, Map<String, Object> variables) {
        if (template == null) {
            return "";
        }
        String result = template;
        if (variables != null) {
            for (Map.Entry<String, Object> entry : variables.entrySet()) {
                String key = "${" + entry.getKey() + "}";
                String value = entry.getValue() != null ? String.valueOf(entry.getValue()) : "";
                result = result.replace(key, value);
            }
        }
        return result;
    }
    
    /**
     * 查询用户通知列表
     */
    @Override
    public List<Notification> selectNotificationList(Long receiverId, String status, String channel) {
        Notification notification = new Notification();
        notification.setReceiverId(receiverId);
        if (StringUtils.isNotEmpty(status)) {
            notification.setStatus(status);
        }
        if (StringUtils.isNotEmpty(channel)) {
            notification.setChannel(channel);
        }
        return notificationMapper.selectNotificationList(notification);
    }
    
    /**
     * 根据ID查询通知详情
     */
    @Override
    public Notification selectNotificationById(Long notificationId, Long receiverId) {
        Notification notification = notificationMapper.selectNotificationById(notificationId);
        if (notification == null) {
            throw new ServiceException("通知不存在");
        }
        // 权限校验：只能查看自己的通知
        if (!notification.getReceiverId().equals(receiverId)) {
            throw new ServiceException("无权访问该通知");
        }
        return notification;
    }
    
    /**
     * 查询未读通知数量
     */
    @Override
    public int countUnreadNotifications(Long receiverId) {
        return notificationMapper.countUnreadNotifications(receiverId);
    }
    
    /**
     * 标记通知为已读
     */
    @Override
    @Transactional
    public int markAsRead(Long notificationId, Long receiverId) {
        // 验证通知是否存在且属于该接收者
        Notification notification = notificationMapper.selectNotificationById(notificationId);
        if (notification == null) {
            throw new ServiceException("通知不存在");
        }
        if (!notification.getReceiverId().equals(receiverId)) {
            throw new ServiceException("无权操作该通知");
        }
        
        // 只有已发送状态的通知才能标记为已读
        if (!"sent".equals(notification.getStatus())) {
            throw new ServiceException("只能标记已发送的通知为已读");
        }
        
        notification.setStatus("read");
        notification.setReadTime(new Date());
        notification.setUpdateBy(SecurityUtils.getUsername());
        return notificationMapper.updateNotification(notification);
    }
    
    /**
     * 批量标记为已读
     */
    @Override
    @Transactional
    public int markBatchAsRead(Long[] notificationIds, Long receiverId) {
        // 验证所有通知都属于该接收者
        for (Long notificationId : notificationIds) {
            Notification notification = notificationMapper.selectNotificationById(notificationId);
            if (notification == null || !notification.getReceiverId().equals(receiverId)) {
                throw new ServiceException("通知ID=" + notificationId + "不存在或无权操作");
            }
        }
        
        return notificationMapper.markBatchAsRead(notificationIds, receiverId);
    }
    
    /**
     * 标记全部为已读
     */
    @Override
    @Transactional
    public int markAllAsRead(Long receiverId) {
        return notificationMapper.markAllAsRead(receiverId);
    }
    
    /**
     * 删除通知
     */
    @Override
    @Transactional
    public int deleteNotification(Long notificationId, Long receiverId) {
        // 验证通知是否存在且属于该接收者
        Notification notification = notificationMapper.selectNotificationById(notificationId);
        if (notification == null) {
            throw new ServiceException("通知不存在");
        }
        if (!notification.getReceiverId().equals(receiverId)) {
            throw new ServiceException("无权删除该通知");
        }
        
        return notificationMapper.deleteNotificationById(notificationId);
    }
    
    /**
     * 批量删除通知
     */
    @Override
    @Transactional
    public int deleteBatchNotification(Long[] notificationIds, Long receiverId) {
        // 验证所有通知都属于该接收者
        for (Long notificationId : notificationIds) {
            Notification notification = notificationMapper.selectNotificationById(notificationId);
            if (notification == null || !notification.getReceiverId().equals(receiverId)) {
                throw new ServiceException("通知ID=" + notificationId + "不存在或无权删除");
            }
        }
        
        return notificationMapper.deleteNotificationByIds(notificationIds);
    }
    
    // ========== 模板管理方法 ==========
    
    /**
     * 查询通知模板列表
     */
    @Override
    public List<NotificationTemplate> selectTemplateList(NotificationTemplate template) {
        return templateMapper.selectNotificationTemplateList(template);
    }
    
    /**
     * 根据ID查询通知模板
     */
    @Override
    public NotificationTemplate selectTemplateById(Long templateId) {
        return templateMapper.selectNotificationTemplateById(templateId);
    }
    
    /**
     * 根据编码查询通知模板
     */
    @Override
    public NotificationTemplate selectTemplateByCode(String templateCode) {
        return templateMapper.selectNotificationTemplateByCode(templateCode);
    }
    
    /**
     * 新增通知模板
     */
    @Override
    @Transactional
    public int insertTemplate(NotificationTemplate template) {
        // 校验模板编码唯一性
        NotificationTemplate existTemplate = templateMapper.checkTemplateCodeUnique(
            template.getTemplateCode(), null);
        if (existTemplate != null) {
            throw new ServiceException("模板编码已存在：" + template.getTemplateCode());
        }
        
        // 设置默认状态
        if (StringUtils.isEmpty(template.getStatus())) {
            template.setStatus("0"); // 0-正常
        }
        
        template.setCreateBy(SecurityUtils.getUsername());
        return templateMapper.insertNotificationTemplate(template);
    }
    
    /**
     * 修改通知模板
     */
    @Override
    @Transactional
    public int updateTemplate(NotificationTemplate template) {
        // 校验模板是否存在
        NotificationTemplate existTemplate = templateMapper.selectNotificationTemplateById(template.getId());
        if (existTemplate == null) {
            throw new ServiceException("模板不存在");
        }
        
        // 校验模板编码唯一性（排除自己）
        if (StringUtils.isNotEmpty(template.getTemplateCode())) {
            NotificationTemplate codeTemplate = templateMapper.checkTemplateCodeUnique(
                template.getTemplateCode(), template.getId());
            if (codeTemplate != null) {
                throw new ServiceException("模板编码已存在：" + template.getTemplateCode());
            }
        }
        
        template.setUpdateBy(SecurityUtils.getUsername());
        return templateMapper.updateNotificationTemplate(template);
    }
    
    /**
     * 删除通知模板
     */
    @Override
    @Transactional
    public int deleteTemplateByIds(Long[] templateIds) {
        // 校验模板是否被使用（可选：检查是否有通知使用该模板）
        // 这里先简单实现，后续可以添加使用检查
        
        return templateMapper.deleteNotificationTemplateByIds(templateIds);
    }
}