'use strict';

var PlatformExporter = require('./PlatformExporter.js');
var TypeScriptExporter = require('../scripting/exporters/TypeScriptExporter.js');
var GraphToAST = require('../scripting/GraphToAST.js');

/* ────────────────────────────────────────────────────────────────
   Web/HTML5 Platform Exporter
   
   Base exporter for web-based game engines.
   Generates HTML, JavaScript/TypeScript, and bundled assets.
──────────────────────────────────────────────────────────────── */
/* ── PixiJS Exporter ──────────────────────────────────────────── */
class PixiJSExporter extends PlatformExporter.PlatformExporter {
    constructor() {
        super(...arguments);
        this.platformId = 'pixijs';
        this.platformInfo = {
            id: 'pixijs',
            name: 'PixiJS',
            description: 'Fast 2D WebGL renderer',
            website: 'https://pixijs.com',
            features: ['2d-rendering', 'particles', 'animation'],
            supportedAssets: ['sprite', 'tileset', 'audio', 'font', 'script', 'animation'],
            exportFormats: ['.html', '.js', '.ts'],
        };
        this.tsExporter = new TypeScriptExporter.TypeScriptExporter();
        this.graphToAST = new GraphToAST.GraphToAST();
    }
    async doExport(project, options) {
        const web = options.platformOptions;
        const useTS = (web === null || web === void 0 ? void 0 : web.typescript) !== false;
        const bundler = (web === null || web === void 0 ? void 0 : web.bundler) || 'vite';
        // 1. Generate package.json
        this.exportPackageJson(project, web);
        // 2. Generate HTML entry
        this.exportIndexHtml(project, options, web);
        // 3. Generate main game file
        this.exportMainGame(project, options, useTS);
        // 4. Export scenes
        this.exportScenes(project, options, useTS);
        // 5. Export scripts
        await this.exportScripts(project, options, useTS);
        // 6. Export asset manifest
        this.exportAssetManifest(project);
        // 7. Generate bundler config
        if (bundler !== 'none') {
            this.exportBundlerConfig(project, bundler, useTS);
        }
        // 8. Generate PWA files
        if (web === null || web === void 0 ? void 0 : web.pwa) {
            this.exportPWAFiles(project);
        }
        // 9. Generate utility classes
        this.exportUtilities(project, useTS);
        // 10. Generate tsconfig if TypeScript
        if (useTS) {
            this.exportTSConfig();
        }
    }
    exportPackageJson(project, web) {
        const useTS = (web === null || web === void 0 ? void 0 : web.typescript) !== false;
        const bundler = (web === null || web === void 0 ? void 0 : web.bundler) || 'vite';
        const pixiVersion = (web === null || web === void 0 ? void 0 : web.frameworkVersion) || '^8.0.0';
        const packageJson = {
            name: project.name.toLowerCase().replace(/\s+/g, '-'),
            version: project.version,
            description: project.description || `${project.name} - Built with Nice2Dev`,
            type: 'module',
            scripts: {
                dev: bundler === 'vite'
                    ? 'vite'
                    : bundler === 'webpack'
                        ? 'webpack serve'
                        : 'parcel index.html',
                build: bundler === 'vite'
                    ? 'vite build'
                    : bundler === 'webpack'
                        ? 'webpack'
                        : 'parcel build index.html',
                preview: bundler === 'vite' ? 'vite preview' : 'serve dist',
            },
            dependencies: {
                pixi: pixiVersion,
                '@pixi/sound': '^5.0.0',
            },
            devDependencies: {
                ...(useTS ? { typescript: '^5.0.0' } : {}),
                ...(bundler === 'vite' ? { vite: '^5.0.0' } : {}),
                ...(bundler === 'webpack'
                    ? { webpack: '^5.0.0', 'webpack-cli': '^5.0.0', 'webpack-dev-server': '^4.0.0' }
                    : {}),
                ...(bundler === 'parcel' ? { parcel: '^2.0.0' } : {}),
            },
        };
        this.addTextFile('package.json', JSON.stringify(packageJson, null, 2));
    }
    exportIndexHtml(project, options, web) {
        var _a;
        const responsive = (web === null || web === void 0 ? void 0 : web.responsive) !== false;
        const { width, height } = project.settings.resolution;
        const html = `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${project.name}</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    body {
      background-color: ${project.settings.backgroundColor};
      overflow: hidden;
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
    }
    
    #game-container {
      ${responsive
            ? `
      width: 100%;
      max-width: ${width}px;
      aspect-ratio: ${width} / ${height};
      `
            : `
      width: ${width}px;
      height: ${height}px;
      `}
    }
    
    canvas {
      display: block;
      width: 100%;
      height: 100%;
      ${((_a = project.settings.rendering) === null || _a === void 0 ? void 0 : _a.pixelArt) ? 'image-rendering: pixelated;' : ''}
    }
  </style>
</head>
<body>
  <div id="game-container"></div>
  <script type="module" src="/src/main.ts"></script>
</body>
</html>
`;
        this.addTextFile('index.html', html);
    }
    exportMainGame(project, options, useTS) {
        var _a, _b;
        const { width, height } = project.settings.resolution;
        const ext = useTS ? 'ts' : 'js';
        const pixelArt = (_a = project.settings.rendering) === null || _a === void 0 ? void 0 : _a.pixelArt;
        const main = `import { Application, Assets } from 'pixi.js';
import { sound } from '@pixi/sound';
import { assetManifest } from './assets/manifest${useTS ? '' : '.js'}';
import { GameManager } from './game/GameManager${useTS ? '' : '.js'}';
import { loadScene } from './scenes/index${useTS ? '' : '.js'}';

${useTS
            ? `
interface GameConfig {
  width: number;
  height: number;
  backgroundColor: number;
}
`
            : ''}

class Game {
  ${useTS ? 'private app: Application;' : ''}
  ${useTS ? 'private gameManager: GameManager;' : ''}

  async init()${useTS ? ': Promise<void>' : ''} {
    // Create PixiJS application
    this.app = new Application();
    
    await this.app.init({
      width: ${width},
      height: ${height},
      backgroundColor: ${this.hexToNumber(project.settings.backgroundColor)},
      resolution: window.devicePixelRatio || 1,
      autoDensity: true,
      ${pixelArt
            ? `
      roundPixels: true,
      antialias: false,`
            : `
      antialias: true,`}
    });

    // Add canvas to DOM
    const container = document.getElementById('game-container');
    if (container) {
      container.appendChild(this.app.canvas);
    }

    // Load assets
    await this.loadAssets();

    // Initialize game manager
    this.gameManager = new GameManager(this.app);

    // Load first scene
    await loadScene('${((_b = project.scenes[0]) === null || _b === void 0 ? void 0 : _b.name) || 'main'}', this.app, this.gameManager);

    // Start game loop
    this.app.ticker.add(this.update.bind(this));

    console.log('${project.name} initialized!');
  }

  private async loadAssets()${useTS ? ': Promise<void>' : ''} {
    // Register asset bundles
    await Assets.init({ manifest: assetManifest });
    
    // Load all bundles
    const bundles = assetManifest.bundles.map(b => b.name);
    await Assets.loadBundle(bundles);
  }

  private update(ticker${useTS ? ': { deltaTime: number }' : ''})${useTS ? ': void' : ''} {
    const delta = ticker.deltaTime;
    this.gameManager.update(delta);
  }
}

// Start game
const game = new Game();
game.init().catch(console.error);
`;
        this.addTextFile(`src/main.${ext}`, main);
    }
    exportScenes(project, options, useTS) {
        const ext = useTS ? 'ts' : 'js';
        // Scene index
        let sceneIndex = `import { Application, Container } from 'pixi.js';
import { GameManager } from '../game/GameManager${useTS ? '' : '.js'}';

${useTS
            ? `
export interface Scene {
  name: string;
  container: Container;
  init: () => Promise<void>;
  update: (delta: number) => void;
  destroy: () => void;
}
`
            : ''}

const scenes${useTS ? ': Map<string, () => Promise<Scene>>' : ''} = new Map();

`;
        for (const scene of project.scenes) {
            const sceneName = this.sanitizeName(scene.name);
            sceneIndex += `scenes.set('${scene.name}', () => import('./${sceneName}${useTS ? '' : '.js'}').then(m => m.default));\n`;
        }
        sceneIndex += `
export async function loadScene(
  name${useTS ? ': string' : ''}, 
  app${useTS ? ': Application' : ''}, 
  gameManager${useTS ? ': GameManager' : ''}
)${useTS ? ': Promise<Scene | null>' : ''} {
  const loader = scenes.get(name);
  if (!loader) {
    console.error(\`Scene "\${name}" not found\`);
    return null;
  }

  const SceneClass = await loader();
  const scene = new SceneClass(app, gameManager);
  await scene.init();
  
  app.stage.addChild(scene.container);
  gameManager.setCurrentScene(scene);
  
  return scene;
}

export { scenes };
`;
        this.addTextFile(`src/scenes/index.${ext}`, sceneIndex);
        // Individual scene files
        for (const scene of project.scenes) {
            this.exportScene(scene, project, useTS);
        }
    }
    exportScene(scene, project, useTS) {
        const ext = useTS ? 'ts' : 'js';
        const sceneName = this.sanitizeName(scene.name);
        let content = `import { Application, Container, Sprite, Assets } from 'pixi.js';
import { GameManager } from '../game/GameManager${useTS ? '' : '.js'}';
${useTS ? `import type { Scene } from './index';` : ''}

export default class ${sceneName}Scene ${useTS ? 'implements Scene' : ''} {
  ${useTS ? 'public name: string;' : ''}
  ${useTS ? 'public container: Container;' : ''}
  ${useTS ? 'private app: Application;' : ''}
  ${useTS ? 'private gameManager: GameManager;' : ''}
  ${useTS ? 'private entities: Map<string, Container> = new Map();' : ''}

  constructor(app${useTS ? ': Application' : ''}, gameManager${useTS ? ': GameManager' : ''}) {
    this.name = '${scene.name}';
    this.app = app;
    this.gameManager = gameManager;
    this.container = new Container();
    ${useTS ? '' : 'this.entities = new Map();'}
  }

  async init()${useTS ? ': Promise<void>' : ''} {
`;
        // Create entities
        for (const entity of scene.entities) {
            content += this.generateEntityCode(entity, project, useTS);
        }
        content += `  }

  update(delta${useTS ? ': number' : ''})${useTS ? ': void' : ''} {
    // Update logic for scene
    for (const [id, entity] of this.entities) {
      // Entity update logic
    }
  }

  destroy()${useTS ? ': void' : ''} {
    this.container.destroy({ children: true });
    this.entities.clear();
  }
}
`;
        this.addTextFile(`src/scenes/${sceneName}.${ext}`, content);
    }
    generateEntityCode(entity, project, useTS) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
        let code = `
    // Entity: ${entity.name}
    {
      const entity = new Container();
      entity.position.set(${(_b = (_a = entity.position) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : 0}, ${(_d = (_c = entity.position) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : 0});
      entity.rotation = ${(_e = entity.rotation) !== null && _e !== void 0 ? _e : 0};
      entity.scale.set(${(_g = (_f = entity.scale) === null || _f === void 0 ? void 0 : _f.x) !== null && _g !== void 0 ? _g : 1}, ${(_j = (_h = entity.scale) === null || _h === void 0 ? void 0 : _h.y) !== null && _j !== void 0 ? _j : 1});
`;
        for (const component of entity.components) {
            switch (component.type) {
                case 'sprite': {
                    const spriteId = (_k = component.properties) === null || _k === void 0 ? void 0 : _k.spriteId;
                    const asset = project.assets.find((a) => a.id === spriteId);
                    if (asset) {
                        code += `
      const sprite = Sprite.from('${asset.name}');
      sprite.anchor.set(0.5);
      entity.addChild(sprite);
`;
                    }
                    break;
                }
                case 'animated-sprite': {
                    code += `
      // Animated sprite would need AnimatedSprite setup
      // const animSprite = new AnimatedSprite(textures);
`;
                    break;
                }
            }
        }
        code += `
      this.container.addChild(entity);
      this.entities.set('${entity.id}', entity);
    }
`;
        // Process children
        if (entity.children) {
            for (const child of entity.children) {
                code += this.generateEntityCode(child, project, useTS);
            }
        }
        return code;
    }
    async exportScripts(project, options, useTS) {
        for (const script of project.scripts) {
            try {
                const ast = this.graphToAST.convert(script);
                const result = this.tsExporter.export(ast, {
                    includeDebugComments: options.debug,
                });
                for (const file of result.files) {
                    this.addTextFile(`src/scripts/${file.path}`, file.content);
                }
            }
            catch (error) {
                this.addWarning('SCRIPT_EXPORT_ERROR', `Failed to export script "${script.name}": ${error}`);
            }
        }
    }
    exportAssetManifest(project) {
        const bundles = [];
        // Group assets by type
        const spriteAssets = project.assets.filter((a) => a.type === 'sprite');
        const audioAssets = project.assets.filter((a) => a.type === 'audio');
        const fontAssets = project.assets.filter((a) => a.type === 'font');
        // Sprites bundle
        if (spriteAssets.length > 0) {
            bundles.push({
                name: 'sprites',
                assets: spriteAssets.map((a) => ({
                    alias: a.name,
                    src: `assets/sprites/${a.path}`,
                })),
            });
        }
        // Audio bundle
        if (audioAssets.length > 0) {
            bundles.push({
                name: 'audio',
                assets: audioAssets.map((a) => ({
                    alias: a.name,
                    src: `assets/audio/${a.path}`,
                })),
            });
        }
        // Fonts bundle
        if (fontAssets.length > 0) {
            bundles.push({
                name: 'fonts',
                assets: fontAssets.map((a) => ({
                    alias: a.name,
                    src: `assets/fonts/${a.path}`,
                })),
            });
        }
        const manifest = {
            bundles,
        };
        this.addTextFile('src/assets/manifest.ts', `export const assetManifest = ${JSON.stringify(manifest, null, 2)};`);
    }
    exportBundlerConfig(project, bundler, useTS) {
        switch (bundler) {
            case 'vite':
                this.addTextFile('vite.config.ts', `import { defineConfig } from 'vite';

export default defineConfig({
  base: './',
  build: {
    outDir: 'dist',
    assetsDir: 'assets',
    sourcemap: true,
  },
  server: {
    port: 3000,
    open: true,
  },
});
`);
                break;
            case 'webpack':
                this.addTextFile('webpack.config.js', `const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/main.${useTS ? 'ts' : 'js'}',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  resolve: {
    extensions: ['.ts', '.js'],
  },
  module: {
    rules: [
      {
        test: /\\.ts$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'index.html',
    }),
  ],
  devServer: {
    static: './dist',
    port: 3000,
    open: true,
  },
};
`);
                break;
        }
    }
    exportPWAFiles(project) {
        // manifest.json
        const manifest = {
            name: project.name,
            short_name: project.name.slice(0, 12),
            description: project.description || '',
            start_url: '/',
            display: 'fullscreen',
            background_color: project.settings.backgroundColor,
            theme_color: project.settings.backgroundColor,
            icons: [
                { src: 'icon-192.png', sizes: '192x192', type: 'image/png' },
                { src: 'icon-512.png', sizes: '512x512', type: 'image/png' },
            ],
        };
        this.addTextFile('public/manifest.json', JSON.stringify(manifest, null, 2));
        // service-worker.js
        this.addTextFile('public/sw.js', `const CACHE_NAME = '${project.name}-v${project.version}';
const urlsToCache = [
  '/',
  '/index.html',
  '/src/main.ts',
];

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then((cache) => cache.addAll(urlsToCache))
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then((response) => response || fetch(event.request))
  );
});
`);
    }
    exportUtilities(project, useTS) {
        const ext = useTS ? 'ts' : 'js';
        // GameManager
        const gameManager = `import { Application, Container } from 'pixi.js';
${useTS ? `import type { Scene } from '../scenes/index';` : ''}

export class GameManager {
  ${useTS ? 'private app: Application;' : ''}
  ${useTS ? 'private currentScene: Scene | null = null;' : ''}
  ${useTS ? 'private entities: Map<string, Container> = new Map();' : ''}
  ${useTS ? 'private isPaused: boolean = false;' : ''}

  constructor(app${useTS ? ': Application' : ''}) {
    this.app = app;
    ${useTS
            ? ''
            : `
    this.currentScene = null;
    this.entities = new Map();
    this.isPaused = false;`}
  }

  setCurrentScene(scene${useTS ? ': Scene' : ''})${useTS ? ': void' : ''} {
    if (this.currentScene) {
      this.currentScene.destroy();
      this.app.stage.removeChild(this.currentScene.container);
    }
    this.currentScene = scene;
  }

  registerEntity(id${useTS ? ': string' : ''}, entity${useTS ? ': Container' : ''})${useTS ? ': void' : ''} {
    this.entities.set(id, entity);
  }

  getEntity(id${useTS ? ': string' : ''})${useTS ? ': Container | undefined' : ''} {
    return this.entities.get(id);
  }

  update(delta${useTS ? ': number' : ''})${useTS ? ': void' : ''} {
    if (this.isPaused) return;
    
    if (this.currentScene) {
      this.currentScene.update(delta);
    }
  }

  pause()${useTS ? ': void' : ''} {
    this.isPaused = true;
  }

  resume()${useTS ? ': void' : ''} {
    this.isPaused = false;
  }

  get paused()${useTS ? ': boolean' : ''} {
    return this.isPaused;
  }
}
`;
        this.addTextFile(`src/game/GameManager.${ext}`, gameManager);
        // Input manager
        const inputManager = `export class InputManager {
  ${useTS ? 'private keys: Set<string> = new Set();' : ''}
  ${useTS ? 'private keysJustPressed: Set<string> = new Set();' : ''}
  ${useTS ? 'private mousePosition: { x: number; y: number } = { x: 0, y: 0 };' : ''}
  ${useTS ? 'private mouseButtons: Set<number> = new Set();' : ''}

  constructor() {
    ${useTS
            ? ''
            : `
    this.keys = new Set();
    this.keysJustPressed = new Set();
    this.mousePosition = { x: 0, y: 0 };
    this.mouseButtons = new Set();`}
    
    window.addEventListener('keydown', this.onKeyDown.bind(this));
    window.addEventListener('keyup', this.onKeyUp.bind(this));
    window.addEventListener('mousemove', this.onMouseMove.bind(this));
    window.addEventListener('mousedown', this.onMouseDown.bind(this));
    window.addEventListener('mouseup', this.onMouseUp.bind(this));
  }

  private onKeyDown(e${useTS ? ': KeyboardEvent' : ''})${useTS ? ': void' : ''} {
    if (!this.keys.has(e.code)) {
      this.keysJustPressed.add(e.code);
    }
    this.keys.add(e.code);
  }

  private onKeyUp(e${useTS ? ': KeyboardEvent' : ''})${useTS ? ': void' : ''} {
    this.keys.delete(e.code);
  }

  private onMouseMove(e${useTS ? ': MouseEvent' : ''})${useTS ? ': void' : ''} {
    this.mousePosition.x = e.clientX;
    this.mousePosition.y = e.clientY;
  }

  private onMouseDown(e${useTS ? ': MouseEvent' : ''})${useTS ? ': void' : ''} {
    this.mouseButtons.add(e.button);
  }

  private onMouseUp(e${useTS ? ': MouseEvent' : ''})${useTS ? ': void' : ''} {
    this.mouseButtons.delete(e.button);
  }

  isKeyPressed(code${useTS ? ': string' : ''})${useTS ? ': boolean' : ''} {
    return this.keys.has(code);
  }

  isKeyJustPressed(code${useTS ? ': string' : ''})${useTS ? ': boolean' : ''} {
    const pressed = this.keysJustPressed.has(code);
    this.keysJustPressed.delete(code);
    return pressed;
  }

  isMouseButtonPressed(button${useTS ? ': number' : ''})${useTS ? ': boolean' : ''} {
    return this.mouseButtons.has(button);
  }

  getMousePosition()${useTS ? ': { x: number; y: number }' : ''} {
    return { ...this.mousePosition };
  }

  update()${useTS ? ': void' : ''} {
    this.keysJustPressed.clear();
  }
}

export const input = new InputManager();
`;
        this.addTextFile(`src/game/InputManager.${ext}`, inputManager);
    }
    exportTSConfig() {
        const tsconfig = {
            compilerOptions: {
                target: 'ES2020',
                useDefineForClassFields: true,
                module: 'ESNext',
                lib: ['ES2020', 'DOM', 'DOM.Iterable'],
                skipLibCheck: true,
                moduleResolution: 'bundler',
                allowImportingTsExtensions: true,
                resolveJsonModule: true,
                isolatedModules: true,
                noEmit: true,
                strict: true,
                noUnusedLocals: true,
                noUnusedParameters: true,
                noFallthroughCasesInSwitch: true,
            },
            include: ['src'],
        };
        this.addTextFile('tsconfig.json', JSON.stringify(tsconfig, null, 2));
    }
    hexToNumber(hex) {
        return parseInt(hex.replace('#', ''), 16);
    }
    sanitizeName(name) {
        return name.replace(/[^a-zA-Z0-9]/g, '');
    }
}
/* ── Phaser Exporter ──────────────────────────────────────────── */
class PhaserExporter extends PlatformExporter.PlatformExporter {
    constructor() {
        super(...arguments);
        this.platformId = 'phaser';
        this.platformInfo = {
            id: 'phaser',
            name: 'Phaser',
            description: 'Desktop and mobile HTML5 game framework',
            website: 'https://phaser.io',
            features: ['2d-rendering', 'physics-2d', 'audio', 'tilemaps', 'particles', 'animation'],
            supportedAssets: ['sprite', 'tileset', 'audio', 'font', 'script', 'animation', 'tilemap'],
            exportFormats: ['.html', '.js', '.ts'],
        };
        this.tsExporter = new TypeScriptExporter.TypeScriptExporter();
        this.graphToAST = new GraphToAST.GraphToAST();
    }
    async doExport(project, options) {
        const web = options.platformOptions;
        const useTS = (web === null || web === void 0 ? void 0 : web.typescript) !== false;
        const bundler = (web === null || web === void 0 ? void 0 : web.bundler) || 'vite';
        // 1. Generate package.json
        this.exportPackageJson(project, web);
        // 2. Generate HTML entry
        this.exportIndexHtml(project);
        // 3. Generate main game config
        this.exportMainGame(project, options, useTS);
        // 4. Export scenes
        this.exportScenes(project, options, useTS);
        // 5. Export scripts
        await this.exportScripts(project, options, useTS);
        // 6. Generate bundler config
        if (bundler !== 'none') {
            this.exportBundlerConfig(bundler, useTS);
        }
        // 7. Generate tsconfig if TypeScript
        if (useTS) {
            this.exportTSConfig();
        }
    }
    exportPackageJson(project, web) {
        const useTS = (web === null || web === void 0 ? void 0 : web.typescript) !== false;
        const bundler = (web === null || web === void 0 ? void 0 : web.bundler) || 'vite';
        const phaserVersion = (web === null || web === void 0 ? void 0 : web.frameworkVersion) || '^3.70.0';
        const packageJson = {
            name: project.name.toLowerCase().replace(/\s+/g, '-'),
            version: project.version,
            type: 'module',
            scripts: {
                dev: bundler === 'vite' ? 'vite' : 'webpack serve',
                build: bundler === 'vite' ? 'vite build' : 'webpack',
            },
            dependencies: {
                phaser: phaserVersion,
            },
            devDependencies: {
                ...(useTS ? { typescript: '^5.0.0' } : {}),
                ...(bundler === 'vite' ? { vite: '^5.0.0' } : {}),
            },
        };
        this.addTextFile('package.json', JSON.stringify(packageJson, null, 2));
    }
    exportIndexHtml(project) {
        var _a;
        const html = `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${project.name}</title>
  <style>
    * { margin: 0; padding: 0; }
    body { 
      background: ${project.settings.backgroundColor}; 
      display: flex; 
      justify-content: center; 
      align-items: center; 
      min-height: 100vh;
    }
    canvas { 
      ${((_a = project.settings.rendering) === null || _a === void 0 ? void 0 : _a.pixelArt) ? 'image-rendering: pixelated;' : ''} 
    }
  </style>
</head>
<body>
  <script type="module" src="/src/main.ts"></script>
</body>
</html>`;
        this.addTextFile('index.html', html);
    }
    exportMainGame(project, options, useTS) {
        var _a, _b, _c, _d, _e, _f;
        const ext = useTS ? 'ts' : 'js';
        const { width, height } = project.settings.resolution;
        const pixelArt = (_a = project.settings.rendering) === null || _a === void 0 ? void 0 : _a.pixelArt;
        const hasPhysics = (_b = project.settings.physics) === null || _b === void 0 ? void 0 : _b.enabled;
        let sceneImports = '';
        let sceneList = '';
        for (const scene of project.scenes) {
            const sceneName = this.sanitizeName(scene.name);
            sceneImports += `import { ${sceneName}Scene } from './scenes/${sceneName}${useTS ? '' : '.js'}';\n`;
            sceneList += `${sceneName}Scene, `;
        }
        const main = `import Phaser from 'phaser';
${sceneImports}

const config${useTS ? ': Phaser.Types.Core.GameConfig' : ''} = {
  type: Phaser.AUTO,
  width: ${width},
  height: ${height},
  backgroundColor: '${project.settings.backgroundColor}',
  parent: 'game-container',
  ${pixelArt
            ? `
  pixelArt: true,
  roundPixels: true,`
            : ''}
  ${hasPhysics
            ? `
  physics: {
    default: 'arcade',
    arcade: {
      gravity: { x: ${(_d = (_c = project.settings.physics) === null || _c === void 0 ? void 0 : _c.gravity.x) !== null && _d !== void 0 ? _d : 0}, y: ${(_f = (_e = project.settings.physics) === null || _e === void 0 ? void 0 : _e.gravity.y) !== null && _f !== void 0 ? _f : 300} },
      debug: ${options.debug || false}
    }
  },`
            : ''}
  scene: [${sceneList}],
  scale: {
    mode: Phaser.Scale.FIT,
    autoCenter: Phaser.Scale.CENTER_BOTH,
  },
};

const game = new Phaser.Game(config);
`;
        this.addTextFile(`src/main.${ext}`, main);
    }
    exportScenes(project, options, useTS) {
        for (const scene of project.scenes) {
            this.exportScene(scene, project, useTS);
        }
    }
    exportScene(scene, project, useTS) {
        var _a;
        const ext = useTS ? 'ts' : 'js';
        const sceneName = this.sanitizeName(scene.name);
        let content = `import Phaser from 'phaser';

export class ${sceneName}Scene extends Phaser.Scene {
  constructor() {
    super({ key: '${scene.name}' });
  }

  preload()${useTS ? ': void' : ''} {
`;
        // Preload assets used in this scene
        const usedAssets = this.getUsedAssets(scene, project);
        for (const asset of usedAssets) {
            switch (asset.type) {
                case 'sprite':
                    content += `    this.load.image('${asset.name}', 'assets/sprites/${asset.path}');\n`;
                    break;
                case 'audio':
                    content += `    this.load.audio('${asset.name}', 'assets/audio/${asset.path}');\n`;
                    break;
                case 'tileset':
                    content += `    this.load.image('${asset.name}', 'assets/tilesets/${asset.path}');\n`;
                    break;
            }
        }
        content += `  }

  create()${useTS ? ': void' : ''} {
`;
        // Create entities
        for (const entity of scene.entities) {
            content += this.generateEntityCode(entity, project, useTS);
        }
        // Create tilemaps
        for (const tilemap of (_a = scene.tilemaps) !== null && _a !== void 0 ? _a : []) {
            content += this.generateTilemapCode(tilemap, project);
        }
        content += `  }

  update(time${useTS ? ': number' : ''}, delta${useTS ? ': number' : ''})${useTS ? ': void' : ''} {
    // Update logic
  }
}
`;
        this.addTextFile(`src/scenes/${sceneName}.${ext}`, content);
    }
    generateEntityCode(entity, project, useTS) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4;
        let code = `
    // Entity: ${entity.name}
`;
        for (const component of entity.components) {
            switch (component.type) {
                case 'sprite': {
                    const spriteId = (_a = component.properties) === null || _a === void 0 ? void 0 : _a.spriteId;
                    const asset = project.assets.find((a) => a.id === spriteId);
                    if (asset) {
                        const hasPhysics = entity.components.some((c) => c.type === 'rigidbody-2d' ||
                            c.type === 'box-collider-2d' ||
                            c.type === 'circle-collider-2d');
                        if (hasPhysics) {
                            code += `    const ${this.varName(entity.name)} = this.physics.add.sprite(${(_c = (_b = entity.position) === null || _b === void 0 ? void 0 : _b.x) !== null && _c !== void 0 ? _c : 0}, ${(_e = (_d = entity.position) === null || _d === void 0 ? void 0 : _d.y) !== null && _e !== void 0 ? _e : 0}, '${asset.name}');\n`;
                        }
                        else {
                            code += `    const ${this.varName(entity.name)} = this.add.sprite(${(_g = (_f = entity.position) === null || _f === void 0 ? void 0 : _f.x) !== null && _g !== void 0 ? _g : 0}, ${(_j = (_h = entity.position) === null || _h === void 0 ? void 0 : _h.y) !== null && _j !== void 0 ? _j : 0}, '${asset.name}');\n`;
                        }
                        code += `    ${this.varName(entity.name)}.setScale(${(_l = (_k = entity.scale) === null || _k === void 0 ? void 0 : _k.x) !== null && _l !== void 0 ? _l : 1}, ${(_o = (_m = entity.scale) === null || _m === void 0 ? void 0 : _m.y) !== null && _o !== void 0 ? _o : 1});\n`;
                        code += `    ${this.varName(entity.name)}.setRotation(${(_p = entity.rotation) !== null && _p !== void 0 ? _p : 0});\n`;
                    }
                    break;
                }
                case 'ui-text': {
                    code += `    const ${this.varName(entity.name)} = this.add.text(${(_r = (_q = entity.position) === null || _q === void 0 ? void 0 : _q.x) !== null && _r !== void 0 ? _r : 0}, ${(_t = (_s = entity.position) === null || _s === void 0 ? void 0 : _s.y) !== null && _t !== void 0 ? _t : 0}, '${((_u = component.properties) === null || _u === void 0 ? void 0 : _u.text) || ''}', {
      fontSize: '${((_v = component.properties) === null || _v === void 0 ? void 0 : _v.fontSize) || 32}px',
      color: '${((_w = component.properties) === null || _w === void 0 ? void 0 : _w.color) || '#ffffff'}',
    });\n`;
                    break;
                }
                case 'particle-system': {
                    code += `    const ${this.varName(entity.name)}Particles = this.add.particles(${(_y = (_x = entity.position) === null || _x === void 0 ? void 0 : _x.x) !== null && _y !== void 0 ? _y : 0}, ${(_0 = (_z = entity.position) === null || _z === void 0 ? void 0 : _z.y) !== null && _0 !== void 0 ? _0 : 0});\n`;
                    break;
                }
                case 'audio-source': {
                    const clipId = (_1 = component.properties) === null || _1 === void 0 ? void 0 : _1.clipId;
                    const clip = project.assets.find((a) => a.id === clipId);
                    if (clip && ((_2 = component.properties) === null || _2 === void 0 ? void 0 : _2.playOnAwake)) {
                        code += `    this.sound.play('${clip.name}', { loop: ${((_3 = component.properties) === null || _3 === void 0 ? void 0 : _3.loop) || false}, volume: ${((_4 = component.properties) === null || _4 === void 0 ? void 0 : _4.volume) || 1} });\n`;
                    }
                    break;
                }
            }
        }
        // Process children
        if (entity.children) {
            for (const child of entity.children) {
                code += this.generateEntityCode(child, project, useTS);
            }
        }
        return code;
    }
    generateTilemapCode(tilemap, project) {
        const tilesetAsset = project.assets.find((a) => a.id === tilemap.tilesetId);
        if (!tilesetAsset)
            return '';
        return `
    // Tilemap: ${tilemap.name}
    const ${this.varName(tilemap.name)}Map = this.make.tilemap({ 
      width: ${tilemap.width}, 
      height: ${tilemap.height}, 
      tileWidth: ${tilemap.tileSize}, 
      tileHeight: ${tilemap.tileSize} 
    });
    const ${this.varName(tilemap.name)}Tileset = ${this.varName(tilemap.name)}Map.addTilesetImage('${tilesetAsset.name}');
`;
    }
    getUsedAssets(scene, project) {
        var _a;
        const assetIds = new Set();
        const collectFromEntity = (entity) => {
            var _a, _b;
            for (const component of entity.components) {
                if ((_a = component.properties) === null || _a === void 0 ? void 0 : _a.spriteId) {
                    assetIds.add(component.properties.spriteId);
                }
                if ((_b = component.properties) === null || _b === void 0 ? void 0 : _b.clipId) {
                    assetIds.add(component.properties.clipId);
                }
            }
            if (entity.children) {
                entity.children.forEach(collectFromEntity);
            }
        };
        scene.entities.forEach(collectFromEntity);
        ((_a = scene.tilemaps) !== null && _a !== void 0 ? _a : []).forEach((tm) => assetIds.add(tm.tilesetId));
        return project.assets.filter((a) => assetIds.has(a.id));
    }
    async exportScripts(project, options, useTS) {
        for (const script of project.scripts) {
            try {
                const ast = this.graphToAST.convert(script);
                const result = this.tsExporter.export(ast, {
                    includeDebugComments: options.debug,
                });
                for (const file of result.files) {
                    this.addTextFile(`src/scripts/${file.path}`, file.content);
                }
            }
            catch (error) {
                this.addWarning('SCRIPT_EXPORT_ERROR', `Failed to export script "${script.name}": ${error}`);
            }
        }
    }
    exportBundlerConfig(bundler, useTS) {
        if (bundler === 'vite') {
            this.addTextFile('vite.config.ts', `import { defineConfig } from 'vite';

export default defineConfig({
  base: './',
  build: {
    outDir: 'dist',
  },
});
`);
        }
    }
    exportTSConfig() {
        const tsconfig = {
            compilerOptions: {
                target: 'ES2020',
                module: 'ESNext',
                moduleResolution: 'bundler',
                strict: true,
                noEmit: true,
                skipLibCheck: true,
                lib: ['ES2020', 'DOM'],
            },
            include: ['src'],
        };
        this.addTextFile('tsconfig.json', JSON.stringify(tsconfig, null, 2));
    }
    sanitizeName(name) {
        return name.replace(/[^a-zA-Z0-9]/g, '');
    }
    varName(name) {
        const sanitized = this.sanitizeName(name);
        return sanitized.charAt(0).toLowerCase() + sanitized.slice(1);
    }
}

exports.PhaserExporter = PhaserExporter;
exports.PixiJSExporter = PixiJSExporter;
//# sourceMappingURL=WebExporter.js.map
