#-----------------------------------------------------------------------------------------------------------------------
# Build `Assets/Shared/3840x1080/layout.json` from `Assets/Shared/1920x1080/layout.json`.
#
# 32:9 is NOT "2× every X". The frame moves to the right (653, 0) and is full-height.
# We take 1920 *screen* slot positions (after display_scale) and shift them by the frame delta.
#
#   python ohd_scale_layout.py
#-----------------------------------------------------------------------------------------------------------------------
import argparse
import json
import os
from typing import Any, Dict, List

from ohd_layout import (
    RESOLUTION_1920,
    RESOLUTION_3840,
    default_shared_layout_path,
    load_layout,
    save_layout,
)

# Progressive frame PNG sizes (for anchor + strip scaling).
FRAME_ANCHOR_1920 = (24, 524)
FRAME_ANCHOR_3840 = (653, 0)
FRAME_DX = FRAME_ANCHOR_3840[0] - FRAME_ANCHOR_1920[0]
FRAME_DY = FRAME_ANCHOR_3840[1] - FRAME_ANCHOR_1920[1]

STRIP_W_1920 = 196
STRIP_H_1920 = 4119
STRIP_W_3840 = 227
STRIP_H_3840 = 5141
STRIP_X_SCALE = STRIP_W_3840 / STRIP_W_1920
STRIP_Y_SCALE = STRIP_H_3840 / STRIP_H_1920


def _shift_slot(slot: Dict[str, Any]) -> Dict[str, Any]:
    out = dict(slot)
    out["x"] = int(round(out["x"] + FRAME_DX))
    out["y"] = int(round(out["y"] + FRAME_DY))
    return out


def _scale_strip_cells(cells: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
    scaled = []
    for cell in cells:
        c = dict(cell)
        c["x"] = int(round(c["x"] * STRIP_X_SCALE))
        c["y"] = int(round(c["y"] * STRIP_Y_SCALE))
        c["w"] = int(round(c["w"] * STRIP_X_SCALE))
        c["h"] = int(round(c["h"] * STRIP_Y_SCALE))
        if c["w"] > STRIP_W_3840:
            c["w"] = STRIP_W_3840
        scaled.append(c)
    return scaled


def layout_1920_to_3840(src_path: str, game_id: int = 1) -> Dict[str, Any]:
    """Convert tuned 1920 layout → 3840 screen coords (display_scale 1.0 in file)."""
    assets_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(src_path))))
    layout = load_layout(RESOLUTION_1920, game_id, assets_root=assets_root)

    with open(src_path, encoding="utf-8") as f:
        raw = json.load(f)

    digit_slots = [_shift_slot(s.to_json()) for s in layout.digit_slots]
    symbol_slots = [_shift_slot(s.to_json()) for s in layout.symbol_slots]

    if layout.digit_slots:
        cell_w = layout.digit_slots[0].w
        cell_h = layout.digit_slots[0].h
        if not layout.scale_slot_positions and layout.display_scale > 1.0:
            cell_w = max(cell_w, int(round(layout.digit_cell_w * layout.display_scale)))
            cell_h = max(cell_h, int(round(layout.digit_cell_h * layout.display_scale)))
    else:
        cell_w, cell_h = 180, 240

    doc: Dict[str, Any] = {
        "resolution": RESOLUTION_3840,
        "screen": [3840, 1080],
        "frame_anchor": list(FRAME_ANCHOR_3840),
        "display_scale": float(raw.get("display_scale", 1.0)),
        "digit_cell": {"w": cell_w, "h": cell_h},
        "digit_strip": {
            "orientation": raw.get("digit_strip", {}).get("orientation", "vertical"),
            "digit_order": raw.get("digit_strip", {}).get("digit_order", "0_at_top"),
            "cells": _scale_strip_cells(raw.get("digit_strip", {}).get("cells", [])),
        },
        "digit_slots": digit_slots,
        "symbol_slots": symbol_slots,
    }
    for key in (
        "horizontal_scale",
        "column_spacing_scale",
        "digit_baseline_y",
        "digit_top_y",
        "scale_slot_positions",
        "use_template_screen_coords",
    ):
        if key in raw:
            doc[key] = raw[key]
    if raw.get("odometer"):
        doc["odometer"] = raw["odometer"]
    ac = raw.get("aligned_cells")
    if isinstance(ac, dict):
        shifted = dict(ac)
        if shifted.get("anchor_right") is not None:
            shifted["anchor_right"] = int(shifted["anchor_right"]) + FRAME_DX
        if shifted.get("anchor_bottom") is not None:
            shifted["anchor_bottom"] = int(shifted["anchor_bottom"]) + FRAME_DY
        doc["aligned_cells"] = shifted
    return doc


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--src", default=None, help="Source 1920 shared `layout.json`")
    args = parser.parse_args()

    src = args.src or default_shared_layout_path(RESOLUTION_1920)
    if not os.path.isfile(src):
        print(f"Missing source layout: {src}")
        return 1
    scaled = layout_1920_to_3840(src)

    out_path = default_shared_layout_path(RESOLUTION_3840)
    os.makedirs(os.path.dirname(out_path), exist_ok=True)
    with open(out_path, "w", encoding="utf-8") as f:
        json.dump(scaled, f, indent=2)
        f.write("\n")
    print(f"Wrote: {out_path}")
    print(f"  frame_anchor={scaled['frame_anchor']}  display_scale={scaled['display_scale']}")
    if scaled["digit_slots"]:
        d0 = scaled["digit_slots"][0]
        d7 = scaled["digit_slots"][-1]
        print(f"  digits x: {d7['x']} .. {d0['x']}  y={d0['y']}  cell={scaled['digit_cell']}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
