# -*- coding: utf-8 -*-
"""受領した学習データをモデル比較用の特徴量CSVに整形する。"""
import argparse
from pathlib import Path

import numpy as np
import pandas as pd


ROOT = Path(__file__).resolve().parents[2]
DEFAULT_INPUT = ROOT / "検証" / "data" / "learning_data.csv"
DEFAULT_OUTPUT = ROOT / "検証" / "data" / "features.csv"

DEFAULT_EXCLUDE = {
    "comment",
    "comments",
    "評価備考",
    "summary",
    "deduction_reasons",
    "craftsperson_check_points",
    "raw_response",
    "api_response",
    "image_path",
    "video_path",
    "filename",
}


def _pick_first(columns, candidates):
    for name in candidates:
        if name in columns:
            return name
    return None


def _coerce_bool_or_category(series):
    text = series.astype(str).str.strip()
    lowered = text.str.lower()
    if lowered.isin(["true", "false", "yes", "no", "0", "1"]).all():
        return lowered.map({"true": 1, "yes": 1, "1": 1, "false": 0, "no": 0, "0": 0})
    codes, _ = pd.factorize(text, sort=True)
    return pd.Series(codes, index=series.index).replace(-1, np.nan)


def prepare(input_path, output_path, target, sample_id, exclude):
    df = pd.read_csv(input_path)
    columns = set(df.columns)

    if sample_id is None:
        sample_id = _pick_first(columns, ["sample_id", "id", "ID", "画像ID", "動画ID"])
    if target is None:
        target = _pick_first(columns, ["total_score", "soup_score", "total", "soup", "濃度込みの点数", "スープのみの点数"])

    if not target or target not in df.columns:
        raise ValueError("目的変数列が見つかりません。--target で指定してください。")

    out = pd.DataFrame()
    out["sample_id"] = df[sample_id] if sample_id in df.columns else np.arange(len(df))
    out["target"] = pd.to_numeric(df[target], errors="coerce")

    excluded = set(exclude) | DEFAULT_EXCLUDE | {target, sample_id}
    for col in df.columns:
        if col in excluded:
            continue
        numeric = pd.to_numeric(df[col], errors="coerce")
        if numeric.notna().sum() >= max(3, int(len(df) * 0.5)):
            out[col] = numeric
        elif df[col].notna().sum() >= max(3, int(len(df) * 0.5)):
            out[col] = _coerce_bool_or_category(df[col])

    feature_cols = [c for c in out.columns if c not in {"sample_id", "target"}]
    if feature_cols:
        out["feature_raw_total"] = out[feature_cols].sum(axis=1, skipna=True)
        out["feature_max"] = out[feature_cols].max(axis=1, skipna=True)
        out["feature_n_low"] = (out[feature_cols] < 10).sum(axis=1)

    out = out.dropna(subset=["target"]).reset_index(drop=True)
    output_path.parent.mkdir(parents=True, exist_ok=True)
    out.to_csv(output_path, index=False, encoding="utf-8-sig")
    return out


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--input", type=Path, default=DEFAULT_INPUT)
    parser.add_argument("--output", type=Path, default=DEFAULT_OUTPUT)
    parser.add_argument("--target", default=None)
    parser.add_argument("--sample-id", default=None)
    parser.add_argument("--exclude", nargs="*", default=[])
    args = parser.parse_args()

    df = prepare(args.input, args.output, args.target, args.sample_id, args.exclude)
    print(f"saved: {args.output}")
    print(f"rows={len(df)} features={len([c for c in df.columns if c not in {'sample_id', 'target'}])}")


if __name__ == "__main__":
    main()
