"""
评测基线报告生成脚本

读取 pipeline 批量处理输出的 CSV，生成统计报告和可视化图表。
"""

import argparse
import os
import random
from pathlib import Path

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import numpy as np
import pandas as pd


def setup_chinese_font():
    """尝试设置中文字体"""
    candidates = [
        'SimHei', 'Microsoft YaHei', 'WenQuanYi Micro Hei',
        'Noto Sans CJK SC', 'AR PL UMing CN', 'DejaVu Sans'
    ]
    for name in candidates:
        matches = [f for f in fm.fontManager.ttflist if name in f.name]
        if matches:
            plt.rcParams['font.sans-serif'] = [name]
            plt.rcParams['axes.unicode_minus'] = False
            return name
    # fallback: 不设置，可能乱码
    plt.rcParams['axes.unicode_minus'] = False
    return None


def load_csv(csv_path: str) -> pd.DataFrame:
    df = pd.read_csv(csv_path)
    print(f"加载 {len(df)} 条记录 from {csv_path}")
    return df


def print_distribution(df: pd.DataFrame):
    """打印花纹类型分布"""
    print("\n=== 花纹类型分布 ===")
    counts = df['pattern_type'].value_counts()
    for ptype, cnt in counts.items():
        pct = cnt / len(df) * 100
        print(f"  {ptype}: {cnt} ({pct:.1f}%)")


def print_stats(df: pd.DataFrame, col: str, label: str, unit: str = ''):
    """打印某列的统计信息"""
    s = df[col].dropna()
    print(f"\n=== {label} ===")
    print(f"  均值:   {s.mean():.3f}{unit}")
    print(f"  中位数: {s.median():.3f}{unit}")
    print(f"  标准差: {s.std():.3f}{unit}")
    print(f"  Q25:    {s.quantile(0.25):.3f}{unit}")
    print(f"  Q75:    {s.quantile(0.75):.3f}{unit}")
    print(f"  最小值: {s.min():.3f}{unit}")
    print(f"  最大值: {s.max():.3f}{unit}")


def plot_charts(df: pd.DataFrame, output_dir: Path):
    """生成评测图表"""
    fig, axes = plt.subplots(2, 2, figsize=(14, 10))

    # 1. 直径直方图
    ax = axes[0, 0]
    ax.hist(df['diameter_mm'].dropna(), bins=30, edgecolor='black', alpha=0.7)
    ax.set_title('diameter_mm distribution')
    ax.set_xlabel('diameter (mm)')
    ax.set_ylabel('count')

    # 2. 开裂比直方图
    ax = axes[0, 1]
    ax.hist(df['crack_ratio_percent'].dropna(), bins=30, edgecolor='black', alpha=0.7, color='orange')
    ax.set_title('crack_ratio_percent distribution')
    ax.set_xlabel('crack ratio (%)')
    ax.set_ylabel('count')

    # 3. 花纹类型饼图
    ax = axes[1, 0]
    counts = df['pattern_type'].value_counts()
    ax.pie(counts.values, labels=counts.index, autopct='%1.1f%%', startangle=90)
    ax.set_title('pattern_type distribution')

    # 4. 阈值散点图
    ax = axes[1, 1]
    ax.scatter(df['v_threshold'], df['s_threshold'], alpha=0.3, s=10)
    ax.set_title('V_threshold vs S_threshold')
    ax.set_xlabel('V_threshold')
    ax.set_ylabel('S_threshold')

    plt.tight_layout()
    chart_path = output_dir / 'evaluation_charts.png'
    fig.savefig(str(chart_path), dpi=150)
    plt.close(fig)
    print(f"\n图表已保存: {chart_path}")


