#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
课评质量自动验证脚本
用于检查生成的课评是否符合规范

使用方法:
    python evaluation_validator.py <课评文件路径>
    python evaluation_validator.py --batch <班级汇总文件路径>
    python evaluation_validator.py --student <学生历史课评文件路径>
"""

import sys
import io
import re
import argparse
from pathlib import Path
from datetime import datetime

# 设置UTF-8输出编码
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')

# ============ 配置项 ============

# 字数范围配置（与规则文件保持一致）
MIN_LENGTH = 180
MAX_LENGTH = 350

# 禁用词汇列表
FORBIDDEN_WORDS = [
    "宝贝", "小天才", "最棒", "无敌", "超级厉害", "完美",
    "在今天的课堂上", "通过本次活动",
    "比其他小朋友", "补课", "补课上", "来补课", "本次补课",
    "临时加入", "从其他班级过来"
]

# 必须包含的模块关键词（至少包含其中几类）
REQUIRED_MODULES = {
    "课程知识点": ["学习了", "认识了", "探索了", "了解了"],
    "掌握程度": ["完成", "掌握", "理解", "尝试", "独立"],
    "课后建议": ["在家", "可以", "建议", "巩固"]
}

# Emoji检查配置
MIN_EMOJI = 3
MAX_EMOJI = 5

# ============ 核心验证类 ============

class EvaluationValidator:
    def __init__(self, text: str, student_name: str = ""):
        self.text = text
        self.student_name = student_name
        self.errors = []
        self.warnings = []
        self.stats = {}

    def validate_all(self) -> dict:
        """执行所有验证检查"""
        self.check_length()
        self.check_forbidden_words()
        self.check_emoji_count()
        self.check_modules()
        self.check_name_usage()
        self.check_week_number()
        self.check_paragraph_structure()

        return {
            "status": "通过" if not self.errors else "未通过",
            "errors": self.errors,
            "warnings": self.warnings,
            "stats": self.stats
        }

    def check_length(self):
        """检查字数是否在弹性范围内"""
        # 计算中文字符数（不含空格、换行、标点）
        chinese_chars = len(re.findall(r'[\u4e00-\u9fff]', self.text))
        # 计算总字符数（含英文单词）
        total_chars = len(self.text.replace(' ', '').replace('\n', ''))

        self.stats["中文字数"] = chinese_chars
        self.stats["总字符数"] = total_chars

        if chinese_chars < MIN_LENGTH:
            self.errors.append(f"字数不足：当前{chinese_chars}字，最少要求{MIN_LENGTH}字")
        elif chinese_chars > MAX_LENGTH:
            self.warnings.append(f"字数偏多：当前{chinese_chars}字，建议控制在{MAX_LENGTH}字以内")
        else:
            self.stats["字数检查"] = f"✅ 通过（{chinese_chars}字）"

    def check_forbidden_words(self):
        """检查是否包含禁用词汇"""
        found = []
        for word in FORBIDDEN_WORDS:
            if word in self.text:
                found.append(word)

        if found:
            self.errors.append(f"包含禁用词汇：{', '.join(found)}")
        else:
            self.stats["禁用词检查"] = "✅ 通过"

    def check_emoji_count(self):
        """检查Emoji数量"""
        # 只匹配真正的Emoji字符（排除Markdown符号如✓、✅等）
        # 匹配Unicode Emoji范围
        emojis = re.findall(r'[\U0001F300-\U0001F9FF]', self.text)
        emoji_count = len(emojis)
        self.stats["Emoji数量"] = emoji_count

        if emoji_count < MIN_EMOJI:
            self.warnings.append(f"Emoji较少：当前{emoji_count}个，建议至少{MIN_EMOJI}个")
        elif emoji_count > MAX_EMOJI:
            self.warnings.append(f"Emoji较多：当前{emoji_count}个，建议不超过{MAX_EMOJI}个")
        else:
            self.stats["Emoji检查"] = f"✅ 通过（{emoji_count}个）"

    def check_modules(self):
        """检查是否包含必要的模块内容"""
        missing_modules = []
        for module_name, keywords in REQUIRED_MODULES.items():
            if not any(keyword in self.text for keyword in keywords):
                missing_modules.append(module_name)

        if missing_modules:
            self.warnings.append(f"可能缺少以下模块：{', '.join(missing_modules)}")
        else:
            self.stats["模块检查"] = "✅ 通过"

    def check_name_usage(self):
        """检查学生称呼使用是否正确"""
        if not self.student_name:
            return

        # 检查是否使用了全名（应该使用小名/去姓/叠字）
        if len(self.student_name) >= 3 and self.student_name in self.text:
            self.warnings.append(f"可能使用了全名'{self.student_name}'，建议使用小名或去姓称呼")

    def check_week_number(self):
        """检查正文中是否出现了周数信息"""
        week_patterns = [r'第\d+周', r'本周第\d+节', r'第\d+节课']
        found = []
        for pattern in week_patterns:
            matches = re.findall(pattern, self.text)
            found.extend(matches)

        if found:
            self.errors.append(f"课评正文禁止出现周数：{', '.join(found)}")
        else:
            self.stats["周数检查"] = "✅ 通过"

    def check_paragraph_structure(self):
        """检查段落结构"""
        paragraphs = [p.strip() for p in self.text.split('\n\n') if p.strip()]

        if len(paragraphs) != 3:
            self.warnings.append(f"段落数建议为3段，当前{len(paragraphs)}段")
        else:
            self.stats["段落检查"] = "✅ 通过（3段）"

        self.stats["段落数"] = len(paragraphs)


# ============ 文件解析函数 ============

def parse_class_summary(file_path: str) -> list:
    """解析班级周汇总文件，提取各学生课评"""
    with open(file_path, 'r', encoding='utf-8') as f:
        content = f.read()

    evaluations = []

    # 匹配学生课评区块
    pattern = r'###\s*(.+?)\n\n(.+?)(?=\n###|\Z)'
    matches = re.findall(pattern, content, re.DOTALL)

    for name_section, eval_text in matches:
        # 提取学生姓名（去掉括号内容）
        name = name_section.split('（')[0].strip()
        evaluations.append({
            "name": name,
            "text": eval_text.strip()
        })

    return evaluations


def parse_student_history(file_path: str) -> list:
    """解析学生历史课评文件，提取各条课评"""
    with open(file_path, 'r', encoding='utf-8') as f:
        content = f.read()

    evaluations = []

    # 匹配课评记录
    pattern = r'###\s*(\d{4}-\d{2}-\d{2})\s*\|\s*课程代码：(.+?)\n\n\*\*课评内容\*\*：\n\n(.+?)(?=\n\*\*能力评估\*\*|\Z)'
    matches = re.findall(pattern, content, re.DOTALL)

    for date, course_code, eval_text in matches:
        evaluations.append({
            "date": date,
            "course": course_code,
            "text": eval_text.strip()
        })

    return evaluations


# ============ 输出格式化 ============

def print_result(result: dict, identifier: str = ""):
    """打印验证结果"""
    print(f"\n{'='*60}")
    if identifier:
        print(f"📋 验证对象：{identifier}")
    print(f"🎯 验证状态：{result['status']}")
    print(f"{'='*60}")

    if result['stats']:
        print("\n📊 统计信息：")
        for key, value in result['stats'].items():
            print(f"   {key}: {value}")

    if result['errors']:
        print("\n❌ 错误（必须修复）：")
        for error in result['errors']:
            print(f"   • {error}")

    if result['warnings']:
        print("\n⚠️  警告（建议优化）：")
        for warning in result['warnings']:
            print(f"   • {warning}")

    if not result['errors'] and not result['warnings']:
        print("\n✅ 所有检查项通过！")

    print(f"{'='*60}\n")


# ============ 主函数 ============

def main():
    parser = argparse.ArgumentParser(description='课评质量自动验证工具')
    parser.add_argument('file', help='要验证的文件路径')
    parser.add_argument('--batch', action='store_true', help='批量验证班级汇总文件')
    parser.add_argument('--student', action='store_true', help='验证学生历史课评文件')
    parser.add_argument('--text', action='store_true', help='直接验证文本内容')

    args = parser.parse_args()

    if args.text:
        # 直接验证文本
        with open(args.file, 'r', encoding='utf-8') as f:
            text = f.read()
        validator = EvaluationValidator(text)
        result = validator.validate_all()
        print_result(result, "文本内容")

    elif args.batch:
        # 批量验证班级汇总
        print(f"📁 正在解析班级汇总文件：{args.file}")
        evaluations = parse_class_summary(args.file)
        print(f"找到 {len(evaluations)} 条课评记录\n")

        all_passed = True
        for eval_data in evaluations:
            validator = EvaluationValidator(eval_data['text'], eval_data['name'])
            result = validator.validate_all()
            print_result(result, f"学生：{eval_data['name']}")
            if result['status'] != '通过':
                all_passed = False

        print(f"\n{'='*60}")
        print(f"📊 批量验证完成：{len(evaluations)}条课评")
        print(f"🎯 总体状态：{'✅ 全部通过' if all_passed else '❌ 存在未通过项'}")
        print(f"{'='*60}")

    elif args.student:
        # 验证学生历史课评
        print(f"📁 正在解析学生历史课评：{args.file}")
        evaluations = parse_student_history(args.file)
        print(f"找到 {len(evaluations)} 条历史记录\n")

        for eval_data in evaluations:
            validator = EvaluationValidator(eval_data['text'])
            result = validator.validate_all()
            print_result(result, f"日期：{eval_data['date']} | 课程：{eval_data['course']}")

    else:
        # 默认：尝试自动识别文件类型
        with open(args.file, 'r', encoding='utf-8') as f:
            content = f.read()

        if '班级周汇总' in content or '学生课评列表' in content:
            print("🔍 自动识别为：班级汇总文件")
            evaluations = parse_class_summary(args.file)
            for eval_data in evaluations:
                validator = EvaluationValidator(eval_data['text'], eval_data['name'])
                result = validator.validate_all()
                print_result(result, f"学生：{eval_data['name']}")
        else:
            print("🔍 自动识别为：单条课评文本")
            validator = EvaluationValidator(content)
            result = validator.validate_all()
            print_result(result, args.file)


if __name__ == '__main__':
    main()
