#!/usr/bin/env python3
"""Emit a lab SuperGold Bingo 0x39 coverall synth from a captured template line.

Usage:
  python build_bingo_jpot_synth.py --template "05,39,01,38,D7,..."
  python build_bingo_jpot_synth.py --template-file packets.raw --line 17
  python build_bingo_jpot_synth.py --template-file packets.raw --line 17 --amount 748850

Default calls: Set A card 1 coverall (24 numbers + pad to 50).
Default progwinval: $7488.50 (748850 cents BE32 @ bytes 13–16).
"""

from __future__ import annotations

import argparse
import sys
from pathlib import Path

from pog422_fixture_core import (
    BINGO_LAB_DEFAULT_JPOT_CENTS,
    BINGO_RESULT_CALL_COUNT,
    BINGO_RESULT_CALL_OFFSET,
    PROGRESSIVE_ACTIVEWINS_OFFSET,
    bingo_calls_from_result,
    bingo_coverall_calls_from_grid,
    bingo_numbers_from_grid,
    BINGO_LAB_SETA_CARD1_GRID,
    build_bingo_jpot_synth,
    pog422_frame_checksum_ok,
    progressive_cents_to_dollars,
    progressive_progwin_cents_be,
    progressive_progdsp_cents_be,
)


def parse_hex_line(line: str) -> bytes:
    line = line.strip()
    if not line or line.startswith("#"):
        return b""
    return bytes(int(part, 16) for part in line.split(","))


def main() -> int:
    ap = argparse.ArgumentParser(description="Build lab Bingo 0x39 coverall synth")
    ap.add_argument("--template", help="Comma-hex captured 0x39 line")
    ap.add_argument("--template-file", type=Path, help="packets.raw or similar")
    ap.add_argument("--line", type=int, default=1, help="1-based line in template-file")
    ap.add_argument(
        "--amount",
        type=lambda s: int(s, 0),
        default=None,
        help=f"progwinval/progdsp BE32 cents (default {BINGO_LAB_DEFAULT_JPOT_CENTS})",
    )
    ap.add_argument(
        "--show-calls",
        action="store_true",
        help="Print default coverall call list only (no synth)",
    )
    args = ap.parse_args()

    if args.show_calls:
        card = bingo_numbers_from_grid(BINGO_LAB_SETA_CARD1_GRID)
        full = bingo_coverall_calls_from_grid(BINGO_LAB_SETA_CARD1_GRID)
        print(f"card_numbers ({len(card)}): {','.join(str(n) for n in card)}")
        print(f"coverall_calls ({len(full)}): {','.join(str(n) for n in full)}")
        return 0

    if args.template:
        template = parse_hex_line(args.template)
    elif args.template_file:
        lines = args.template_file.read_text(encoding="utf-8", errors="replace").splitlines()
        if args.line < 1 or args.line > len(lines):
            print(f"line {args.line} out of range (file has {len(lines)} lines)", file=sys.stderr)
            return 1
        template = parse_hex_line(lines[args.line - 1])
    else:
        ap.error("provide --template or --template-file")

    if not template:
        print("empty template", file=sys.stderr)
        return 1

    synth = build_bingo_jpot_synth(template, jpot_amount=args.amount)
    if synth is None:
        print("build_bingo_jpot_synth failed (need 74 B 0x39 template)", file=sys.stderr)
        return 1
    if not pog422_frame_checksum_ok(synth):
        print("checksum invalid after synth", file=sys.stderr)
        return 1

    calls = bingo_calls_from_result(synth)
    progwin = progressive_progwin_cents_be(synth)
    progdsp = progressive_progdsp_cents_be(synth)
    card = bingo_numbers_from_grid(BINGO_LAB_SETA_CARD1_GRID)

    print(",".join(f"{b:02X}" for b in synth))
    print(
        f"# active_wins={synth[PROGRESSIVE_ACTIVEWINS_OFFSET]} "
        f"progdsp=${progressive_cents_to_dollars(progdsp):.2f} "
        f"progwin=${progressive_cents_to_dollars(progwin):.2f} "
        f"calls={len(calls)}/{BINGO_RESULT_CALL_COUNT}",
        file=sys.stderr,
    )
    print(
        f"# card1_coverall_first24={','.join(str(n) for n in card)}",
        file=sys.stderr,
    )
    print(
        f"# calls@{BINGO_RESULT_CALL_OFFSET}="
        f"{','.join(str(n) for n in calls[:24])}...",
        file=sys.stderr,
    )
    return 0


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