from __future__ import annotations

import argparse
import datetime as dt
import json
from pathlib import Path
from typing import Any


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


def _as_obj(value: Any) -> dict[str, Any]:
    if isinstance(value, dict):
        return value
    if isinstance(value, str):
        try:
            parsed = json.loads(value)
            return parsed if isinstance(parsed, dict) else {}
        except Exception:
            return {}
    return {}


def _as_rows(value: Any) -> list[dict[str, Any]]:
    if isinstance(value, list):
        return [v for v in value if isinstance(v, dict)]
    if isinstance(value, str):
        try:
            parsed = json.loads(value)
            return _as_rows(parsed)
        except Exception:
            return []
    return []


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


def _safe_bool(v: Any, default: bool = False) -> bool:
    if isinstance(v, bool):
        return v
    if isinstance(v, (int, float)):
        return bool(v)
    if isinstance(v, str):
        return v.strip().lower() in ("1", "true", "y", "yes")
    return default


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()

    json_path = Path(args.json)
    if not json_path.is_absolute():
        json_path = ROOT / json_path
    out_path = Path(args.out)
    if not out_path.is_absolute():
        out_path = ROOT / out_path

    payload = _load_json(json_path)
    if not payload:
        print("STRATEGY_DECISION_V3_FAIL: input json missing/invalid")
        return 1

    data = _as_obj(payload.get("data"))
    apex = _as_obj(payload.get("hApex"))
    hctx = _as_obj(data.get("_harness_context"))
    h = dict(hctx)
    h.update(apex)

    export_gate_obj = _as_obj(h.get("export_gate_json"))
    export_allowed = export_gate_obj.get("hts_entry_allowed")
    if export_allowed is True:
        export_gate = "PASS"
    elif export_allowed is False:
        export_gate = "BLOCKED"
    else:
        export_gate = "REVIEW_ONLY"

    blueprint = _as_rows(h.get("order_blueprint_json"))
    shadow = [row for row in blueprint if str(row.get("validation_status", "")).upper() != "PASS"]

    oq_obj = _as_obj(h.get("outcome_quality_score_v1_json"))
    oq_gate = str(oq_obj.get("gate") or "")
    buy_allowed = export_allowed is True and oq_gate != "CRITICAL_MODE"
    sell_allowed = "ALLOW" if export_allowed is True else "REVIEW_ONLY"

    out = {
        "schema_version": "strategy-decision-result-v3",
        "as_of": dt.datetime.now(dt.timezone.utc).isoformat(),
        "source_truth": {
            "price_basis": "HARNESS_ONLY",
            "cash_basis": "D_PLUS_2"
        },
        "route": {
            "route_id": str(h.get("request_route") or "PIPELINE_EOD_BATCH"),
            "serving_mode": "JSON_ONLY_LLM_EXPLAIN"
        },
        "global_gates": {
            "export_gate": export_gate,
            "llm_numeric_generation_allowed": False
        },
        "portfolio_decision": {
            "buy_allowed": _safe_bool(buy_allowed, False),
            "sell_allowed": sell_allowed
        },
        "order_blueprint": blueprint,
        "shadow_ledger": shadow,
        "audit_ledger": [
            {
                "formula_id": "STRATEGY_DECISION_RESULT_V3",
                "source_json": str(json_path.name),
                "blueprint_rows": len(blueprint),
                "shadow_rows": len(shadow)
            }
        ]
    }

    out_path.parent.mkdir(parents=True, exist_ok=True)
    out_path.write_text(json.dumps(out, ensure_ascii=False, indent=2), encoding="utf-8")
    print(f"STRATEGY_DECISION_V3_OK: {out_path}")
    return 0


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