package net.micode.myapplication.service;

import net.micode.myapplication.model.Chapter;
import net.micode.myapplication.model.ClassificationResult;
import net.micode.myapplication.model.Course;
import net.micode.myapplication.model.Note;
import net.micode.myapplication.repository.CourseRepository;

import java.util.ArrayList;
import java.util.List;
import java.util.Collections;

public class ClassificationService {
    private CourseRepository courseRepository;
    private TextProcessor textProcessor;
    
    // 分类阈值
    private static final double MIN_CONFIDENCE_THRESHOLD = 0.3; // 最低置信度阈值
    private static final double HIGH_CONFIDENCE_THRESHOLD = 0.7; // 高置信度阈值
    
    public ClassificationService(CourseRepository courseRepository) {
        this.courseRepository = courseRepository;
        this.textProcessor = new TextProcessor();
    }
    
    /**
     * 对笔记进行自动分类
     */
    public ClassificationResult classifyNote(Note note) {
        if (note == null) {
            return createNoMatchResult("笔记为空");
        }
        
        // 获取所有课程和章节
        List<Course> allCourses = courseRepository.getAllCourses();
        if (allCourses.isEmpty()) {
            return createNoMatchResult("没有可用的课程数据");
        }
        
        // 组合笔记的文本内容
        String noteText = combineNoteText(note);
        if (noteText.isEmpty()) {
            return createNoMatchResult("笔记内容为空");
        }
        
        // 预处理文本
        String processedText = textProcessor.preprocessText(noteText);
        
        // 计算每个章节的匹配分数
        List<ChapterMatch> chapterMatches = new ArrayList<>();
        
        for (Course course : allCourses) {
            List<Chapter> chapters = courseRepository.getChaptersByCourseId(course.getCourseId());
            
            for (Chapter chapter : chapters) {
                double score = calculateMatchScore(processedText, chapter);
                if (score > 0) {
                    chapterMatches.add(new ChapterMatch(course, chapter, score));
                }
            }
        }
        
        // 如果没有找到匹配的章节
        if (chapterMatches.isEmpty()) {
            return createNoMatchResult("没有找到匹配的课程章节");
        }
        
        // 按分数排序，找到最佳匹配
        Collections.sort(chapterMatches, (a, b) -> Double.compare(b.score, a.score));
        ChapterMatch bestMatch = chapterMatches.get(0);
        
        // 检查置信度
        if (bestMatch.score < MIN_CONFIDENCE_THRESHOLD) {
            return createLowConfidenceResult(bestMatch.course, bestMatch.chapter, bestMatch.score);
        }
        
        // 返回分类结果
        return createClassificationResult(bestMatch.course, bestMatch.chapter, bestMatch.score);
    }
    
    /**
     * 计算笔记文本与章节的匹配分数
     */
    private double calculateMatchScore(String noteText, Chapter chapter) {
        double totalScore = 0.0;
        
        // 1. 关键词匹配分数 (权重: 0.5)
        double keywordScore = calculateKeywordScore(noteText, chapter);
        totalScore += keywordScore * 0.5;
        
        // 2. 章节标题相似度分数 (权重: 0.3)
        double titleScore = calculateTitleSimilarity(noteText, chapter);
        totalScore += titleScore * 0.3;
        
        // 3. 别名匹配分数 (权重: 0.2)
        double aliasScore = calculateAliasScore(noteText, chapter);
        totalScore += aliasScore * 0.2;
        
        return totalScore;
    }
    
    /**
     * 计算关键词匹配分数
     */
    private double calculateKeywordScore(String noteText, Chapter chapter) {
        if (chapter.getKeywords() == null || chapter.getKeywords().isEmpty()) {
            return 0.0;
        }
        
        return textProcessor.calculateKeywordMatchScore(noteText, chapter.getKeywords());
    }
    
