"""POG422 Draw Poker card wire codec (calibrated 2026-07-02 bench).

Wire byte = rank_base + suit_delta (single byte per card).

rank_base: A=0x01, 2=0x02 … 9=0x09, 10=0x0A, J=0x0B, Q=0x0C, K=0x0D
suit_delta: H=0x00, C=0x10, D=0x20, S=0x30

0x59 34-byte frame card region (SOH-indexed):
  byte 19-20  deck marker (0xF3 + per-hand counter)
  byte 21-25  initial deal (5 cards)
  byte 26-30  draw-pile (next 5 cards from shoe; fill discard slots in order)
"""

from __future__ import annotations

RANKS = ("2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A")
SUITS = ("H", "D", "C", "S")

RANK_BASE: dict[str, int] = {
    "A": 0x01,
    "2": 0x02,
    "3": 0x03,
    "4": 0x04,
    "5": 0x05,
    "6": 0x06,
    "7": 0x07,
    "8": 0x08,
    "9": 0x09,
    "10": 0x0A,
    "J": 0x0B,
    "Q": 0x0C,
    "K": 0x0D,
}

SUIT_DELTA: dict[str, int] = {
    "H": 0x00,
    "C": 0x10,
    "D": 0x20,
    "S": 0x30,
}

POKER_CARD_DEAL_START = 21
POKER_CARD_DRAW_START = 26
POKER_CARD_COUNT = 5


def card_to_wire(rank: str, suit: str) -> int:
    return RANK_BASE[rank] + SUIT_DELTA[suit]


def wire_to_card(wire: int) -> tuple[str, str] | None:
    for suit, delta in SUIT_DELTA.items():
        base = wire - delta
        if base in RANK_BASE.values():
            for rank, rb in RANK_BASE.items():
                if rb == base:
                    return rank, suit
    return None


def wire_to_label(wire: int) -> str:
    parsed = wire_to_card(wire)
    if parsed:
        rank, suit = parsed
        return f"{rank}{suit}"
    return f"0x{wire:02X}?"


def build_wire_maps() -> tuple[dict[int, tuple[str, str]], dict[tuple[str, str], int]]:
    wire_to: dict[int, tuple[str, str]] = {}
    card_to: dict[tuple[str, str], int] = {}
    for rank in RANKS:
        for suit in SUITS:
            w = card_to_wire(rank, suit)
            wire_to[w] = (rank, suit)
            card_to[(rank, suit)] = w
    return wire_to, card_to
