package com.aegis.knowledge.service.impl;

import com.aegis.common.utils.StringUtils;
import com.aegis.knowledge.domain.KnowledgeDocument;
import com.aegis.knowledge.mapper.KnowledgeDocumentMapper;
import com.aegis.knowledge.service.IKnowledgeDocumentService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;

/**
 * 知识库文档 Service 实现
 */
@Service
public class KnowledgeDocumentServiceImpl extends ServiceImpl<KnowledgeDocumentMapper, KnowledgeDocument> implements IKnowledgeDocumentService {

    @Override
    public List<KnowledgeDocument> listByCondition(String keyword, Long categoryId, String tags, Date beginTime, Date endTime) {
        LambdaQueryWrapper<KnowledgeDocument> wrapper = new LambdaQueryWrapper<>();
        
        // 关键词搜索（标题、标签、关键词字段）
        if (StringUtils.isNotBlank(keyword)) {
            wrapper.and(w -> w.like(KnowledgeDocument::getTitle, keyword)
                    .or().like(KnowledgeDocument::getTags, keyword)
                    .or().like(KnowledgeDocument::getKeywords, keyword));
        }
        
        // 分类筛选
        if (categoryId != null) {
            wrapper.eq(KnowledgeDocument::getCategoryId, categoryId);
        }
        
        // 标签筛选
        if (StringUtils.isNotBlank(tags)) {
            String[] tagArray = tags.split(",");
            for (String tag : tagArray) {
                if (StringUtils.isNotBlank(tag)) {
                    wrapper.like(KnowledgeDocument::getTags, tag.trim());
                }
            }
        }
        
        // 时间范围
        if (beginTime != null) {
            wrapper.ge(KnowledgeDocument::getCreateTime, beginTime);
        }
        if (endTime != null) {
            wrapper.le(KnowledgeDocument::getCreateTime, endTime);
        }
        
        wrapper.eq(KnowledgeDocument::getDelFlag, "0");
        wrapper.orderByDesc(KnowledgeDocument::getCreateTime);
        
        return this.list(wrapper);
    }

    @Override
    public List<KnowledgeDocument> recommendDocuments(String eventType, String keywords) {
        LambdaQueryWrapper<KnowledgeDocument> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(KnowledgeDocument::getDelFlag, "0");
        
        List<KnowledgeDocument> candidates = this.list(wrapper);
        
        // 计算匹配度并排序
        List<DocumentMatch> matches = new ArrayList<>();
        for (KnowledgeDocument doc : candidates) {
            double score = calculateMatchScore(doc, eventType, keywords);
            if (score > 0) {
                matches.add(new DocumentMatch(doc, score));
            }
        }
        
        // 按匹配度降序排序
        matches.sort((a, b) -> Double.compare(b.score, a.score));
        
        // 返回文档列表
        return matches.stream()
                .map(m -> m.document)
                .collect(Collectors.toList());
    }

    @Override
    public void incrementViewCount(Long id) {
        KnowledgeDocument document = this.getById(id);
        if (document != null) {
            document.setViewCount((document.getViewCount() == null ? 0 : document.getViewCount()) + 1);
            this.updateById(document);
        }
    }

    @Override
    public void incrementDownloadCount(Long id) {
        KnowledgeDocument document = this.getById(id);
        if (document != null) {
            document.setDownloadCount((document.getDownloadCount() == null ? 0 : document.getDownloadCount()) + 1);
            this.updateById(document);
        }
    }

    /**
     * 计算文档匹配度
     */
    private double calculateMatchScore(KnowledgeDocument doc, String eventType, String keywords) {
        double score = 0.0;
        int totalKeywords = 0;

        // 解析文档关键词
        List<String> docKeywords = new ArrayList<>();
        if (StringUtils.isNotBlank(doc.getKeywords())) {
            docKeywords.addAll(Arrays.stream(doc.getKeywords().split(","))
                    .map(String::trim)
                    .filter(s -> StringUtils.isNotBlank(s))
                    .collect(Collectors.toList()));
        }
        if (StringUtils.isNotBlank(doc.getTags())) {
            docKeywords.addAll(Arrays.stream(doc.getTags().split(","))
                    .map(String::trim)
                    .filter(s -> StringUtils.isNotBlank(s))
                    .collect(Collectors.toList()));
        }
        totalKeywords = docKeywords.size();
        if (totalKeywords == 0) {
            return 0.0;
        }

        int matchCount = 0;
        int inputKeywordCount = 0;

        // 匹配事件类型
        if (StringUtils.isNotBlank(eventType)) {
            for (String docKeyword : docKeywords) {
                if (docKeyword.contains(eventType) || eventType.contains(docKeyword)) {
                    matchCount++;
                    score += 0.5; // 事件类型匹配权重
                }
            }
        }

        // 匹配关键词
        List<String> inputKeywords = new ArrayList<>();
        if (StringUtils.isNotBlank(keywords)) {
            inputKeywords = Arrays.stream(keywords.split(","))
                    .map(String::trim)
                    .filter(StringUtils::isNotBlank)
                    .collect(Collectors.toList());
            inputKeywordCount = inputKeywords.size();
            
            for (String inputKeyword : inputKeywords) {
                for (String docKeyword : docKeywords) {
                    if (docKeyword.contains(inputKeyword) || inputKeyword.contains(docKeyword)) {
                        matchCount++;
                        score += 1.0; // 关键词匹配权重
                    }
                }
            }
        }

        // 计算匹配度（匹配的关键词数量 / (文档关键词总数 + 输入关键词总数)）
        if (totalKeywords > 0 || inputKeywordCount > 0) {
            score = matchCount / (double) (totalKeywords + inputKeywordCount);
        }

        return score;
    }

    /**
     * 文档匹配结果内部类
     */
    private static class DocumentMatch {
        KnowledgeDocument document;
        double score;

        DocumentMatch(KnowledgeDocument document, double score) {
            this.document = document;
            this.score = score;
        }
    }
}