    /**
     * 计算章节标题相似度分数
     */
    private double calculateTitleSimilarity(String noteText, Chapter chapter) {
        if (chapter.getChapterTitle() == null || chapter.getChapterTitle().isEmpty()) {
            return 0.0;
        }
        
        // 提取标题中的关键词
        List<String> titleKeywords = textProcessor.extractKeywords(chapter.getChapterTitle(), 5);
        
        if (titleKeywords.isEmpty()) {
            return 0.0;
        }
        
        return textProcessor.calculateKeywordMatchScore(noteText, titleKeywords);
    }
    
    /**
     * 计算别名匹配分数
     */
    private double calculateAliasScore(String noteText, Chapter chapter) {
        if (chapter.getAliases() == null || chapter.getAliases().isEmpty()) {
            return 0.0;
        }
        
        return textProcessor.calculateKeywordMatchScore(noteText, chapter.getAliases());
    }
    
    /**
     * 组合笔记的所有文本内容
     */
    private String combineNoteText(Note note) {
        StringBuilder text = new StringBuilder();
        
        if (note.getTitle() != null && !note.getTitle().trim().isEmpty()) {
            text.append(note.getTitle()).append(" ");
        }
        
        if (note.getDescription() != null && !note.getDescription().trim().isEmpty()) {
            text.append(note.getDescription()).append(" ");
        }
        
        if (note.getOcrText() != null && !note.getOcrText().trim().isEmpty()) {
            text.append(note.getOcrText());
        }
        
        return text.toString().trim();
    }
    
    /**
     * 创建分类结果
     */
    private ClassificationResult createClassificationResult(Course course, Chapter chapter, double score) {
        ClassificationResult result = new ClassificationResult();
        result.setCourse(course);
        result.setChapter(chapter);
        result.setConfidenceScore(score);
        
        String reason;
        if (score >= HIGH_CONFIDENCE_THRESHOLD) {
            reason = "高置信度匹配：关键词和标题高度相关";
        } else {
            reason = "中等置信度匹配：发现相关关键词";
        }
        result.setReason(reason);
        
        return result;
    }
    
    /**
     * 创建低置信度结果
     */
    private ClassificationResult createLowConfidenceResult(Course course, Chapter chapter, double score) {
        ClassificationResult result = new ClassificationResult();
        result.setCourse(course);
        result.setChapter(chapter);
        result.setConfidenceScore(score);
        result.setReason("低置信度匹配：建议用户确认或手动选择");
        return result;
    }
    
    /**
     * 创建无匹配结果
     */
    private ClassificationResult createNoMatchResult(String reason) {
        ClassificationResult result = new ClassificationResult();
        result.setConfidenceScore(0.0);
        result.setReason(reason);
        return result;
    }
    
    /**
     * 获取推荐分类列表（前N个最佳匹配）
     */
    public List<ClassificationResult> getTopClassifications(Note note, int topN) {
        List<ClassificationResult> results = new ArrayList<>();
        
        if (note == null) {
            return results;
        }
        
        List<Course> allCourses = courseRepository.getAllCourses();
        if (allCourses.isEmpty()) {
            return results;
        }
        
        String noteText = combineNoteText(note);
        String processedText = textProcessor.preprocessText(noteText);
        
        List<ChapterMatch> chapterMatches = new ArrayList<>();
        
        for (Course course : allCourses) {
            List<Chapter> chapters = courseRepository.getChaptersByCourseId(course.getCourseId());
            
            for (Chapter chapter : chapters) {
                double score = calculateMatchScore(processedText, chapter);
                if (score > 0) {
                    chapterMatches.add(new ChapterMatch(course, chapter, score));
                }
            }
        }
        
        Collections.sort(chapterMatches, (a, b) -> Double.compare(b.score, a.score));
        
        int count = Math.min(topN, chapterMatches.size());
        for (int i = 0; i < count; i++) {
            ChapterMatch match = chapterMatches.get(i);
            results.add(createClassificationResult(match.course, match.chapter, match.score));
        }
        
        return results;
    }
    
    /**
     * 内部类用于存储章节匹配结果
     */
    private static class ChapterMatch {
        Course course;
        Chapter chapter;
        double score;
        
        ChapterMatch(Course course, Chapter chapter, double score) {
            this.course = course;
            this.chapter = chapter;
            this.score = score;
        }
    }
}