import { Component, ECSComponent, Serializable, Serialize, Property } from '@esengine/ecs-framework';
import type { IResourceComponent, ResourceReference } from '@esengine/asset-system';
import { UVHelper } from '@esengine/asset-system';

/**
 * Resize anchor point for tilemap expansion
 * 瓦片地图扩展的锚点位置
 */
export type ResizeAnchor =
    | 'top-left' | 'top-center' | 'top-right'
    | 'middle-left' | 'center' | 'middle-right'
    | 'bottom-left' | 'bottom-center' | 'bottom-right';

/**
 * Tileset data interface
 * 图块集数据接口
 */
export interface ITilesetData {
    /** Tileset name | 图块集名称 */
    name: string;
    /** Data format version | 数据格式版本 */
    version: number;
    /** Image file path | 图片文件路径 */
    image: string;
    /** Image width in pixels | 图片宽度（像素） */
    imageWidth: number;
    /** Image height in pixels | 图片高度（像素） */
    imageHeight: number;
    /** Single tile width in pixels | 单个图块宽度（像素） */
    tileWidth: number;
    /** Single tile height in pixels | 单个图块高度（像素） */
    tileHeight: number;
    /** Total number of tiles | 图块总数 */
    tileCount: number;
    /** Number of tile columns | 图块列数 */
    columns: number;
    /** Number of tile rows | 图块行数 */
    rows: number;
    /** Margin around tileset in pixels | 图块集边距（像素） */
    margin?: number;
    /** Spacing between tiles in pixels | 图块间距（像素） */
    spacing?: number;
    /** Individual tile metadata | 单个图块元数据 */
    tiles?: Array<{
        id: number;
        type?: string;
        properties?: Record<string, unknown>;
    }>;
}

/**
 * Layer data interface
 * 图层数据接口
 */
export interface ITilemapLayerData {
    /** Unique layer identifier | 图层唯一标识符 */
    id: string;
    /** Layer display name | 图层显示名称 */
    name: string;
    /** Layer visibility | 图层可见性 */
    visible: boolean;
    /** Layer opacity (0-1) | 图层不透明度（0-1） */
    opacity: number;
    /** Tile index data array (row-major order) | 图块索引数据数组（行优先顺序） */
    data: number[];
    /** Default tileset index for this layer | 此图层的默认图块集索引 */
    tilesetIndex?: number;
    /** Layer X offset in pixels | 图层X偏移（像素） */
    offsetX?: number;
    /** Layer Y offset in pixels | 图层Y偏移（像素） */
    offsetY?: number;
    /** Custom layer properties | 自定义图层属性 */
    properties?: Record<string, unknown>;
}

/**
 * Tileset reference info
 * 图块集引用信息
 */
export interface ITilesetRef {
    /** Tileset image source path | 图块集图片源路径 */
    source: string;
    /** First global tile ID for this tileset | 此图块集的第一个全局图块ID */
    firstGid: number;
    /** Loaded tileset data | 已加载的图块集数据 */
    data?: ITilesetData;
    /** GPU texture ID for rendering | 用于渲染的GPU纹理ID */
    textureId?: number;
}

/**
 * Tilemap data interface
 * 瓦片地图数据接口
 */
export interface ITilemapData {
    /** Tilemap name | 瓦片地图名称 */
    name: string;
    /** Data format version | 数据格式版本 */
    version: number;
    /** Map width in tiles | 地图宽度（图块数） */
    width: number;
    /** Map height in tiles | 地图高度（图块数） */
    height: number;
    /** Single tile width in pixels | 单个图块宽度（像素） */
    tileWidth: number;
    /** Single tile height in pixels | 单个图块高度（像素） */
    tileHeight: number;
    /** Array of tileset references | 图块集引用数组 */
    tilesets: ITilesetRef[];
    /** Array of layer data | 图层数据数组 */
    layers: ITilemapLayerData[];
    /** Collision data array | 碰撞数据数组 */
    collisionData?: number[];
    /** Custom tilemap properties | 自定义瓦片地图属性 */
    properties?: Record<string, unknown>;
}

