/**
 * Реестр тайлей мира (трек 29, скины): слоты тайлей моделей локальны —
 * при штамповке opts.texRemap переводит их в глобальные id 1..255 этого
 * реестра. Тайли дедуплицируются по контенту: одинаковый пиксель-арт у
 * разных моделей (домов с разными сидами, манекенов разных персонажей)
 * занимает один id — реестр остаётся в пределах байта.
 */
import { resolveTiles } from '@rpg/engine';
import type { CloudTiles, VoxelModel, ResolvedTile } from '@rpg/engine';

/** Глобальные тайли мира: id → разрешённый тайль (вход атласа рендера). */
export const worldTiles: CloudTiles = {};

let nextId = 1;
const byKey = new Map<string, number>(); // ключ контента тайля → глобальный id
const remapCache = new Map<VoxelModel, (localId: number) => number>();

/** Ключ дедупликации: размер + грани (hex-пиксели resolveTiles). */
function tileKey(t: ResolvedTile): string {
    return `${t.size}|${t.faces.map((f) => f.join(',')).join(';')}`;
}

/** Переводчик локальных id тайлей модели → глобальные (кэшируется по модели). */
export function texRemapFor(model: VoxelModel): (localId: number) => number {
    let m = remapCache.get(model);
    if (!m) {
        const local = new Map<number, number>();
        for (const [k, t] of Object.entries(resolveTiles(model))) {
            const id = Number(k);
            if (id <= 0) continue; // 0 — плоский цвет, не тайль
            const key = tileKey(t);
            let gid = byKey.get(key);
            if (gid === undefined) {
                if (nextId > 255) throw new Error('Реестр тайлей мира переполнен (>255)');
                gid = nextId++;
                worldTiles[gid] = t;
                byKey.set(key, gid);
            }
            local.set(id, gid);
        }
        m = (lid) => local.get(lid) ?? 0; // незарегистрированный — плоский цвет
        remapCache.set(model, m);
    }
    return m;
}