def plot_extra_distributions(df: pd.DataFrame, output_dir: Path):
    """白色/茶褐色花纹占比分布"""
    fig, axes = plt.subplots(1, 2, figsize=(12, 5))

    ax = axes[0]
    vals = df['white_pattern_ratio'].dropna() * 100
    ax.hist(vals, bins=30, edgecolor='black', alpha=0.7, color='skyblue')
    ax.set_title('white_pattern_ratio distribution')
    ax.set_xlabel('white pattern ratio (%)')
    ax.set_ylabel('count')

    ax = axes[1]
    vals = df['brown_pattern_ratio'].dropna() * 100
    ax.hist(vals, bins=30, edgecolor='black', alpha=0.7, color='sienna')
    ax.set_title('brown_pattern_ratio distribution')
    ax.set_xlabel('brown pattern ratio (%)')
    ax.set_ylabel('count')

    plt.tight_layout()
    path = output_dir / 'pattern_ratio_distributions.png'
    fig.savefig(str(path), dpi=150)
    plt.close(fig)
    print(f"花纹占比分布图已保存: {path}")


def sample_filenames(df: pd.DataFrame, n: int = 50) -> list:
    """随机抽样n张图的文件名，供人工审查"""
    filenames = df['filename'].unique().tolist()
    n = min(n, len(filenames))
    sampled = random.sample(filenames, n)
    return sampled


def save_text_report(df: pd.DataFrame, output_dir: Path):
    """保存文本评测报告"""
    lines = []
    lines.append("=" * 60)
    lines.append("评测基线报告")
    lines.append("=" * 60)
    lines.append(f"总样本数: {len(df)}")
    lines.append(f"总图像数: {df['filename'].nunique()}")
    lines.append("")

    # 花纹类型分布
    lines.append("【花纹类型分布】")
    counts = df['pattern_type'].value_counts()
    for ptype, cnt in counts.items():
        lines.append(f"  {ptype}: {cnt} ({cnt/len(df)*100:.1f}%)")
    lines.append("")

    # 各项统计
    for col, label, unit in [
        ('diameter_mm', '直径', ' mm'),
        ('crack_ratio_percent', '开裂比', '%'),
        ('white_pattern_ratio', '白色花纹占比', ''),
        ('brown_pattern_ratio', '茶褐色花纹占比', ''),
        ('v_threshold', 'V_threshold', ''),
        ('s_threshold', 'S_threshold', ''),
    ]:
        if col not in df.columns:
            continue
        s = df[col].dropna()
        lines.append(f"【{label}统计】")
        lines.append(f"  均值:   {s.mean():.3f}{unit}")
        lines.append(f"  中位数: {s.median():.3f}{unit}")
        lines.append(f"  标准差: {s.std():.3f}{unit}")
        lines.append(f"  Q25:    {s.quantile(0.25):.3f}{unit}")
        lines.append(f"  Q75:    {s.quantile(0.75):.3f}{unit}")
        lines.append("")

    # 随机抽样
    sampled = sample_filenames(df, 50)
    lines.append(f"【随机抽样 {len(sampled)} 张图（供人工审查）】")
    for fname in sampled:
        lines.append(f"  {fname}")
    lines.append("")
    lines.append("=" * 60)

    report_path = output_dir / 'evaluation_report.txt'
    with open(report_path, 'w', encoding='utf-8') as f:
        f.write('\n'.join(lines))
    print(f"文本报告已保存: {report_path}")


def main():
    parser = argparse.ArgumentParser(description='评测基线报告生成')
    parser.add_argument('csv_path', type=str, help='pipeline输出的CSV文件路径')
    parser.add_argument('--output-dir', type=str, default='./evaluation', help='评测报告输出目录')
    args = parser.parse_args()

    output_dir = Path(args.output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)

    setup_chinese_font()

    df = load_csv(args.csv_path)

    # 控制台输出
    print_distribution(df)
    print_stats(df, 'diameter_mm', '直径分布', ' mm')
    print_stats(df, 'crack_ratio_percent', '开裂比分布', '%')
    if 'white_pattern_ratio' in df.columns:
        print_stats(df, 'white_pattern_ratio', '白色花纹占比')
    if 'brown_pattern_ratio' in df.columns:
        print_stats(df, 'brown_pattern_ratio', '茶褐色花纹占比')
    print_stats(df, 'v_threshold', 'V_threshold分布')
    print_stats(df, 's_threshold', 'S_threshold分布')

    # 生成图表
    plot_charts(df, output_dir)
    plot_extra_distributions(df, output_dir)

    # 保存文本报告
    save_text_report(df, output_dir)

    print("\n评测完成。")


if __name__ == "__main__":
    main()
