"""HTML レポート生成モジュール."""

import base64
from datetime import datetime
from pathlib import Path

import pandas
from jinja2 import Environment, FileSystemLoader


def encode_image_base64(image_path: str) -> str:
    """PNG 画像ファイルを Base64 エンコードした data URI に変換する．

    HTML に画像をインライン埋め込みすることで、レポートを自己完結させる．

    Args:
        image_path: PNG 画像ファイルのパス．

    Returns:
        "data:image/png;base64,..." 形式の文字列．
        ファイルが存在しない場合は空文字列を返す．
    """
    path = Path(image_path)
    if not path.exists():
        return ""

    with path.open("rb") as f:
        encoded = base64.b64encode(f.read()).decode("utf-8")

    return f"data:image/png;base64,{encoded}"


def build_report_context(
    summary_csv_path: str,
    spatial_csv_path: str,
    figures_dir: str,
) -> dict:
    """CSV と図ファイルからテンプレート描画用のコンテキスト辞書を構築する．

    画像は Base64 エンコードしてインライン埋め込みにするため、
    レポート HTML が単独で完結する形になる．

    Args:
        summary_csv_path: 均一性サマリ CSV のパス（summary_uniformity.csv）．
        spatial_csv_path: 空間解析サマリ CSV のパス（summary_spatial.csv）．
        figures_dir: 各種図ファイルが格納されたディレクトリのパス．

    Returns:
        Jinja2 テンプレートに渡すコンテキスト辞書．キーは:
        "generated_at", "summary_rows", "spatial_rows", "image_details"．

    Raises:
        FileNotFoundError: CSV ファイルが存在しない場合．
    """
    summary_path = Path(summary_csv_path)
    if not summary_path.exists():
        raise FileNotFoundError(
            f"均一性サマリ CSV が見つかりません: {summary_csv_path}"
        )

    spatial_path = Path(spatial_csv_path)
    if not spatial_path.exists():
        raise FileNotFoundError(
            f"空間解析サマリ CSV が見つかりません: {spatial_csv_path}"
        )

    summary_df = pandas.read_csv(summary_path)
    spatial_df = pandas.read_csv(spatial_path)

    figures_path = Path(figures_dir)

    # 画像別詳細: サマリに登場する image_name ごとに図を収集する
    image_details = []
    for image_name in summary_df["image_name"].tolist():
        detail = {
            "name": image_name,
            "luminance_map": encode_image_base64(
                str(figures_path / f"{image_name}_luminance_map.png")
            ),
            "histogram": encode_image_base64(
                str(figures_path / f"{image_name}_histogram.png")
            ),
            "radial_profile": encode_image_base64(
                str(figures_path / f"{image_name}_radial_profile.png")
            ),
            "zone_map": encode_image_base64(
                str(figures_path / f"{image_name}_zone_map.png")
            ),
        }
        image_details.append(detail)

    return {
        "generated_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        "summary_rows": summary_df.to_dict(orient="records"),
        "spatial_rows": spatial_df.to_dict(orient="records"),
        "image_details": image_details,
    }


def render_html_report(context: dict, template_path: str, output_path: str) -> None:
    """Jinja2 テンプレートにコンテキストを適用して HTML レポートを生成する．

    Args:
        context: テンプレートに渡すコンテキスト辞書（build_report_context の戻り値）．
        template_path: Jinja2 テンプレートファイルのパス．
        output_path: 出力先 HTML ファイルのパス．
    """
    template_file = Path(template_path)
    env = Environment(
        loader=FileSystemLoader(str(template_file.parent)),
        autoescape=True,
    )
    template = env.get_template(template_file.name)
    html = template.render(**context)

    out_path = Path(output_path)
    out_path.parent.mkdir(parents=True, exist_ok=True)
    out_path.write_text(html, encoding="utf-8")

    print(f"HTML レポートを保存しました: {output_path}")
