from __future__ import annotations

import argparse
import json
from pathlib import Path
from typing import Any


ROOT = Path(__file__).resolve().parents[1]
TEMP = ROOT / "Temp"
DEFAULT_JSON = ROOT / "GatherTradingData.json"
DEFAULT_OUT = TEMP / "value_preservation_scorer_v2.json"


def _load(path: Path) -> dict[str, Any]:
    if not path.exists():
        return {}
    try:
        obj = json.loads(path.read_text(encoding="utf-8"))
    except Exception:
        return {}
    return obj if isinstance(obj, dict) else {}


def _count_masked_metrics(scr: dict) -> int:
    """RAW_VS_ADJUSTED_DISCLOSURE_V1: raw 병기 없는 adjusted 단독 표시 감지."""
    count = 0
    raw = scr.get("raw_value_damage_pct_avg")
    adj = scr.get("adjusted_value_damage_pct_avg")
    if adj is not None and raw is None:
        count += 1
    return count


def main() -> int:
    ap = argparse.ArgumentParser()
    ap.add_argument("--json", default=str(DEFAULT_JSON))
    ap.add_argument("--out", default=str(DEFAULT_OUT))
    args = ap.parse_args()

    payload = _load(Path(args.json) if Path(args.json).is_absolute() else ROOT / args.json)
    rows = payload.get("value_preservation_rows") if isinstance(payload.get("value_preservation_rows"), list) else []
    recommended_actions = [str(r.get("recommended_action") or "UNKNOWN") for r in rows if isinstance(r, dict)]
    distinct_actions = sorted(set(recommended_actions))
    reason = None
    if len(rows) >= 2 and len(distinct_actions) < 2:
        reason = "HOMOGENEOUS_RISK_JUSTIFIED"

    # RAW_VS_ADJUSTED_DISCLOSURE_V1: smart_cash_recovery에서 raw 값 읽기
    scr_v8 = _load(TEMP / "smart_cash_recovery_v8.json") or _load(TEMP / "smart_cash_recovery_v7.json")
    raw_damage = scr_v8.get("raw_value_damage_pct_avg")   # raw 우선 (게이트 입력)
    adj_damage = scr_v8.get("adjusted_value_damage_pct_avg")
    masked_count = _count_masked_metrics(scr_v8)

    # 가치훼손 캡 게이트는 반드시 raw 값을 사용
    value_damage_gate_input = raw_damage   # adjusted 아님 — RAW_VS_ADJUSTED_DISCLOSURE_V1
    value_damage_cap_pass = (
        raw_damage is not None and float(raw_damage) <= 10.0
    )

    # [VD1] n<30 → WATCH_PENDING_SAMPLE (공허 PASS 차단)
    MIN_SAMPLES = 30
    if len(rows) < MIN_SAMPLES:
        action_gate = "WATCH_PENDING_SAMPLE"
    elif len(rows) < 2 or len(distinct_actions) >= 2 or reason:
        action_gate = "PASS"
    else:
        action_gate = "FAIL"

    result = {
        "formula_id": "VALUE_PRESERVATION_SCORER_V2",
        "row_count": len(rows),
        "distinct_actions": len(distinct_actions),
        "recommended_actions": distinct_actions,
        "reason": reason,
        "gate": action_gate,
        # RAW_VS_ADJUSTED_DISCLOSURE_V1 필드
        "raw_value_damage_pct_avg": raw_damage,
        "adjusted_value_damage_pct_avg": adj_damage,
        "value_damage_gate_input": value_damage_gate_input,
        "value_damage_gate_input_source": "raw_value_damage_pct_avg",
        "value_damage_cap_pass": value_damage_cap_pass,
        "masked_metric_without_raw_count": masked_count,
        "masking_disclosure_note": (
            f"raw {raw_damage}% / adj {adj_damage}%"
            if raw_damage is not None and adj_damage is not None
            else "[RAW_MISSING: raw_value_damage_pct_avg 없음]" if raw_damage is None else "OK"
        ),
    }

    out_path = Path(args.out)
    if not out_path.is_absolute():
        out_path = ROOT / out_path
    out_path.parent.mkdir(parents=True, exist_ok=True)
    out_path.write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
    print(json.dumps(result, ensure_ascii=False, indent=2))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