/**
 * Tilemap Component - Manages tile-based 2D map rendering
 * 瓦片地图组件 - 管理基于瓦片的2D地图渲染
 */
@ECSComponent('Tilemap')
@Serializable({ version: 2, typeId: 'Tilemap' })
export class TilemapComponent extends Component implements IResourceComponent {
    /** Tilemap asset GUID reference | 瓦片地图资源GUID引用 */
    @Serialize()
    @Property({ type: 'asset', label: 'Tilemap', extensions: ['.tilemap', '.tilemap.json'] })
    public tilemapAssetGuid: string = '';

    @Serialize()
    private _width: number = 10;

    @Serialize()
    private _height: number = 10;

    /** Map width in tiles | 地图宽度（图块数） */
    @Property({ type: 'integer', label: 'Width (Tiles)', min: 1 })
    public get width(): number {
        return this._width;
    }

    public set width(value: number) {
        if (value !== this._width && value > 0) {
            this.resize(value, this._height);
        }
    }

    /** Map height in tiles | 地图高度（图块数） */
    @Property({ type: 'integer', label: 'Height (Tiles)', min: 1 })
    public get height(): number {
        return this._height;
    }

    public set height(value: number) {
        if (value !== this._height && value > 0) {
            this.resize(this._width, value);
        }
    }

    /** Single tile width in pixels | 单个图块宽度（像素） */
    @Serialize()
    @Property({ type: 'integer', label: 'Tile Width', min: 1 })
    public tileWidth: number = 32;

    /** Single tile height in pixels | 单个图块高度（像素） */
    @Serialize()
    @Property({ type: 'integer', label: 'Tile Height', min: 1 })
    public tileHeight: number = 32;

    /** Component visibility | 组件可见性 */
    @Serialize()
    @Property({ type: 'boolean', label: 'Visible' })
    public visible: boolean = true;

    /** Rendering sort order | 渲染排序顺序 */
    @Serialize()
    @Property({ type: 'integer', label: 'Sorting Order' })
    public sortingOrder: number = 0;

    /** Tint color in hex format | 着色颜色（十六进制格式） */
    @Serialize()
    @Property({ type: 'color', label: 'Color' })
    public color: string = '#ffffff';

    /** Opacity value (0-1) | 不透明度（0-1） */
    @Serialize()
    @Property({ type: 'number', label: 'Alpha', min: 0, max: 1, step: 0.01 })
    public alpha: number = 1;

    /** Flag indicating render data needs update | 标记渲染数据需要更新 */
    public renderDirty: boolean = true;

    // ===== 多Tileset =====

    @Serialize()
    private _tilesets: ITilesetRef[] = [];

    private _tilesetsData: Map<number, ITilesetData> = new Map();

    // ===== 多图层 =====

    @Serialize()
    private _layers: ITilemapLayerData[] = [];

    private _layersData: Map<string, Uint32Array> = new Map();

    @Serialize()
    private _activeLayerIndex: number = 0;

    // ===== 碰撞数据 =====

    @Serialize()
    private _collisionDataArray: number[] = [];

    private _collisionData: Uint32Array = new Uint32Array(0);

    // ===== Getters =====

    /** All tileset references | 所有图块集引用 */
    get tilesets(): readonly ITilesetRef[] {
        return this._tilesets;
    }

    /** All layer data | 所有图层数据 */
    get layers(): readonly ITilemapLayerData[] {
        return this._layers;
    }

    /** Current active layer index | 当前活动图层索引 */
    get activeLayerIndex(): number {
        return this._activeLayerIndex;
    }

    set activeLayerIndex(value: number) {
        if (value >= 0 && value < this._layers.length) {
            this._activeLayerIndex = value;
        }
    }

    /** Current active layer data | 当前活动图层数据 */
    get activeLayer(): ITilemapLayerData | undefined {
        return this._layers[this._activeLayerIndex];
    }

