"""CSV・PNG 出力モジュール."""

import csv
from pathlib import Path

import numpy as np

SUMMARY_FIELDNAMES = ["image_name", "mean", "std", "cov", "max_min_ratio", "max", "min"]
SPATIAL_FIELDNAMES = [
    "image_name",
    "center_mean",
    "middle_mean",
    "periphery_mean",
    "center_periphery_ratio",
    "gradient_magnitude",
]


def ensure_output_dirs(base_path: str) -> None:
    """output/figures/, output/results/, output/reports/ ディレクトリを作成する．

    Args:
        base_path: 出力ルートディレクトリのパス．
    """
    base = Path(base_path)
    (base / "figures").mkdir(parents=True, exist_ok=True)
    (base / "results").mkdir(parents=True, exist_ok=True)
    (base / "reports").mkdir(parents=True, exist_ok=True)
    print(f"出力ディレクトリを確認しました: {base}")


def export_results(results: dict, output_path: str) -> None:
    """均一性指標を CSV ファイルに出力する．

    CSV の形式は 1 行目がヘッダー，2 行目が値．

    Args:
        results: 均一性指標の辞書（calc_uniformity の戻り値）．
        output_path: 出力先ファイルパス（CSV）．
    """
    Path(output_path).parent.mkdir(parents=True, exist_ok=True)

    with Path(output_path).open("w", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=list(results.keys()))
        writer.writeheader()
        writer.writerow(results)

    print(f"結果を保存しました: {output_path}")


def export_summary(all_results: list[dict], output_path: str) -> None:
    """バッチ解析の集約結果を CSV ファイルに出力する．

    CSV の形式は 1 行目がヘッダー，2 行目以降が各画像の値．

    Args:
        all_results: 均一性指標の辞書リスト．各要素は
            {"image_name": "xxx", "mean": ..., "std": ..., "cov": ...,
             "max_min_ratio": ..., "max": ..., "min": ...} の形式．
        output_path: 出力先ファイルパス（CSV）．
    """
    Path(output_path).parent.mkdir(parents=True, exist_ok=True)

    with Path(output_path).open("w", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=SUMMARY_FIELDNAMES, extrasaction="ignore")
        writer.writeheader()
        writer.writerows(all_results)

    print(f"まとめ CSV を保存しました: {output_path}")


def export_spatial_summary(all_results: list[dict], output_path: str) -> None:
    """空間解析の集約結果を CSV ファイルに出力する．

    CSV の形式は 1 行目がヘッダー，2 行目以降が各画像の値．

    Args:
        all_results: 空間解析結果を含む辞書リスト．各要素は
            {"image_name": "xxx", "center_mean": ..., "middle_mean": ...,
             "periphery_mean": ..., "center_periphery_ratio": ...,
             "gradient_magnitude": ...} を含む形式．
        output_path: 出力先ファイルパス（CSV）．
    """
    Path(output_path).parent.mkdir(parents=True, exist_ok=True)

    with Path(output_path).open("w", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=SPATIAL_FIELDNAMES, extrasaction="ignore")
        writer.writeheader()
        writer.writerows(all_results)

    print(f"空間解析まとめ CSV を保存しました: {output_path}")


def calc_batch_statistics(all_results: list[dict]) -> dict:
    """バッチ解析結果から画像間の集計統計を算出する．

    各指標について mean, std, min, max, cv（画像間変動係数）を計算する．

    Args:
        all_results: 均一性指標と空間解析結果を含む辞書リスト．

    Returns:
        {"uniformity": {...}, "spatial": {...}} の形式．
        各値は {指標名: {"mean": ..., "std": ..., "min": ..., "max": ..., "cv": ...}}
        の辞書．
    """
    uniformity_metrics = ["mean", "std", "cov", "max_min_ratio"]
    spatial_metrics = [
        "center_mean",
        "middle_mean",
        "periphery_mean",
        "center_periphery_ratio",
        "gradient_magnitude",
    ]

    def _calc_metric_stats(metric_name: str) -> dict:
        values = np.array([r[metric_name] for r in all_results if metric_name in r])
        m = float(np.mean(values))
        s = float(np.std(values, ddof=0))
        cv = s / m if m != 0 else 0.0
        return {
            "mean": m,
            "std": s,
            "min": float(np.min(values)),
            "max": float(np.max(values)),
            "cv": cv,
        }

    uniformity_stats = {
        metric: _calc_metric_stats(metric) for metric in uniformity_metrics
    }
    spatial_stats = {
        metric: _calc_metric_stats(metric) for metric in spatial_metrics
    }

    return {"uniformity": uniformity_stats, "spatial": spatial_stats}


def export_batch_statistics(stats: dict, output_path: str) -> None:
    """集計統計を CSV ファイルに出力する．

    行: 各指標名，列: statistic, mean, std, min, max, cv

    Args:
        stats: calc_batch_statistics の戻り値．
        output_path: 出力先ファイルパス（CSV）．
    """
    Path(output_path).parent.mkdir(parents=True, exist_ok=True)

    fieldnames = ["statistic", "mean", "std", "min", "max", "cv"]
    rows = []
    for category in ("uniformity", "spatial"):
        for metric_name, values in stats[category].items():
            rows.append({
                "statistic": metric_name,
                "mean": values["mean"],
                "std": values["std"],
                "min": values["min"],
                "max": values["max"],
                "cv": values["cv"],
            })

    with Path(output_path).open("w", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(rows)

    print(f"集計統計 CSV を保存しました: {output_path}")
