import { EventBus } from '../core/EventBus.js';

/* ────────────────────────────────────────────────────────────────
   Kid Tools — LEGENDARY L7
   
   • Guided Wizard ("Co chcesz zrobić?")
   • Drag & Drop block editor (no typing required)
   • Kid-friendly project creation flow
──────────────────────────────────────────────────────────────── */
class GuidedWizard {
    constructor(locale = 'en') {
        this.events = new EventBus();
        this.steps = new Map();
        this.choicePath = [];
        this.locale = 'en';
        this.locale = locale;
        this.startStepId = 'start';
        this.currentStepId = this.startStepId;
        // Register built-in wizard steps
        for (const step of WIZARD_STEPS) {
            this.steps.set(step.id, step);
        }
    }
    /** Set display locale. */
    setLocale(locale) {
        this.locale = locale;
    }
    /** Get the current step. */
    getCurrentStep() {
        return this.steps.get(this.currentStepId);
    }
    /** Get choices for the current step, filtered by age. */
    getChoices(playerAge) {
        const step = this.getCurrentStep();
        if (!step)
            return [];
        return step.choices.filter(c => {
            if (playerAge !== undefined) {
                if (c.minAge !== undefined && playerAge < c.minAge)
                    return false;
                if (c.maxAge !== undefined && playerAge > c.maxAge)
                    return false;
            }
            return true;
        });
    }
    /** Select a choice. Returns a WizardResult if the wizard is complete, null otherwise. */
    select(choiceId) {
        const step = this.getCurrentStep();
        if (!step)
            return null;
        const choice = step.choices.find(c => c.id === choiceId);
        if (!choice)
            return null;
        this.choicePath.push(choiceId);
        this.events.emit('wizard:choice', { stepId: this.currentStepId, choiceId, choice });
        switch (choice.action) {
            case 'wizard-step':
                if (choice.nextStepId) {
                    this.currentStepId = choice.nextStepId;
                    this.events.emit('wizard:step', { stepId: this.currentStepId });
                    return null;
                }
                break;
            case 'template':
                return {
                    choicePath: [...this.choicePath],
                    finalAction: 'template',
                    templateId: choice.templateId,
                };
            case 'tutorial':
                return {
                    choicePath: [...this.choicePath],
                    finalAction: 'tutorial',
                    tutorialId: choice.tutorialId,
                };
            case 'open-project':
                return {
                    choicePath: [...this.choicePath],
                    finalAction: 'open-project',
                };
        }
        return null;
    }
    /** Go back to the previous step. */
    back() {
        if (this.choicePath.length === 0)
            return;
        this.choicePath.pop();
        // Simple: reset to start and replay choices
        this.currentStepId = this.startStepId;
        const saved = [...this.choicePath];
        this.choicePath = [];
        for (const cId of saved) {
            this.select(cId);
        }
    }
    /** Reset wizard to initial state. */
    reset() {
        this.currentStepId = this.startStepId;
        this.choicePath = [];
    }
    /** Register a custom wizard step. */
    registerStep(step) {
        this.steps.set(step.id, step);
    }
    /** Get the localized question for the current step. */
    getQuestion() {
        var _a, _b;
        const step = this.getCurrentStep();
        if (!step)
            return '';
        return (_b = (_a = step.question[this.locale]) !== null && _a !== void 0 ? _a : step.question['en']) !== null && _b !== void 0 ? _b : '';
    }
}
/* ── Built-in Wizard Steps ────────────────────────────────────── */
const WIZARD_STEPS = [
    {
        id: 'start',
        question: {
            en: 'What would you like to do? 🎮',
            pl: 'Co chcesz zrobić? 🎮',
            de: 'Was möchtest du machen? 🎮',
        },
        choices: [
            {
                id: 'make-game',
                icon: '🎮',
                label: { en: 'Make a game!', pl: 'Zrobić grę!', de: 'Ein Spiel machen!' },
                description: { en: 'Create your own video game', pl: 'Stwórz własną grę wideo', de: 'Erstelle dein eigenes Videospiel' },
                action: 'wizard-step',
                nextStepId: 'game-type',
            },
            {
                id: 'learn',
                icon: '📚',
                label: { en: 'Learn something', pl: 'Nauczyć się czegoś', de: 'Etwas lernen' },
                description: { en: 'Follow a tutorial step by step', pl: 'Podążaj za tutorialem krok po kroku', de: 'Folge einem Tutorial Schritt für Schritt' },
                action: 'wizard-step',
                nextStepId: 'learn-what',
            },
            {
                id: 'open-existing',
                icon: '📂',
                label: { en: 'Open my project', pl: 'Otworzyć mój projekt', de: 'Mein Projekt öffnen' },
                description: { en: 'Continue working on a saved project', pl: 'Kontynuuj pracę nad zapisanym projektem', de: 'An einem gespeicherten Projekt weiterarbeiten' },
                action: 'open-project',
            },
        ],
    },
    {
        id: 'game-type',
        question: {
            en: 'What kind of game? 🤔',
            pl: 'Jaki rodzaj gry? 🤔',
            de: 'Was für ein Spiel? 🤔',
        },
        showBack: true,
        choices: [
            {
                id: 'platformer',
                icon: '🏃',
                label: { en: 'Platformer', pl: 'Platformówka', de: 'Plattformer' },
                description: { en: 'Jump and run like Mario!', pl: 'Skacz i biegnij jak Mario!', de: 'Springe und laufe wie Mario!' },
                action: 'template',
                templateId: 'platformer',
            },
            {
                id: 'space-shooter',
                icon: '🚀',
                label: { en: 'Space Shooter', pl: 'Kosmiczny strzelec', de: 'Weltraum-Shooter' },
                description: { en: 'Shoot aliens in space!', pl: 'Strzelaj do kosmitów!', de: 'Schieße Aliens im Weltraum!' },
                action: 'template',
                templateId: 'space-shooter',
            },
            {
                id: 'rpg',
                icon: '⚔️',
                label: { en: 'RPG Adventure', pl: 'Przygoda RPG', de: 'RPG-Abenteuer' },
                description: { en: 'Heroes, quests and magic!', pl: 'Bohaterowie, questy i magia!', de: 'Helden, Quests und Magie!' },
                action: 'template',
                templateId: 'rpg',
                minAge: 10,
            },
            {
                id: 'tower-defense',
                icon: '🏰',
                label: { en: 'Tower Defense', pl: 'Tower Defense', de: 'Tower Defense' },
                description: { en: 'Build towers, stop enemies!', pl: 'Buduj wieże, powstrzymuj wrogów!', de: 'Baue Türme, stoppe Feinde!' },
                action: 'template',
                templateId: 'tower-defense',
                minAge: 10,
            },
            {
                id: 'puzzle',
                icon: '🧩',
                label: { en: 'Puzzle Game', pl: 'Gra logiczna', de: 'Puzzlespiel' },
                description: { en: 'Match colors and solve puzzles!', pl: 'Dopasuj kolory i rozwiązuj zagadki!', de: 'Kombiniere Farben und löse Rätsel!' },
                action: 'template',
                templateId: 'puzzle',
            },
            {
                id: 'empty',
                icon: '✨',
                label: { en: 'Empty Project', pl: 'Pusty projekt', de: 'Leeres Projekt' },
                description: { en: 'Start from scratch!', pl: 'Zacznij od zera!', de: 'Von Grund auf beginnen!' },
                action: 'template',
                templateId: 'empty-project',
            },
        ],
    },
    {
        id: 'learn-what',
        question: {
            en: 'What would you like to learn? 🧑‍🎓',
            pl: 'Czego chcesz się nauczyć? 🧑‍🎓',
            de: 'Was möchtest du lernen? 🧑‍🎓',
        },
        showBack: true,
        choices: [
            {
                id: 'learn-basics',
                icon: '🌟',
                label: { en: 'The Basics', pl: 'Podstawy', de: 'Die Grundlagen' },
                description: { en: 'My very first game', pl: 'Moja pierwsza gra', de: 'Mein allererstes Spiel' },
                action: 'tutorial',
                tutorialId: 'first-game',
            },
            {
                id: 'learn-controls',
                icon: '🕹️',
                label: { en: 'Controls & Movement', pl: 'Sterowanie i ruch', de: 'Steuerung & Bewegung' },
                description: { en: 'Keyboard, mouse, gamepad', pl: 'Klawiatura, myszka, gamepad', de: 'Tastatur, Maus, Gamepad' },
                action: 'tutorial',
                tutorialId: 'input-and-movement',
            },
            {
                id: 'learn-physics',
                icon: '⚡',
                label: { en: 'Collisions & Physics', pl: 'Kolizje i fizyka', de: 'Kollisionen & Physik' },
                description: { en: 'Bounce, crash, explode!', pl: 'Odbijaj, zderzaj, eksploduj!', de: 'Prallen, krachen, explodieren!' },
                action: 'tutorial',
                tutorialId: 'collisions-and-physics',
            },
            {
                id: 'learn-animations',
                icon: '🎬',
                label: { en: 'Animations', pl: 'Animacje', de: 'Animationen' },
                description: { en: 'Make things move smoothly', pl: 'Ruszaj rzeczami płynnie', de: 'Dinge fließend bewegen' },
                action: 'tutorial',
                tutorialId: 'animations',
            },
            {
                id: 'learn-multiplayer',
                icon: '👫',
                label: { en: 'Play with friends', pl: 'Graj ze znajomymi', de: 'Mit Freunden spielen' },
                description: { en: 'Local multiplayer on one screen', pl: 'Lokalny multiplayer na jednym ekranie', de: 'Lokaler Mehrspieler auf einem Bildschirm' },
                action: 'tutorial',
                tutorialId: 'local-multiplayer-coop',
            },
            {
                id: 'learn-platformer',
                icon: '🏃',
                label: { en: 'Build a Platformer', pl: 'Zbuduj platformówkę', de: 'Baue einen Plattformer' },
                description: { en: 'Full game from start to finish', pl: 'Cała gra od A do Z', de: 'Ein ganzes Spiel von A bis Z' },
                action: 'tutorial',
                tutorialId: 'build-a-platformer',
                minAge: 10,
            },
        ],
    },
];
class BlockEditor {
    constructor() {
        this.events = new EventBus();
        this.state = {
            blocks: new Map(),
            dragging: null,
            snapPreview: null,
            selected: null,
        };
        this.nextBlockId = 1;
        this.snapDistance = 30;
    }
    /** Add a new block to the canvas at position (x, y). */
    addBlock(blockType, x, y, values) {
        const id = `block_${this.nextBlockId++}`;
        const block = {
            id,
            blockType,
            values: values !== null && values !== void 0 ? values : {},
            x,
            y,
        };
        this.state.blocks.set(id, block);
        this.events.emit('block:added', block);
        return id;
    }
    /** Remove a block (and unsnap from neighbors). */
    removeBlock(id) {
        const block = this.state.blocks.get(id);
        if (!block)
            return;
        // Unsnap from parent
        if (block.parentBlockId) {
            const parent = this.state.blocks.get(block.parentBlockId);
            if (parent) {
                if (parent.nextBlockId === id)
                    parent.nextBlockId = undefined;
                if (parent.innerBlockId === id)
                    parent.innerBlockId = undefined;
            }
        }
        // Unsnap children
        if (block.nextBlockId) {
            const next = this.state.blocks.get(block.nextBlockId);
            if (next)
                next.parentBlockId = undefined;
        }
        if (block.innerBlockId) {
            const inner = this.state.blocks.get(block.innerBlockId);
            if (inner)
                inner.parentBlockId = undefined;
        }
        this.state.blocks.delete(id);
        if (this.state.selected === id)
            this.state.selected = null;
        this.events.emit('block:removed', { id });
    }
    /** Start dragging a block. */
    startDrag(id) {
        if (!this.state.blocks.has(id))
            return;
        const block = this.state.blocks.get(id);
        // Detach from parent
        if (block.parentBlockId) {
            const parent = this.state.blocks.get(block.parentBlockId);
            if (parent) {
                if (parent.nextBlockId === id)
                    parent.nextBlockId = undefined;
                if (parent.innerBlockId === id)
                    parent.innerBlockId = undefined;
            }
            block.parentBlockId = undefined;
        }
        this.state.dragging = id;
        this.events.emit('block:drag-start', { id });
    }
    /** Move the dragged block. */
    moveDrag(x, y) {
        if (!this.state.dragging)
            return;
        const block = this.state.blocks.get(this.state.dragging);
        if (!block)
            return;
        block.x = x;
        block.y = y;
        // Check for snap points
        this.state.snapPreview = this.findSnapTarget(block);
        this.events.emit('block:drag-move', { id: block.id, x, y, snapPreview: this.state.snapPreview });
    }
    /** End dragging — snap if near a target. */
    endDrag() {
        if (!this.state.dragging)
            return;
        const block = this.state.blocks.get(this.state.dragging);
        if (!block) {
            this.state.dragging = null;
            return;
        }
        if (this.state.snapPreview) {
            this.snapBlock(block.id, this.state.snapPreview.targetBlockId, this.state.snapPreview.position);
        }
        this.state.dragging = null;
        this.state.snapPreview = null;
        this.events.emit('block:drag-end', { id: block.id });
    }
    /** Select a block for value editing. */
    selectBlock(id) {
        this.state.selected = id;
        this.events.emit('block:selected', { id });
    }
    /** Update a block's value. */
    setBlockValue(id, key, value) {
        const block = this.state.blocks.get(id);
        if (!block)
            return;
        block.values[key] = value;
        this.events.emit('block:value-changed', { id, key, value });
    }
    /** Get all blocks. */
    getAllBlocks() {
        return Array.from(this.state.blocks.values());
    }
    /** Get the block chain starting from a root block. */
    getChain(startId) {
        const chain = [];
        let current = this.state.blocks.get(startId);
        while (current) {
            chain.push(current);
            current = current.nextBlockId ? this.state.blocks.get(current.nextBlockId) : undefined;
        }
        return chain;
    }
    /** Get all root blocks (blocks with no parent). */
    getRootBlocks() {
        const roots = [];
        for (const block of this.state.blocks.values()) {
            if (!block.parentBlockId)
                roots.push(block);
        }
        return roots;
    }
    /** Convert the block program to a simple code representation. */
    toCode(startId, indent = 0) {
        const lines = [];
        const pad = '  '.repeat(indent);
        const chain = this.getChain(startId);
        for (const block of chain) {
            const vals = Object.entries(block.values)
                .map(([k, v]) => `${k}=${typeof v === 'string' ? `"${v}"` : v}`)
                .join(', ');
            lines.push(`${pad}${block.blockType}(${vals})`);
            if (block.innerBlockId) {
                lines.push(`${pad}{`);
                lines.push(this.toCode(block.innerBlockId, indent + 1));
                lines.push(`${pad}}`);
            }
        }
        return lines.join('\n');
    }
    /** Clear all blocks. */
    clear() {
        this.state.blocks.clear();
        this.state.dragging = null;
        this.state.snapPreview = null;
        this.state.selected = null;
        this.events.emit('block:cleared', {});
    }
    /* ── Internals ──────────────────────────────────────────────── */
    findSnapTarget(block) {
        const BLOCK_HEIGHT = 40;
        for (const [id, other] of this.state.blocks) {
            if (id === block.id)
                continue;
            // Snap below (connect as nextBlock)
            const belowX = Math.abs(block.x - other.x);
            const belowY = block.y - (other.y + BLOCK_HEIGHT);
            if (belowX < this.snapDistance && belowY >= -this.snapDistance && belowY <= this.snapDistance && !other.nextBlockId) {
                return { targetBlockId: id, position: 'below' };
            }
            // Snap inside (for loop/condition blocks)
            const insideX = Math.abs(block.x - (other.x + 20));
            const insideY = block.y - (other.y + BLOCK_HEIGHT - 10);
            if (insideX < this.snapDistance && insideY >= -this.snapDistance && insideY <= this.snapDistance && !other.innerBlockId) {
                return { targetBlockId: id, position: 'inside' };
            }
        }
        return null;
    }
    snapBlock(blockId, targetId, position) {
        const block = this.state.blocks.get(blockId);
        const target = this.state.blocks.get(targetId);
        if (!block || !target)
            return;
        const BLOCK_HEIGHT = 40;
        if (position === 'below') {
            target.nextBlockId = blockId;
            block.parentBlockId = targetId;
            block.x = target.x;
            block.y = target.y + BLOCK_HEIGHT;
        }
        else {
            target.innerBlockId = blockId;
            block.parentBlockId = targetId;
            block.x = target.x + 20;
            block.y = target.y + BLOCK_HEIGHT - 10;
        }
        this.events.emit('block:snapped', { blockId, targetId, position });
    }
}
/* ── Built-in Block Palettes ──────────────────────────────────── */
const KID_BLOCK_PALETTES = [
    {
        category: 'motion',
        icon: '🏃',
        label: { en: 'Motion', pl: 'Ruch', de: 'Bewegung' },
        blocks: ['move_right', 'move_left', 'move_up', 'move_down', 'jump', 'set_speed', 'turn_left', 'turn_right'],
    },
    {
        category: 'looks',
        icon: '🎨',
        label: { en: 'Looks', pl: 'Wygląd', de: 'Aussehen' },
        blocks: ['set_color', 'set_size', 'show', 'hide', 'set_sprite', 'say'],
    },
    {
        category: 'events',
        icon: '⚡',
        label: { en: 'Events', pl: 'Zdarzenia', de: 'Ereignisse' },
        blocks: ['on_start', 'on_click', 'on_key_press', 'on_collision', 'on_timer'],
    },
    {
        category: 'control',
        icon: '🔄',
        label: { en: 'Control', pl: 'Sterowanie', de: 'Steuerung' },
        blocks: ['repeat', 'forever', 'if_then', 'if_then_else', 'wait'],
    },
    {
        category: 'sensing',
        icon: '👁️',
        label: { en: 'Sensing', pl: 'Wykrywanie', de: 'Erkennung' },
        blocks: ['touching', 'key_pressed', 'mouse_x', 'mouse_y', 'distance_to'],
    },
    {
        category: 'operators',
        icon: '➕',
        label: { en: 'Math', pl: 'Matematyka', de: 'Mathematik' },
        blocks: ['add', 'subtract', 'multiply', 'random', 'greater_than', 'less_than'],
    },
    {
        category: 'variables',
        icon: '📦',
        label: { en: 'Variables', pl: 'Zmienne', de: 'Variablen' },
        blocks: ['set_variable', 'change_variable', 'show_variable'],
    },
];

export { BlockEditor, GuidedWizard, KID_BLOCK_PALETTES };
//# sourceMappingURL=KidTools.js.map
