import { useState, useRef, useCallback } from 'react';
import { createEmptyProject, generateId, serializeProject, downloadJson, deserializeProject, createTileFromImage, dataUrlToImageData, createEmptyTileMap, createEmptyTileLayer, loadImage, autoSliceSpriteSheet, detectFrames, createSpriteAnimation, applyEffects, exportToTiledJson, downloadPng } from './gameAssetUtils.js';

/**
 * useGameAssetEditor.ts — State and logic hook for GameAsset2dEditor
 */
const DEFAULT_EDITOR_STATE = {
    mode: 'tilemap',
    tileMapTool: 'brush',
    spriteSheetTool: 'select',
    selectedTileId: null,
    selectedFrameIds: [],
    selectedStateId: null,
    activeLayerId: null,
    activeTileMapId: null,
    activeSpriteSheetId: null,
    activeStateMachineId: null,
    zoom: 1,
    panX: 0,
    panY: 0,
    showGrid: true,
    showCollision: false,
    snapToGrid: true,
};
const MAX_HISTORY = 50;
const useGameAssetEditor = (options = {}) => {
    const { onSave, onExport } = options;
    const [project, setProject] = useState(() => createEmptyProject('Untitled'));
    const [editorState, setEditorState] = useState(DEFAULT_EDITOR_STATE);
    const [history, setHistory] = useState([]);
    const [historyIndex, setHistoryIndex] = useState(-1);
    const [currentEffects, setCurrentEffects] = useState([]);
    const canvasRef = useRef(null);
    const fileInputRef = useRef(null);
    // ─────────────────────────────────────────────────────────────
    // History management
    // ─────────────────────────────────────────────────────────────
    const pushHistory = useCallback((description) => {
        const entry = {
            id: generateId('history'),
            description,
            timestamp: Date.now(),
            snapshot: JSON.parse(JSON.stringify(project)),
        };
        setHistory(prev => {
            const newHistory = prev.slice(0, historyIndex + 1);
            newHistory.push(entry);
            if (newHistory.length > MAX_HISTORY)
                newHistory.shift();
            return newHistory;
        });
        setHistoryIndex(prev => Math.min(prev + 1, MAX_HISTORY - 1));
    }, [project, historyIndex]);
    const undo = useCallback(() => {
        if (historyIndex > 0) {
            const entry = history[historyIndex - 1];
            setProject(entry.snapshot);
            setHistoryIndex(prev => prev - 1);
        }
    }, [history, historyIndex]);
    const redo = useCallback(() => {
        if (historyIndex < history.length - 1) {
            const entry = history[historyIndex + 1];
            setProject(entry.snapshot);
            setHistoryIndex(prev => prev + 1);
        }
    }, [history, historyIndex]);
    // ─────────────────────────────────────────────────────────────
    // Project operations
    // ─────────────────────────────────────────────────────────────
    const newProject = useCallback((name) => {
        const newProj = createEmptyProject(name);
        setProject(newProj);
        setEditorState(DEFAULT_EDITOR_STATE);
        setHistory([]);
        setHistoryIndex(-1);
    }, []);
    const saveProject = useCallback(() => {
        const data = serializeProject(project);
        downloadJson(JSON.parse(data), `${project.name}.json`);
        onSave === null || onSave === void 0 ? void 0 : onSave(project);
    }, [project, onSave]);
    const loadProject = useCallback(async (file) => {
        const text = await file.text();
        const loaded = await deserializeProject(text);
        setProject(loaded);
        setEditorState(DEFAULT_EDITOR_STATE);
        setHistory([]);
        setHistoryIndex(-1);
    }, []);
    // ─────────────────────────────────────────────────────────────
    // Editor state operations
    // ─────────────────────────────────────────────────────────────
    const setMode = useCallback((mode) => {
        setEditorState(prev => ({ ...prev, mode }));
    }, []);
    const setTileMapTool = useCallback((tool) => {
        setEditorState(prev => ({ ...prev, tileMapTool: tool }));
    }, []);
    const setSpriteSheetTool = useCallback((tool) => {
        setEditorState(prev => ({ ...prev, spriteSheetTool: tool }));
    }, []);
    const setZoom = useCallback((zoom) => {
        setEditorState(prev => ({ ...prev, zoom: Math.max(0.1, Math.min(10, zoom)) }));
    }, []);
    const setPan = useCallback((x, y) => {
        setEditorState(prev => ({ ...prev, panX: x, panY: y }));
    }, []);
    const toggleGrid = useCallback(() => {
        setEditorState(prev => ({ ...prev, showGrid: !prev.showGrid }));
    }, []);
    const toggleCollision = useCallback(() => {
        setEditorState(prev => ({ ...prev, showCollision: !prev.showCollision }));
    }, []);
    const toggleSnap = useCallback(() => {
        setEditorState(prev => ({ ...prev, snapToGrid: !prev.snapToGrid }));
    }, []);
    // ─────────────────────────────────────────────────────────────
    // Tile set operations
    // ─────────────────────────────────────────────────────────────
    const addTile = useCallback((imageData, name) => {
        const tile = createTileFromImage(imageData, name);
        setProject(prev => ({ ...prev, tileSets: [...prev.tileSets, tile] }));
        pushHistory(`Add tile: ${name}`);
    }, [pushHistory]);
    const removeTile = useCallback((id) => {
        setProject(prev => ({
            ...prev,
            tileSets: prev.tileSets.filter(t => t.id !== id),
        }));
        pushHistory('Remove tile');
    }, [pushHistory]);
    const selectTile = useCallback((id) => {
        setEditorState(prev => ({ ...prev, selectedTileId: id }));
    }, []);
    const importTileSet = useCallback(async (file) => {
        const dataUrl = await new Promise((resolve) => {
            const reader = new FileReader();
            reader.onload = () => resolve(reader.result);
            reader.readAsDataURL(file);
        });
        const imageData = await dataUrlToImageData(dataUrl);
        const name = file.name.replace(/\.[^/.]+$/, '');
        addTile(imageData, name);
    }, [addTile]);
    // ─────────────────────────────────────────────────────────────
    // Tile map operations
    // ─────────────────────────────────────────────────────────────
    const createTileMap = useCallback((name, width, height) => {
        const map = createEmptyTileMap(name, width, height, project.settings.defaultTileWidth, project.settings.defaultTileHeight);
        setProject(prev => ({ ...prev, tileMaps: [...prev.tileMaps, map] }));
        setEditorState(prev => ({
            ...prev,
            activeTileMapId: map.id,
            activeLayerId: map.layers[0].id,
        }));
        pushHistory(`Create tile map: ${name}`);
    }, [project.settings, pushHistory]);
    const removeTileMap = useCallback((id) => {
        setProject(prev => ({
            ...prev,
            tileMaps: prev.tileMaps.filter(m => m.id !== id),
        }));
        pushHistory('Remove tile map');
    }, [pushHistory]);
    const selectTileMap = useCallback((id) => {
        setEditorState(prev => {
            var _a, _b;
            const map = project.tileMaps.find(m => m.id === id);
            return {
                ...prev,
                activeTileMapId: id,
                activeLayerId: (_b = (_a = map === null || map === void 0 ? void 0 : map.layers[0]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null,
            };
        });
    }, [project.tileMaps]);
    const setTile = useCallback((layerId, x, y, tileId) => {
        setProject(prev => ({
            ...prev,
            tileMaps: prev.tileMaps.map(map => ({
                ...map,
                layers: map.layers.map(layer => {
                    if (layer.id !== layerId)
                        return layer;
                    const newTiles = layer.tiles.map(row => [...row]);
                    if (y >= 0 && y < newTiles.length && x >= 0 && x < newTiles[0].length) {
                        newTiles[y][x] = tileId;
                    }
                    return { ...layer, tiles: newTiles };
                }),
            })),
        }));
    }, []);
    const fillTiles = useCallback((layerId, startX, startY, newTileId) => {
        setProject(prev => {
            var _a;
            const map = prev.tileMaps.find(m => m.layers.some(l => l.id === layerId));
            if (!map)
                return prev;
            const layer = map.layers.find(l => l.id === layerId);
            if (!layer)
                return prev;
            const targetId = (_a = layer.tiles[startY]) === null || _a === void 0 ? void 0 : _a[startX];
            if (targetId === newTileId)
                return prev;
            const newTiles = layer.tiles.map(row => [...row]);
            const stack = [[startX, startY]];
            const visited = new Set();
            while (stack.length > 0) {
                const [x, y] = stack.pop();
                const key = `${x},${y}`;
                if (visited.has(key))
                    continue;
                if (y < 0 || y >= newTiles.length || x < 0 || x >= newTiles[0].length)
                    continue;
                if (newTiles[y][x] !== targetId)
                    continue;
                visited.add(key);
                newTiles[y][x] = newTileId;
                stack.push([x + 1, y], [x - 1, y], [x, y + 1], [x, y - 1]);
            }
            return {
                ...prev,
                tileMaps: prev.tileMaps.map(m => m.id === map.id
                    ? { ...m, layers: m.layers.map(l => (l.id === layerId ? { ...l, tiles: newTiles } : l)) }
                    : m),
            };
        });
        pushHistory('Fill tiles');
    }, [pushHistory]);
    const addLayer = useCallback(() => {
        const map = project.tileMaps.find(m => m.id === editorState.activeTileMapId);
        if (!map)
            return;
        const newLayer = createEmptyTileLayer(`Layer ${map.layers.length + 1}`, map.width, map.height);
        setProject(prev => ({
            ...prev,
            tileMaps: prev.tileMaps.map(m => m.id === map.id ? { ...m, layers: [...m.layers, newLayer] } : m),
        }));
        setEditorState(prev => ({ ...prev, activeLayerId: newLayer.id }));
        pushHistory('Add layer');
    }, [project.tileMaps, editorState.activeTileMapId, pushHistory]);
    const removeLayer = useCallback((id) => {
        setProject(prev => ({
            ...prev,
            tileMaps: prev.tileMaps.map(m => ({
                ...m,
                layers: m.layers.filter(l => l.id !== id),
            })),
        }));
        pushHistory('Remove layer');
    }, [pushHistory]);
    const selectLayer = useCallback((id) => {
        setEditorState(prev => ({ ...prev, activeLayerId: id }));
    }, []);
    const toggleLayerVisibility = useCallback((id) => {
        setProject(prev => ({
            ...prev,
            tileMaps: prev.tileMaps.map(m => ({
                ...m,
                layers: m.layers.map(l => (l.id === id ? { ...l, visible: !l.visible } : l)),
            })),
        }));
    }, []);
    const setLayerOpacity = useCallback((id, opacity) => {
        setProject(prev => ({
            ...prev,
            tileMaps: prev.tileMaps.map(m => ({
                ...m,
                layers: m.layers.map(l => (l.id === id ? { ...l, opacity } : l)),
            })),
        }));
    }, []);
    const moveLayer = useCallback((id, direction) => {
        setProject(prev => ({
            ...prev,
            tileMaps: prev.tileMaps.map(m => {
                const idx = m.layers.findIndex(l => l.id === id);
                if (idx === -1)
                    return m;
                const newIdx = direction === 'up' ? idx - 1 : idx + 1;
                if (newIdx < 0 || newIdx >= m.layers.length)
                    return m;
                const newLayers = [...m.layers];
                [newLayers[idx], newLayers[newIdx]] = [newLayers[newIdx], newLayers[idx]];
                return { ...m, layers: newLayers };
            }),
        }));
        pushHistory(`Move layer ${direction}`);
    }, [pushHistory]);
    // ─────────────────────────────────────────────────────────────
    // Sprite sheet operations
    // ─────────────────────────────────────────────────────────────
    const importSpriteSheet = useCallback(async (file) => {
        const dataUrl = await new Promise((resolve) => {
            const reader = new FileReader();
            reader.onload = () => resolve(reader.result);
            reader.readAsDataURL(file);
        });
        const image = await loadImage(dataUrl);
        const canvas = document.createElement('canvas');
        canvas.width = image.width;
        canvas.height = image.height;
        const ctx = canvas.getContext('2d');
        ctx.drawImage(image, 0, 0);
        const imageData = ctx.getImageData(0, 0, image.width, image.height);
        const sheet = {
            id: generateId('sheet'),
            name: file.name.replace(/\.[^/.]+$/, ''),
            image,
            imageData,
            dataUrl,
            width: image.width,
            height: image.height,
            frames: [],
            animations: [],
        };
        setProject(prev => ({ ...prev, spriteSheets: [...prev.spriteSheets, sheet] }));
        setEditorState(prev => ({ ...prev, activeSpriteSheetId: sheet.id }));
        pushHistory(`Import sprite sheet: ${sheet.name}`);
    }, [pushHistory]);
    const removeSpriteSheet = useCallback((id) => {
        setProject(prev => ({
            ...prev,
            spriteSheets: prev.spriteSheets.filter(s => s.id !== id),
        }));
        pushHistory('Remove sprite sheet');
    }, [pushHistory]);
    const selectSpriteSheet = useCallback((id) => {
        setEditorState(prev => ({ ...prev, activeSpriteSheetId: id, selectedFrameIds: [] }));
    }, []);
    const autoSlice = useCallback((frameWidth, frameHeight) => {
        const sheet = project.spriteSheets.find(s => s.id === editorState.activeSpriteSheetId);
        if (!(sheet === null || sheet === void 0 ? void 0 : sheet.imageData))
            return;
        const frames = autoSliceSpriteSheet(sheet.imageData, frameWidth, frameHeight);
        setProject(prev => ({
            ...prev,
            spriteSheets: prev.spriteSheets.map(s => s.id === sheet.id ? { ...s, frames } : s),
        }));
        pushHistory('Auto-slice sprite sheet');
    }, [project.spriteSheets, editorState.activeSpriteSheetId, pushHistory]);
    const detectSprites = useCallback(() => {
        const sheet = project.spriteSheets.find(s => s.id === editorState.activeSpriteSheetId);
        if (!(sheet === null || sheet === void 0 ? void 0 : sheet.imageData))
            return;
        const frames = detectFrames(sheet.imageData);
        setProject(prev => ({
            ...prev,
            spriteSheets: prev.spriteSheets.map(s => s.id === sheet.id ? { ...s, frames } : s),
        }));
        pushHistory('Detect sprites');
    }, [project.spriteSheets, editorState.activeSpriteSheetId, pushHistory]);
    const addFrame = useCallback((frame) => {
        const newFrame = { ...frame, id: generateId('frame') };
        setProject(prev => ({
            ...prev,
            spriteSheets: prev.spriteSheets.map(s => s.id === editorState.activeSpriteSheetId
                ? { ...s, frames: [...s.frames, newFrame] }
                : s),
        }));
        pushHistory('Add frame');
    }, [editorState.activeSpriteSheetId, pushHistory]);
    const updateFrame = useCallback((id, updates) => {
        setProject(prev => ({
            ...prev,
            spriteSheets: prev.spriteSheets.map(s => ({
                ...s,
                frames: s.frames.map(f => (f.id === id ? { ...f, ...updates } : f)),
            })),
        }));
    }, []);
    const removeFrame = useCallback((id) => {
        setProject(prev => ({
            ...prev,
            spriteSheets: prev.spriteSheets.map(s => ({
                ...s,
                frames: s.frames.filter(f => f.id !== id),
            })),
        }));
        pushHistory('Remove frame');
    }, [pushHistory]);
    const selectFrames = useCallback((ids) => {
        setEditorState(prev => ({ ...prev, selectedFrameIds: ids }));
    }, []);
    // ─────────────────────────────────────────────────────────────
    // Animation operations
    // ─────────────────────────────────────────────────────────────
    const createAnimation = useCallback((name, frameIds) => {
        const animation = createSpriteAnimation(name, frameIds);
        setProject(prev => ({
            ...prev,
            spriteSheets: prev.spriteSheets.map(s => s.id === editorState.activeSpriteSheetId
                ? { ...s, animations: [...s.animations, animation] }
                : s),
        }));
        pushHistory(`Create animation: ${name}`);
    }, [editorState.activeSpriteSheetId, pushHistory]);
    const removeAnimation = useCallback((id) => {
        setProject(prev => ({
            ...prev,
            spriteSheets: prev.spriteSheets.map(s => ({
                ...s,
                animations: s.animations.filter(a => a.id !== id),
            })),
        }));
        pushHistory('Remove animation');
    }, [pushHistory]);
    const updateAnimation = useCallback((id, updates) => {
        setProject(prev => ({
            ...prev,
            spriteSheets: prev.spriteSheets.map(s => ({
                ...s,
                animations: s.animations.map(a => (a.id === id ? { ...a, ...updates } : a)),
            })),
        }));
    }, []);
    // ─────────────────────────────────────────────────────────────
    // State machine operations
    // ─────────────────────────────────────────────────────────────
    const createStateMachine = useCallback((name) => {
        const sm = {
            id: generateId('sm'),
            name,
            states: [],
            transitions: [],
            parameters: [],
            entryStateId: '',
            anyStateTransitions: [],
        };
        setProject(prev => ({ ...prev, stateMachines: [...prev.stateMachines, sm] }));
        setEditorState(prev => ({ ...prev, activeStateMachineId: sm.id }));
        pushHistory(`Create state machine: ${name}`);
    }, [pushHistory]);
    const removeStateMachine = useCallback((id) => {
        setProject(prev => ({
            ...prev,
            stateMachines: prev.stateMachines.filter(sm => sm.id !== id),
        }));
        pushHistory('Remove state machine');
    }, [pushHistory]);
    const selectStateMachine = useCallback((id) => {
        setEditorState(prev => ({ ...prev, activeStateMachineId: id, selectedStateId: null }));
    }, []);
    const addState = useCallback((name, animationId) => {
        const state = {
            id: generateId('state'),
            name,
            animationId,
            speed: 1,
            loop: true,
            position: { x: Math.random() * 400, y: Math.random() * 300 },
        };
        setProject(prev => ({
            ...prev,
            stateMachines: prev.stateMachines.map(sm => sm.id === editorState.activeStateMachineId
                ? {
                    ...sm,
                    states: [...sm.states, state],
                    entryStateId: sm.entryStateId || state.id,
                }
                : sm),
        }));
        pushHistory(`Add state: ${name}`);
    }, [editorState.activeStateMachineId, pushHistory]);
    const removeState = useCallback((id) => {
        setProject(prev => ({
            ...prev,
            stateMachines: prev.stateMachines.map(sm => ({
                ...sm,
                states: sm.states.filter(s => s.id !== id),
                transitions: sm.transitions.filter(t => t.fromStateId !== id && t.toStateId !== id),
            })),
        }));
        pushHistory('Remove state');
    }, [pushHistory]);
    const selectState = useCallback((id) => {
        setEditorState(prev => ({ ...prev, selectedStateId: id }));
    }, []);
    const updateState = useCallback((id, updates) => {
        setProject(prev => ({
            ...prev,
            stateMachines: prev.stateMachines.map(sm => ({
                ...sm,
                states: sm.states.map(s => (s.id === id ? { ...s, ...updates } : s)),
            })),
        }));
    }, []);
    const addTransition = useCallback((fromId, toId) => {
        const transition = {
            id: generateId('trans'),
            fromStateId: fromId,
            toStateId: toId,
            condition: { type: 'trigger', paramName: '' },
            duration: 0.1,
            priority: 0,
        };
        setProject(prev => ({
            ...prev,
            stateMachines: prev.stateMachines.map(sm => sm.id === editorState.activeStateMachineId
                ? { ...sm, transitions: [...sm.transitions, transition] }
                : sm),
        }));
        pushHistory('Add transition');
    }, [editorState.activeStateMachineId, pushHistory]);
    const removeTransition = useCallback((id) => {
        setProject(prev => ({
            ...prev,
            stateMachines: prev.stateMachines.map(sm => ({
                ...sm,
                transitions: sm.transitions.filter(t => t.id !== id),
            })),
        }));
        pushHistory('Remove transition');
    }, [pushHistory]);
    const addParameter = useCallback((name, type) => {
        const param = {
            id: generateId('param'),
            name,
            type,
            defaultValue: type === 'bool' ? false : 0,
        };
        setProject(prev => ({
            ...prev,
            stateMachines: prev.stateMachines.map(sm => sm.id === editorState.activeStateMachineId
                ? { ...sm, parameters: [...sm.parameters, param] }
                : sm),
        }));
        pushHistory(`Add parameter: ${name}`);
    }, [editorState.activeStateMachineId, pushHistory]);
    const removeParameter = useCallback((id) => {
        setProject(prev => ({
            ...prev,
            stateMachines: prev.stateMachines.map(sm => ({
                ...sm,
                parameters: sm.parameters.filter(p => p.id !== id),
            })),
        }));
        pushHistory('Remove parameter');
    }, [pushHistory]);
    // ─────────────────────────────────────────────────────────────
    // Effects operations
    // ─────────────────────────────────────────────────────────────
    const addEffect = useCallback((type) => {
        const defaultParams = {
            'outline': { color: '#000000', thickness: 1 },
            'shadow': { color: '#00000080', offsetX: 2, offsetY: 2, blur: 0 },
            'glow': { color: '#ffffff', size: 4, intensity: 0.8 },
            'palette-swap': { from: '#ffffff', to: '#ff0000' },
            'pixelate': { size: 4 },
            'blur': { radius: 2 },
            'brightness': { value: 0 },
            'contrast': { value: 0 },
            'saturation': { value: 0 },
            'hue-shift': { degrees: 0 },
            'invert': {},
            'tint': { color: '#ffffff', amount: 0.5 },
        };
        const effect = {
            id: generateId('effect'),
            type,
            enabled: true,
            params: { ...defaultParams[type] },
        };
        setCurrentEffects(prev => [...prev, effect]);
    }, []);
    const removeEffect = useCallback((id) => {
        setCurrentEffects(prev => prev.filter(e => e.id !== id));
    }, []);
    const updateEffect = useCallback((id, updates) => {
        setCurrentEffects(prev => prev.map(e => (e.id === id ? { ...e, ...updates } : e)));
    }, []);
    const toggleEffect = useCallback((id) => {
        setCurrentEffects(prev => prev.map(e => (e.id === id ? { ...e, enabled: !e.enabled } : e)));
    }, []);
    const saveEffectPreset = useCallback((name) => {
        const preset = {
            id: generateId('preset'),
            name,
            effects: currentEffects.map(e => ({ ...e, id: generateId('effect') })),
        };
        setProject(prev => ({ ...prev, effectPresets: [...prev.effectPresets, preset] }));
        pushHistory(`Save effect preset: ${name}`);
    }, [currentEffects, pushHistory]);
    const loadEffectPreset = useCallback((id) => {
        const preset = project.effectPresets.find(p => p.id === id);
        if (preset) {
            setCurrentEffects(preset.effects.map(e => ({ ...e, id: generateId('effect') })));
        }
    }, [project.effectPresets]);
    const previewEffects = useCallback((imageData) => {
        return applyEffects(imageData, currentEffects);
    }, [currentEffects]);
    // ─────────────────────────────────────────────────────────────
    // Export operations
    // ─────────────────────────────────────────────────────────────
    const exportTileMap = useCallback((format) => {
        var _a;
        const map = project.tileMaps.find(m => m.id === editorState.activeTileMapId);
        if (!map)
            return;
        if (format === 'json') {
            downloadJson(map, `${map.name}.json`);
        }
        else if (format === 'tiled-json') {
            const tiledData = exportToTiledJson(map, project.tileSets);
            downloadJson(tiledData, `${map.name}.tmj`);
        }
        else if (format === 'png') {
            // Render map to canvas and export
            const canvas = document.createElement('canvas');
            canvas.width = map.width * map.tileWidth;
            canvas.height = map.height * map.tileHeight;
            const ctx = canvas.getContext('2d');
            ctx.fillStyle = map.backgroundColor;
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            for (const layer of map.layers.filter(l => l.visible)) {
                ctx.globalAlpha = layer.opacity;
                for (let y = 0; y < map.height; y++) {
                    for (let x = 0; x < map.width; x++) {
                        const tileId = (_a = layer.tiles[y]) === null || _a === void 0 ? void 0 : _a[x];
                        if (tileId) {
                            const tile = project.tileSets.find(t => t.id === tileId);
                            if (tile === null || tile === void 0 ? void 0 : tile.image) {
                                const tempCanvas = document.createElement('canvas');
                                tempCanvas.width = tile.image.width;
                                tempCanvas.height = tile.image.height;
                                tempCanvas.getContext('2d').putImageData(tile.image, 0, 0);
                                ctx.drawImage(tempCanvas, x * map.tileWidth, y * map.tileHeight);
                            }
                        }
                    }
                }
            }
            downloadPng(canvas, `${map.name}.png`);
        }
        onExport === null || onExport === void 0 ? void 0 : onExport(JSON.stringify(map), format);
    }, [project, editorState.activeTileMapId, onExport]);
    const exportSpriteSheet = useCallback((format) => {
        const sheet = project.spriteSheets.find(s => s.id === editorState.activeSpriteSheetId);
        if (!sheet)
            return;
        if (format === 'json') {
            const exportData = {
                name: sheet.name,
                width: sheet.width,
                height: sheet.height,
                frames: sheet.frames,
                animations: sheet.animations,
            };
            downloadJson(exportData, `${sheet.name}.json`);
        }
        else if (format === 'atlas') {
            // TexturePacker-compatible format
            const framesObj = {};
            for (const f of sheet.frames) {
                framesObj[f.name] = {
                    frame: { x: f.x, y: f.y, w: f.width, h: f.height },
                    pivot: { x: f.pivotX, y: f.pivotY },
                    sourceSize: { w: f.width, h: f.height },
                };
            }
            const atlas = {
                frames: framesObj,
                meta: {
                    app: 'GameAsset2dEditor',
                    version: '1.0',
                    image: `${sheet.name}.png`,
                    size: { w: sheet.width, h: sheet.height },
                },
            };
            downloadJson(atlas, `${sheet.name}.atlas.json`);
        }
        onExport === null || onExport === void 0 ? void 0 : onExport(JSON.stringify(sheet), format);
    }, [project.spriteSheets, editorState.activeSpriteSheetId, onExport]);
    const exportStateMachine = useCallback((format) => {
        const sm = project.stateMachines.find(s => s.id === editorState.activeStateMachineId);
        if (!sm)
            return;
        downloadJson(sm, `${sm.name}.statemachine.json`);
        onExport === null || onExport === void 0 ? void 0 : onExport(JSON.stringify(sm), format);
    }, [project.stateMachines, editorState.activeStateMachineId, onExport]);
    // ─────────────────────────────────────────────────────────────
    // Return API
    // ─────────────────────────────────────────────────────────────
    return {
        project,
        setProject,
        newProject,
        saveProject,
        loadProject,
        editorState,
        setMode,
        setTileMapTool,
        setSpriteSheetTool,
        setZoom,
        setPan,
        toggleGrid,
        toggleCollision,
        toggleSnap,
        addTile,
        removeTile,
        selectTile,
        importTileSet,
        createTileMap,
        removeTileMap,
        selectTileMap,
        setTile,
        fillTiles,
        addLayer,
        removeLayer,
        selectLayer,
        toggleLayerVisibility,
        setLayerOpacity,
        moveLayer,
        importSpriteSheet,
        removeSpriteSheet,
        selectSpriteSheet,
        autoSlice,
        detectSprites,
        addFrame,
        updateFrame,
        removeFrame,
        selectFrames,
        createAnimation,
        removeAnimation,
        updateAnimation,
        createStateMachine,
        removeStateMachine,
        selectStateMachine,
        addState,
        removeState,
        selectState,
        updateState,
        addTransition,
        removeTransition,
        addParameter,
        removeParameter,
        addEffect,
        removeEffect,
        updateEffect,
        toggleEffect,
        saveEffectPreset,
        loadEffectPreset,
        previewEffects,
        undo,
        redo,
        canUndo: historyIndex > 0,
        canRedo: historyIndex < history.length - 1,
        exportTileMap,
        exportSpriteSheet,
        exportStateMachine,
        canvasRef,
        fileInputRef,
    };
};

export { useGameAssetEditor };
//# sourceMappingURL=useGameAssetEditor.js.map
