package com.erp.audit.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.erp.audit.entity.SensitiveAlertRecord;
import com.erp.audit.entity.SensitiveOperationRule;
import com.erp.audit.repository.SensitiveAlertRecordRepository;
import com.erp.audit.repository.SensitiveOperationRuleRepository;
import com.erp.audit.service.SensitiveOperationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 敏感操作服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SensitiveOperationServiceImpl implements SensitiveOperationService {

    private final SensitiveOperationRuleRepository ruleRepository;
    private final SensitiveAlertRecordRepository alertRepository;

    @Override
    public List<SensitiveOperationRule> getEnabledRules() {
        LambdaQueryWrapper<SensitiveOperationRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SensitiveOperationRule::getEnabled, true);
        return ruleRepository.selectList(wrapper);
    }

    @Override
    @Transactional
    public SensitiveOperationRule saveRule(SensitiveOperationRule rule) {
        if (rule.getId() == null) {
            rule.setCreatedAt(LocalDateTime.now());
            ruleRepository.insert(rule);
        } else {
            rule.setUpdatedAt(LocalDateTime.now());
            ruleRepository.updateById(rule);
        }
        return rule;
    }

    @Override
    @Transactional
    public void deleteRule(Long id) {
        ruleRepository.deleteById(id);
    }

    @Override
    public SensitiveOperationRule matchRule(String url, String operationType, String module) {
        List<SensitiveOperationRule> rules = ruleRepository.selectEnabledRules();
        for (SensitiveOperationRule rule : rules) {
            if (matches(rule, url, operationType, module)) {
                return rule;
            }
        }
        return null;
    }

    private boolean matches(SensitiveOperationRule rule, String url, String operationType, String module) {
        boolean urlMatch = rule.getUrlPattern() != null && 
                (rule.getUrlPattern().equals("*") || url.contains(rule.getUrlPattern()));
        boolean opMatch = rule.getOperationType() != null && 
                rule.getOperationType().equalsIgnoreCase(operationType);
        boolean modMatch = rule.getModule() != null && 
                rule.getModule().equalsIgnoreCase(module);
        return urlMatch || opMatch || modMatch;
    }

    @Override
    @Async
    @Transactional
    public void triggerAlert(Long auditLogId, SensitiveOperationRule rule) {
        if (rule == null) {
            return;
        }

        log.warn("🚨 触发敏感操作告警 - 规则: {}, 级别: {}", rule.getRuleName(), rule.getAlertLevel());

        SensitiveAlertRecord alert = SensitiveAlertRecord.builder()
                .auditLogId(auditLogId)
                .ruleId(rule.getId())
                .ruleCode(rule.getRuleCode())
                .alertLevel(rule.getAlertLevel())
                .alertContent(String.format("检测到敏感操作: %s [%s]", rule.getRuleName(), rule.getAlertLevel()))
                .alertStatus("PENDING")
                .notifyChannel(rule.getNotifyChannels())
                .notifyUser(rule.getNotifyUsers())
                .createdAt(LocalDateTime.now())
                .build();

        alertRepository.insert(alert);

        // 发送通知
        sendNotification(alert, rule);
    }

    private void sendNotification(SensitiveAlertRecord alert, SensitiveOperationRule rule) {
        String[] channels = rule.getNotifyChannels().split(",");
        for (String channel : channels) {
            switch (channel.trim().toUpperCase()) {
                case "ROCKETMQ":
                    sendRocketMQNotification(alert, rule);
                    break;
                case "WEBHOOK":
                    sendWebhookNotification(alert, rule);
                    break;
                case "EMAIL":
                    sendEmailNotification(alert, rule);
                    break;
                default:
                    log.info("未知通知渠道: {}", channel);
            }
        }

        alert.setAlertStatus("SENT");
        alert.setNotifyTime(LocalDateTime.now());
        alertRepository.updateById(alert);
    }

    private void sendRocketMQNotification(SensitiveAlertRecord alert, SensitiveOperationRule rule) {
        log.info("📬 发送RocketMQ告警通知 - 规则: {}, 接收人: {}", 
                rule.getRuleName(), rule.getNotifyUsers());
    }

    private void sendWebhookNotification(SensitiveAlertRecord alert, SensitiveOperationRule rule) {
        log.info("🔗 发送Webhook告警通知 - 规则: {}", rule.getRuleName());
    }

    private void sendEmailNotification(SensitiveAlertRecord alert, SensitiveOperationRule rule) {
        log.info("📧 发送邮件告警通知 - 规则: {}, 接收人: {}", 
                rule.getRuleName(), rule.getNotifyUsers());
    }
}
