from __future__ import annotations

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


ROOT = Path(__file__).resolve().parents[1]
DEFAULT_JSON = ROOT / "GatherTradingData.json"
DEFAULT_REPORT = ROOT / "Temp" / "operational_report.md"


def load_json(path: Path) -> dict[str, Any]:
    payload = json.loads(path.read_text(encoding="utf-8"))
    if not isinstance(payload, dict):
        raise ValueError("json payload must be object")
    return payload


def extract_section(text: str, heading: str) -> str:
    marker = f"## {heading}"
    idx = text.find(marker)
    if idx < 0:
        return ""
    tail = text[idx:]
    m = re.search(r"\n##\s+", tail[1:])
    return tail if not m else tail[: m.start() + 1]


def parse_md_rows(section: str) -> list[list[str]]:
    rows: list[list[str]] = []
    for line in section.splitlines():
        if not line.strip().startswith("|"):
            continue
        rows.append([c.strip() for c in line.strip().strip("|").split("|")])
    if len(rows) <= 2:
        return []
    return rows[2:]


def text(v: Any) -> str:
    return str(v or "").strip()


def main() -> int:
    parser = argparse.ArgumentParser(description="Validate satellite buy proposal sheet consistency.")
    parser.add_argument("--json", default=str(DEFAULT_JSON))
    parser.add_argument("--report", default=str(DEFAULT_REPORT))
    args = parser.parse_args()

    json_path = Path(args.json)
    report_path = Path(args.report)
    if not json_path.is_absolute():
        json_path = ROOT / json_path
    if not report_path.is_absolute():
        report_path = ROOT / report_path

    payload = load_json(json_path)
    report = report_path.read_text(encoding="utf-8")
    section = extract_section(report, "위성 신규 매수 제안 원장")
    if not section:
        print("SATELLITE_PROPOSAL_SHEET_FAIL: section missing")
        return 1

    required_headers = [
        "종목",
        "추천상태",
        "기준지정가(원)",
        "기준손절가(원)",
        "기준익절가1(원)",
        "기준수량(주)",
        "진입점수",
        "익일위험점수",
        "매도충돌점수",
        "추천사유(정량근거)",
    ]
    for h in required_headers:
        if h not in section:
            print(f"SATELLITE_PROPOSAL_SHEET_FAIL: missing header {h}")
            return 1

    data = payload.get("data") if isinstance(payload.get("data"), dict) else {}
    core = [r for r in (data.get("core_satellite") or []) if isinstance(r, dict)]
    core_with_state = [r for r in core if text(r.get("Execution_Recommendation_State"))]
    md_rows = parse_md_rows(section)

    if not md_rows:
        print("SATELLITE_PROPOSAL_SHEET_FAIL: no data rows")
        return 1
    if len(md_rows) < min(1, len(core_with_state)):
        print(f"SATELLITE_PROPOSAL_SHEET_FAIL: insufficient rows md={len(md_rows)} core={len(core_with_state)}")
        return 1

    # 최소 검증: 보고서에 core_satellite 종목코드가 최소 1개 이상 반영되어야 함
    tickers = {text(r.get("Ticker")) for r in core_with_state if text(r.get("Ticker"))}
    section_tickers = {row[0] for row in md_rows if row and row[0] and row[0] != "-"}
    if not (tickers & section_tickers):
        print("SATELLITE_PROPOSAL_SHEET_FAIL: no overlapping tickers with core_satellite")
        return 1

    print(f"SATELLITE_PROPOSAL_SHEET_OK: rows_md={len(md_rows)} overlap={len(tickers & section_tickers)}")
    return 0


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