#!/usr/bin/env python3
"""
从 Unity Assets/Tile/{theme}.prefab + Assets/Texture/{theme} 生成 Cocos 调色板配置。
对齐 Unity 平铺调色板（如 sanxing：WallBlock / JumpBlock / Baseblock / kuai11）。
"""
from __future__ import annotations

import json
import re
from pathlib import Path

# Unity 目录名 → Cocos / GameController 主题名
THEMES = {
    "SILU": "silu",
    "snow": "snow",
    "sanxing": "sanxing",
    "Chinese": "chinese",
    "numMan": "numMan",
    "redArmy": "redarmy",
    "RED": "redArmy",
    "Level": "default",
}

GROUND_NAMES = {"Baseblock", "JumpBlock"}
BORDER_NAMES = {"WallBlock", "kuai11", "Decor23", "素材切图-23", "素材切图2-23", "小游戏素材红色_03"}


def parse_palette_guids(prefab_text: str) -> list[str]:
    guids: list[str] = []
    in_array = False
    for line in prefab_text.splitlines():
        if "m_TileAssetArray:" in line:
            in_array = True
            continue
        if in_array and "m_TileSpriteArray:" in line:
            break
        if in_array and "guid:" in line:
            m = re.search(r"guid: ([a-f0-9]+)", line)
            if m:
                guids.append(m.group(1))
    return guids


def read_meta_guid(meta_path: Path) -> str | None:
    try:
        for line in meta_path.read_text(encoding="utf-8").splitlines():
            if line.startswith("guid:"):
                return line.split(":", 1)[1].strip()
    except Exception:
        pass
    return None


def guid_to_tile_name(theme_dir: Path, guid: str) -> str | None:
    if not theme_dir.is_dir():
        return None
    for meta in theme_dir.glob("*.asset.meta"):
        if read_meta_guid(meta) == guid:
            return meta.name.replace(".asset.meta", "")
    return None


def build_theme(unity_root: Path, unity_folder: str, cocos_key: str) -> dict | None:
    tile_prefab = unity_root / "Assets" / "Tile" / f"{unity_folder}.prefab"
    tex_dir = unity_root / "Assets" / "Texture" / unity_folder
    if unity_folder == "Level":
        tex_dir = unity_root / "Assets" / "Texture"
    if not tile_prefab.is_file():
        return None
    guids = parse_palette_guids(tile_prefab.read_text(encoding="utf-8"))
    tiles = []
    for i, g in enumerate(guids):
        name = guid_to_tile_name(tex_dir, g)
        if not name:
            continue
        layer = "ground" if name in GROUND_NAMES else "border"
        tex_rel = f"textures/{cocos_key}/{name}"
        if cocos_key == "default":
            tex_rel = f"textures/default/{name}"
        tiles.append(
            {
                "display": name,
                "layer": layer,
                "tileKey": name,
                "texture": tex_rel,
                "unityIndex": i,
            }
        )
    return {"displayName": cocos_key, "tiles": tiles}


def main():
    import argparse

    ap = argparse.ArgumentParser()
    ap.add_argument("--unity-root", required=True)
    ap.add_argument("--out", default="assets/resources/map-tiles/palettes")
    args = ap.parse_args()

    project = Path(__file__).resolve().parent.parent
    unity_root = Path(args.unity_root)
    out_dir = project / args.out
    out_dir.mkdir(parents=True, exist_ok=True)

    all_themes: dict[str, dict] = {}
    for unity_folder, cocos_key in THEMES.items():
        t = build_theme(unity_root, unity_folder, cocos_key)
        if not t or not t["tiles"]:
            print(f"  skip {unity_folder}")
            continue
        all_themes[cocos_key] = t
        (out_dir / f"{cocos_key}.json").write_text(
            json.dumps(t, indent=2, ensure_ascii=False), encoding="utf-8"
        )
        print(f"  {cocos_key}: {len(t['tiles'])} tiles")

    (out_dir / "_index.json").write_text(
        json.dumps({"themes": all_themes}, indent=2, ensure_ascii=False), encoding="utf-8"
    )
    print(f"Wrote -> {out_dir}")


if __name__ == "__main__":
    main()