    /** Total map width in pixels | 地图总宽度（像素） */
    get pixelWidth(): number {
        return this._width * this.tileWidth;
    }

    /** Total map height in pixels | 地图总高度（像素） */
    get pixelHeight(): number {
        return this._height * this.tileHeight;
    }

    /** Raw collision data array | 原始碰撞数据数组 */
    get collisionData(): Uint32Array {
        return this._collisionData;
    }

    // ===== Initialization | 初始化 =====

    /**
     * Initialize an empty tilemap with default layer
     * 初始化一个带有默认图层的空瓦片地图
     * @param width Map width in tiles | 地图宽度（图块数）
     * @param height Map height in tiles | 地图高度（图块数）
     */
    initializeEmpty(width: number, height: number): void {
        this._width = width;
        this._height = height;

        const defaultLayer: ITilemapLayerData = {
            id: 'default',
            name: 'Layer 0',
            visible: true,
            opacity: 1,
            data: new Array(width * height).fill(0)
        };
        this._layers = [defaultLayer];
        this._layersData.set('default', new Uint32Array(width * height));
        this._activeLayerIndex = 0;

        this.renderDirty = true;
    }

    /**
     * Apply tilemap data from external source
     * 从外部数据源应用瓦片地图数据
     * @param data Tilemap data to apply | 要应用的瓦片地图数据
     */
    applyTilemapData(data: ITilemapData): void {
        this._width = data.width;
        this._height = data.height;
        this.tileWidth = data.tileWidth;
        this.tileHeight = data.tileHeight;

        // 加载Tilesets
        this._tilesets = data.tilesets.map((ts) => ({ ...ts }));
        this._tilesetsData.clear();

        // 加载图层
        this._layers = data.layers.map((layer) => ({
            ...layer,
            data: [...layer.data]
        }));
        this._layersData.clear();
        for (const layer of this._layers) {
            this._layersData.set(layer.id, new Uint32Array(layer.data));
        }

        // 加载碰撞数据
        if (data.collisionData) {
            this._collisionData = new Uint32Array(data.collisionData);
            this._collisionDataArray = [...data.collisionData];
        } else {
            this._collisionData = new Uint32Array(0);
            this._collisionDataArray = [];
        }

        this.renderDirty = true;
    }

    // ===== Tileset Methods | 图块集方法 =====

    /**
     * Add a new tileset reference
     * 添加新的图块集引用
     * @param source Tileset image source path | 图块集图片源路径
     * @param firstGid Optional first global tile ID | 可选的第一个全局图块ID
     * @returns Index of the added tileset | 添加的图块集索引
     */
    addTileset(source: string, firstGid?: number): number {
        const gid = firstGid ?? this.calculateNextFirstGid();
        this._tilesets.push({ source, firstGid: gid });
        this.renderDirty = true;
        return this._tilesets.length - 1;
    }

    /**
     * Remove a tileset by index
     * 按索引移除图块集
     * @param index Tileset index to remove | 要移除的图块集索引
     */
    removeTileset(index: number): void {
        if (index >= 0 && index < this._tilesets.length) {
            this._tilesets.splice(index, 1);
            this._tilesetsData.delete(index);
            this.renderDirty = true;
        }
    }

    /**
     * Set tileset data for a specific index
     * 设置指定索引的图块集数据
     * @param index Tileset index | 图块集索引
     * @param data Tileset data to set | 要设置的图块集数据
     */
    setTilesetData(index: number, data: ITilesetData): void {
        if (index >= 0 && index < this._tilesets.length) {
            this._tilesets[index].data = data;
            this._tilesetsData.set(index, data);
            this.renderDirty = true;
        }
    }

    /**
     * Get tileset data by index
     * 按索引获取图块集数据
     * @param index Tileset index | 图块集索引
     * @returns Tileset data or undefined | 图块集数据或undefined
     */
    getTilesetData(index: number): ITilesetData | undefined {
        return this._tilesetsData.get(index) || this._tilesets[index]?.data;
    }

