from __future__ import annotations

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


def _rows(path: Path) -> list[dict[str, Any]]:
    if not path.exists():
        return []
    result = []
    for line in path.read_text(encoding="utf-8", errors="replace").splitlines():
        try:
            row = json.loads(line)
            if isinstance(row, dict):
                result.append(row)
        except json.JSONDecodeError:
            continue
    return result


def _key(row: dict[str, Any], window_field: str) -> tuple[str, str]:
    return str(row.get(window_field) or ""), str(row.get("coin") or "").upper()


def build_report(runtime_dir: str | Path) -> dict[str, Any]:
    runtime = Path(runtime_dir)
    shadow = _rows(runtime / "maker_taker_shadow_journal.jsonl")
    market = _rows(runtime / "trade_journal.jsonl")
    submitted = [r for r in shadow if r.get("event") == "maker_pending"]
    fills = [r for r in shadow if r.get("event") == "maker_fill"]
    cancels = [r for r in shadow if r.get("event") == "maker_cancel"]
    maker_exits = {_key(r, "source_window_id"): r for r in shadow if r.get("event") == "maker_exit"}
    market_exits = {_key(r, "data_window_id"): r for r in market if r.get("event") == "exit"}
    matched = sorted(set(maker_exits) & set(market_exits))
    maker_net = sum((Decimal(str(maker_exits[k].get("net_pnl_usd") or 0)) for k in matched), Decimal("0"))
    market_net = sum((Decimal(str(market_exits[k].get("net_pnl_usd") or 0)) for k in matched), Decimal("0"))
    fill_rate = Decimal(len(fills)) / Decimal(len(submitted)) * Decimal("100") if submitted else Decimal("0")
    return {
        "schema_version": "maker_taker_shadow_report.v1",
        "submitted": len(submitted),
        "filled": len(fills),
        "cancelled": len(cancels),
        "fill_rate_pct": str(fill_rate),
        "maker_completed": len(maker_exits),
        "matched_completed": len(matched),
        "maker_net_pnl_usd": str(maker_net),
        "market_net_pnl_usd": str(market_net),
        "maker_advantage_usd": str(maker_net - market_net),
        "maker_fee_rate_assumption": "0.00015",
        "market_entry_model": "market_taker",
        "maker_entry_model": "limit_Alo_future_touch_max_2_bars",
        "exit_model": "market_taker",
        "paper_research_only": True,
        "execution_allowed": False,
        "live_order_allowed": False,
        "mainnet_signed_action": False,
    }


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--runtime-dir", required=True)
    parser.add_argument("--json", action="store_true")
    args = parser.parse_args(argv)
    report = build_report(args.runtime_dir)
    output = Path(args.runtime_dir) / "maker_taker_shadow_report_latest.json"
    output.write_text(json.dumps(report, indent=2, sort_keys=True), encoding="utf-8")
    if args.json:
        print(json.dumps(report, sort_keys=True))
    return 0


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