    /**
     * Find tileset for a global tile ID
     * 根据全局图块ID查找图块集
     * @param gid Global tile ID | 全局图块ID
     * @returns Tileset info with local ID, or null if not found | 包含本地ID的图块集信息，未找到返回null
     */
    getTilesetForGid(gid: number): { tileset: ITilesetRef; localId: number; index: number } | null {
        if (gid <= 0) return null;

        for (let i = this._tilesets.length - 1; i >= 0; i--) {
            const tileset = this._tilesets[i];
            if (gid >= tileset.firstGid) {
                return {
                    tileset,
                    localId: gid - tileset.firstGid + 1,
                    index: i
                };
            }
        }
        return null;
    }

    private calculateNextFirstGid(): number {
        if (this._tilesets.length === 0) return 1;

        let maxGid = 1;
        for (const tileset of this._tilesets) {
            const tileCount = tileset.data?.tileCount || 256;
            const nextGid = tileset.firstGid + tileCount;
            if (nextGid > maxGid) maxGid = nextGid;
        }
        return maxGid;
    }

    // ===== Layer Methods | 图层方法 =====

    /**
     * Add a new layer to the tilemap
     * 向瓦片地图添加新图层
     * @param name Optional layer name | 可选的图层名称
     * @param index Optional insertion index | 可选的插入索引
     * @returns The created layer data | 创建的图层数据
     */
    addLayer(name?: string, index?: number): ITilemapLayerData {
        const id = `layer_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
        const layerName = name || `Layer ${this._layers.length}`;
        const data = new Array(this._width * this._height).fill(0);

        const layer: ITilemapLayerData = {
            id,
            name: layerName,
            visible: true,
            opacity: 1,
            data
        };

        if (index !== undefined && index >= 0 && index <= this._layers.length) {
            this._layers.splice(index, 0, layer);
        } else {
            this._layers.push(layer);
        }

        this._layersData.set(id, new Uint32Array(data));
        this.renderDirty = true;
        return layer;
    }

    /**
     * Remove a layer by index (cannot remove last layer)
     * 按索引移除图层（不能移除最后一个图层）
     * @param index Layer index to remove | 要移除的图层索引
     */
    removeLayer(index: number): void {
        if (index >= 0 && index < this._layers.length && this._layers.length > 1) {
            const layer = this._layers[index];
            this._layers.splice(index, 1);
            this._layersData.delete(layer.id);

            if (this._activeLayerIndex >= this._layers.length) {
                this._activeLayerIndex = this._layers.length - 1;
            }

            this.renderDirty = true;
        }
    }

    /**
     * Move a layer from one position to another
     * 将图层从一个位置移动到另一个位置
     * @param fromIndex Source index | 源索引
     * @param toIndex Target index | 目标索引
     */
    moveLayer(fromIndex: number, toIndex: number): void {
        if (
            fromIndex >= 0 &&
            fromIndex < this._layers.length &&
            toIndex >= 0 &&
            toIndex < this._layers.length &&
            fromIndex !== toIndex
        ) {
            const [layer] = this._layers.splice(fromIndex, 1);
            this._layers.splice(toIndex, 0, layer);
            this.renderDirty = true;
        }
    }

    /**
     * Get layer data by index
     * 按索引获取图层数据
     */
    getLayer(index: number): ITilemapLayerData | undefined {
        return this._layers[index];
    }

    /**
     * Get layer data by ID
     * 按ID获取图层数据
     */
    getLayerById(id: string): ITilemapLayerData | undefined {
        return this._layers.find((l) => l.id === id);
    }

    /**
     * Set layer visibility
     * 设置图层可见性
     */
    setLayerVisible(index: number, visible: boolean): void {
        if (index >= 0 && index < this._layers.length) {
            this._layers[index].visible = visible;
            this.renderDirty = true;
        }
    }

    /**
     * Set layer opacity
     * 设置图层不透明度
     */
    setLayerOpacity(index: number, opacity: number): void {
        if (index >= 0 && index < this._layers.length) {
            this._layers[index].opacity = Math.max(0, Math.min(1, opacity));
            this.renderDirty = true;
        }
    }

    /**
     * Rename a layer
     * 重命名图层
     */
    renameLayer(index: number, name: string): void {
        if (index >= 0 && index < this._layers.length) {
            this._layers[index].name = name;
        }
    }

    // ===== Tile Operations | 瓦片操作 =====

    /**
     * Get tile index at position
     * 获取指定位置的图块索引
     * @param layerIndex Layer index | 图层索引
     * @param col Column (X) | 列（X）
     * @param row Row (Y) | 行（Y）
     * @returns Tile index (0 = empty) | 图块索引（0表示空）
     */
    getTile(layerIndex: number, col: number, row: number): number {
        if (col < 0 || col >= this._width || row < 0 || row >= this._height) {
            return 0;
        }
        const layer = this._layers[layerIndex];
        if (!layer) return 0;

        const layerData = this._layersData.get(layer.id);
        if (layerData) {
            return layerData[row * this._width + col];
        }
        return layer.data[row * this._width + col] || 0;
    }

    /**
     * Set tile index at position
     * 设置指定位置的图块索引
     * @param layerIndex Layer index | 图层索引
     * @param col Column (X) | 列（X）
     * @param row Row (Y) | 行（Y）
     * @param tileIndex Tile index to set (0 = clear) | 要设置的图块索引（0表示清除）
     */
    setTile(layerIndex: number, col: number, row: number, tileIndex: number): void {
        if (col < 0 || col >= this._width || row < 0 || row >= this._height) {
            return;
        }
        const layer = this._layers[layerIndex];
        if (!layer) return;

        const index = row * this._width + col;
        layer.data[index] = tileIndex;

        let layerData = this._layersData.get(layer.id);
        if (!layerData) {
            layerData = new Uint32Array(layer.data);
            this._layersData.set(layer.id, layerData);
        }
        layerData[index] = tileIndex;

        this.renderDirty = true;
    }

    /**
     * Get raw tile data array for a layer
     * 获取图层的原始图块数据数组
     * @param layerIndex Layer index | 图层索引
     * @returns Uint32Array of tile indices | 图块索引的Uint32Array
     */
    getLayerData(layerIndex: number): Uint32Array | undefined {
        const layer = this._layers[layerIndex];
        if (!layer) return undefined;
        return this._layersData.get(layer.id);
    }

    /**
     * Get merged tile data from all visible layers
     * 获取所有可见图层合并后的图块数据
     * @returns Merged tile data array | 合并的图块数据数组
     */
    getMergedTileData(): Uint32Array {
        const merged = new Uint32Array(this._width * this._height);

        for (const layer of this._layers) {
            if (!layer.visible) continue;

            const layerData = this._layersData.get(layer.id);
            if (!layerData) continue;

            for (let i = 0; i < merged.length; i++) {
                if (layerData[i] > 0) {
                    merged[i] = layerData[i];
                }
            }
        }

        return merged;
    }

    // ===== Collision | 碰撞 =====

    /**
     * Check if tile has collision
     * 检查图块是否有碰撞
     * @param col Column (X) | 列（X）
     * @param row Row (Y) | 行（Y）
     * @returns True if has collision | 如果有碰撞返回true
     */
    hasCollision(col: number, row: number): boolean {
        if (col < 0 || col >= this._width || row < 0 || row >= this._height) {
            return true;
        }
        if (this._collisionData.length === 0) {
            return false;
        }
        return this._collisionData[row * this._width + col] > 0;
    }

    /**
     * Get collision type at tile position
     * 获取图块位置的碰撞类型
     */
    getCollisionType(col: number, row: number): number {
        if (col < 0 || col >= this._width || row < 0 || row >= this._height) {
            return 0;
        }
        if (this._collisionData.length === 0) {
            return 0;
        }
        return this._collisionData[row * this._width + col];
    }

    /**
     * Set collision type at tile position
     * 设置图块位置的碰撞类型
     * @param col Column (X) | 列（X）
     * @param row Row (Y) | 行（Y）
     * @param collisionType Collision type (0 = none) | 碰撞类型（0表示无）
     */
    setCollision(col: number, row: number, collisionType: number): void {
        if (col < 0 || col >= this._width || row < 0 || row >= this._height) {
            return;
        }
        if (this._collisionData.length === 0) {
            this._collisionData = new Uint32Array(this._width * this._height);
            this._collisionDataArray = new Array(this._width * this._height).fill(0);
        }
        const index = row * this._width + col;
        this._collisionData[index] = collisionType;
        this._collisionDataArray[index] = collisionType;
    }

    /**
     * Check collision at world coordinates
     * 检查世界坐标处的碰撞
     */
    hasCollisionAt(worldX: number, worldY: number): boolean {
        const [col, row] = this.worldToTile(worldX, worldY);
        return this.hasCollision(col, row);
    }

    /**
     * Get all collision tiles within bounds
     * 获取边界内的所有碰撞图块
     * @returns Array of [col, row, type] | [列, 行, 类型]数组
     */
    getCollisionTilesInBounds(
        left: number,
        bottom: number,
        right: number,
        top: number
    ): Array<[number, number, number]> {
        const result: Array<[number, number, number]> = [];

        if (this._collisionData.length === 0) {
            return result;
        }

        const startCol = Math.max(0, Math.floor(left / this.tileWidth));
        const endCol = Math.min(this._width, Math.ceil(right / this.tileWidth));
        const startRow = Math.max(0, Math.floor(bottom / this.tileHeight));
        const endRow = Math.min(this._height, Math.ceil(top / this.tileHeight));

        for (let row = startRow; row < endRow; row++) {
            for (let col = startCol; col < endCol; col++) {
                const type = this._collisionData[row * this._width + col];
                if (type > 0) {
                    result.push([col, row, type]);
                }
            }
        }

        return result;
    }

    /**
     * Generate collision rectangles for physics
     * 为物理系统生成碰撞矩形
     * @returns Array of collision rectangles | 碰撞矩形数组
     */
    generateCollisionRects(): Array<{
        x: number;
        y: number;
        width: number;
        height: number;
        type: number;
    }> {
        const rects: Array<{
            x: number;
            y: number;
            width: number;
            height: number;
            type: number;
        }> = [];

        if (this._collisionData.length === 0) {
            return rects;
        }

        for (let row = 0; row < this._height; row++) {
            for (let col = 0; col < this._width; col++) {
                const type = this._collisionData[row * this._width + col];
                if (type > 0) {
                    rects.push({
                        x: col * this.tileWidth,
                        y: row * this.tileHeight,
                        width: this.tileWidth,
                        height: this.tileHeight,
                        type
                    });
                }
            }
        }

        return rects;
    }

    // ===== Coordinate Conversion | 坐标转换 =====

    /**
     * Convert world coordinates to tile coordinates
     * 将世界坐标转换为图块坐标
     * @returns [col, row] | [列, 行]
     */
    worldToTile(worldX: number, worldY: number): [number, number] {
        const col = Math.floor(worldX / this.tileWidth);
        const row = Math.floor(worldY / this.tileHeight);
        return [col, row];
    }

    /**
     * Convert tile coordinates to world coordinates (center of tile)
     * 将图块坐标转换为世界坐标（图块中心）
     * @returns [worldX, worldY] | [世界X, 世界Y]
     */
    tileToWorld(col: number, row: number): [number, number] {
        const worldX = col * this.tileWidth + this.tileWidth / 2;
        const worldY = row * this.tileHeight + this.tileHeight / 2;
        return [worldX, worldY];
    }

    // ===== UV Calculation | UV计算 =====

    /**
     * Get UV coordinates for a tile
     * 获取 tile 的 UV 坐标
     *
     * 使用 UVHelper 计算 OpenGL 纹理坐标。
     * Uses UVHelper to calculate OpenGL texture coordinates.
     *
     * @see UVHelper.calculateTileUV for coordinate system documentation
     * @param tilesetIndex Tileset index | Tileset 索引
     * @param localTileId Local tile ID (1-based) | 本地 tile ID（从1开始）
     * @returns [u0, v0, u1, v1] OpenGL UV coordinates, or null if invalid
     */
    getTileUV(tilesetIndex: number, localTileId: number): [number, number, number, number] | null {
        if (localTileId <= 0) return null;

        const tilesetData = this.getTilesetData(tilesetIndex);
        if (!tilesetData) {
            console.warn('[TilemapComponent] getTileUV: No tileset data for index', tilesetIndex);
            return null;
        }

        // Use UVHelper for coordinate calculation
        // 使用 UVHelper 计算坐标
        return UVHelper.calculateTileUV(localTileId - 1, {
            columns: tilesetData.columns,
            tileWidth: tilesetData.tileWidth,
            tileHeight: tilesetData.tileHeight,
            imageWidth: tilesetData.imageWidth,
            imageHeight: tilesetData.imageHeight,
            margin: tilesetData.margin,
            spacing: tilesetData.spacing
        });
    }

    // ===== Resize | 大小调整 =====

    /**
     * Calculate offset based on anchor point
     * 根据锚点计算偏移量
     */
    private calculateAnchorOffset(
        oldSize: number,
        newSize: number,
        anchor: 'start' | 'center' | 'end'
    ): number {
        const delta = newSize - oldSize;
        switch (anchor) {
            case 'start': return 0;
            case 'center': return Math.floor(delta / 2);
            case 'end': return delta;
        }
    }

    /**
     * Resize the tilemap, preserving existing data at the specified anchor position
     * 调整瓦片地图大小，在指定锚点位置保留现有数据
     * @param newWidth New width in tiles | 新宽度（图块数）
     * @param newHeight New height in tiles | 新高度（图块数）
     * @param anchor Anchor point for preserving data (default: 'bottom-left' for Y-up coordinate system) | 保留数据的锚点（默认：'bottom-left'，适用于Y轴向上的坐标系）
     */
    resize(newWidth: number, newHeight: number, anchor: ResizeAnchor = 'bottom-left'): void {
        if (newWidth === this._width && newHeight === this._height) {
            return;
        }

        // Parse anchor to get X and Y alignment
        // 解析锚点获取X和Y方向的对齐方式
        let xAnchor: 'start' | 'center' | 'end' = 'start';
        let yAnchor: 'start' | 'center' | 'end' = 'end'; // 'end' means bottom in Y-up system

        if (anchor.includes('left')) xAnchor = 'start';
        else if (anchor.includes('right')) xAnchor = 'end';
        else xAnchor = 'center';

        if (anchor.includes('bottom')) yAnchor = 'end';
        else if (anchor.includes('top')) yAnchor = 'start';
        else yAnchor = 'center';

        // Calculate offsets for placing old data in new array
        // 计算将旧数据放入新数组的偏移量
        const offsetX = this.calculateAnchorOffset(this._width, newWidth, xAnchor);
        const offsetY = this.calculateAnchorOffset(this._height, newHeight, yAnchor);

        // 调整所有图层
        for (const layer of this._layers) {
            const oldLayerData = this._layersData.get(layer.id);
            const newLayerData = new Uint32Array(newWidth * newHeight);
            const newDataArray = new Array(newWidth * newHeight).fill(0);

            if (oldLayerData) {
                for (let y = 0; y < this._height; y++) {
                    for (let x = 0; x < this._width; x++) {
                        const newX = x + offsetX;
                        const newY = y + offsetY;

                        // Check bounds
                        if (newX >= 0 && newX < newWidth && newY >= 0 && newY < newHeight) {
                            const value = oldLayerData[y * this._width + x];
                            newLayerData[newY * newWidth + newX] = value;
                            newDataArray[newY * newWidth + newX] = value;
                        }
                    }
                }
            }

            this._layersData.set(layer.id, newLayerData);
            layer.data = newDataArray;
        }

        // 调整碰撞数据
        if (this._collisionData.length > 0) {
            const newCollisionData = new Uint32Array(newWidth * newHeight);
            const newCollisionArray = new Array(newWidth * newHeight).fill(0);

            for (let y = 0; y < this._height; y++) {
                for (let x = 0; x < this._width; x++) {
                    const newX = x + offsetX;
                    const newY = y + offsetY;

                    if (newX >= 0 && newX < newWidth && newY >= 0 && newY < newHeight) {
                        const value = this._collisionData[y * this._width + x];
                        newCollisionData[newY * newWidth + newX] = value;
                        newCollisionArray[newY * newWidth + newX] = value;
                    }
                }
            }

            this._collisionData = newCollisionData;
            this._collisionDataArray = newCollisionArray;
        }

        this._width = newWidth;
        this._height = newHeight;
        this.renderDirty = true;
    }

    // ===== Serialization | 序列化 =====

    /**
     * Called after deserialization to restore runtime data
     * 反序列化后调用以恢复运行时数据
     */
    override onDeserialized(): void {
        // 恢复图层运行时数据
        for (const layer of this._layers) {
            if (layer.data && layer.data.length > 0) {
                this._layersData.set(layer.id, new Uint32Array(layer.data));
            }
        }

        // 恢复Tileset缓存数据
        for (let i = 0; i < this._tilesets.length; i++) {
            const tileset = this._tilesets[i];
            if (tileset.data) {
                this._tilesetsData.set(i, tileset.data);
            }
        }

        // 恢复碰撞数据
        if (this._collisionDataArray.length > 0) {
            this._collisionData = new Uint32Array(this._collisionDataArray);
        }

        this.renderDirty = true;
    }


    /**
     * Cleanup when component is destroyed
     * 组件销毁时清理资源
     */
    onDestroy(): void {
        this._tilesets = [];
        this._tilesetsData.clear();
        this._layers = [];
        this._layersData.clear();
        this._collisionData = new Uint32Array(0);
        this._collisionDataArray = [];
    }

    /**
     * Export tilemap to data format
     * 导出瓦片地图为数据格式
     * @returns Tilemap data object | 瓦片地图数据对象
     */
    exportToData(): ITilemapData {
        return {
            name: 'Tilemap',
            version: 2,
            width: this._width,
            height: this._height,
            tileWidth: this.tileWidth,
            tileHeight: this.tileHeight,
            tilesets: this._tilesets.map((ts) => ({ ...ts })),
            layers: this._layers.map((layer) => ({
                ...layer,
                data: [...layer.data]
            })),
            collisionData: this._collisionData.length > 0 ? Array.from(this._collisionData) : undefined
        };
    }

    // ===== IResourceComponent 实现 =====

    /**
     * 获取此组件需要的所有资源引用
     * Get all resource references needed by this component
     */
    getResourceReferences(): ResourceReference[] {
        const refs: ResourceReference[] = [];

        // 收集所有 tileset 纹理引用
        // Collect all tileset texture references
        for (const tileset of this._tilesets) {
            if (tileset.source) {
                refs.push({
                    path: tileset.source,
                    type: 'texture',
                    runtimeId: tileset.textureId
                });
            }
        }

        return refs;
    }

    /**
     * 设置已加载资源的运行时 ID
     * Set runtime IDs for loaded resources
     */
    setResourceIds(pathToId: Map<string, number>): void {
        // 为每个 tileset 设置纹理 ID
        // Set texture ID for each tileset
        for (const tileset of this._tilesets) {
            if (tileset.source) {
                const textureId = pathToId.get(tileset.source);
                if (textureId !== undefined) {
                    tileset.textureId = textureId;
                }
            }
        }

        // 标记渲染数据为脏，需要重新构建
        // Mark render data as dirty, needs rebuild
        this.renderDirty = true;
    }
}
