'use strict';

var EventBus = require('../core/EventBus.js');

/* ────────────────────────────────────────────────────────────────
   Documentation Generator — LEGENDARY L10
   
   Auto-generates API docs from registered modules:
   • Markdown output
   • Interactive docs browser model (JSON structure)
   • Search index for API lookup
   • Example code linking
──────────────────────────────────────────────────────────────── */
/* ══════════════════════════════════════════════════════════════
   DocRegistry — Central API documentation registry
   ══════════════════════════════════════════════════════════════ */
class DocRegistry {
    constructor() {
        this.events = new EventBus.EventBus();
        this.modules = new Map();
    }
    /** Register a module's documentation. */
    registerModule(mod) {
        this.modules.set(mod.name, mod);
        this.events.emit('doc:module-registered', { name: mod.name });
    }
    /** Unregister a module. */
    unregisterModule(name) {
        this.modules.delete(name);
    }
    /** Get a module by name. */
    getModule(name) {
        return this.modules.get(name);
    }
    /** Get all registered modules. */
    getAllModules() {
        return Array.from(this.modules.values());
    }
    /** Get all modules in a category. */
    getModulesByCategory(category) {
        const result = [];
        for (const mod of this.modules.values()) {
            if (mod.category === category)
                result.push(mod);
        }
        return result;
    }
    /** Search across all docs. */
    search(query, maxResults = 20) {
        const q = query.toLowerCase();
        const results = [];
        for (const mod of this.modules.values()) {
            for (const member of mod.members) {
                const score = this.scoreMember(member, q);
                if (score > 0) {
                    results.push({ member, module: mod.name, score });
                }
            }
        }
        results.sort((a, b) => b.score - a.score);
        return results.slice(0, maxResults);
    }
    scoreMember(member, query) {
        let score = 0;
        const name = member.name.toLowerCase();
        // Exact name match
        if (name === query)
            return 100;
        // Name starts with query
        if (name.startsWith(query))
            score += 50;
        // Name contains query
        if (name.indexOf(query) >= 0)
            score += 30;
        // Description match
        if (member.description.toLowerCase().indexOf(query) >= 0)
            score += 10;
        // Tag match
        if (member.tags) {
            for (const tag of member.tags) {
                if (tag.toLowerCase().indexOf(query) >= 0)
                    score += 15;
            }
        }
        return score;
    }
    /** Get a specific member by name. */
    findMember(memberName) {
        const lower = memberName.toLowerCase();
        for (const mod of this.modules.values()) {
            for (const member of mod.members) {
                if (member.name.toLowerCase() === lower) {
                    return { member, module: mod.name };
                }
            }
        }
        return null;
    }
    /** Generate Markdown docs for a single module. */
    generateModuleMarkdown(moduleName) {
        const mod = this.modules.get(moduleName);
        if (!mod)
            return `Module "${moduleName}" not found.`;
        const lines = [];
        lines.push(`# ${mod.name}`);
        lines.push('');
        lines.push(mod.description);
        lines.push('');
        // Group by kind
        const groups = new Map();
        for (const m of mod.members) {
            let arr = groups.get(m.kind);
            if (!arr) {
                arr = [];
                groups.set(m.kind, arr);
            }
            arr.push(m);
        }
        const kindOrder = ['class', 'interface', 'type', 'function', 'constant', 'enum'];
        const kindTitles = {
            class: 'Classes',
            interface: 'Interfaces',
            type: 'Types',
            function: 'Functions',
            constant: 'Constants',
            enum: 'Enums',
        };
        for (const kind of kindOrder) {
            const members = groups.get(kind);
            if (!members)
                continue;
            lines.push(`## ${kindTitles[kind]}`);
            lines.push('');
            for (const m of members) {
                lines.push(`### ${m.name}`);
                if (m.deprecated)
                    lines.push(`> **Deprecated:** ${m.deprecated}`);
                lines.push('');
                if (m.signature)
                    lines.push('```typescript\n' + m.signature + '\n```');
                lines.push('');
                lines.push(m.description);
                lines.push('');
                if (m.params && m.params.length > 0) {
                    lines.push('**Parameters:**');
                    lines.push('');
                    lines.push('| Name | Type | Description |');
                    lines.push('|------|------|-------------|');
                    for (const p of m.params) {
                        const opt = p.optional ? ' (optional)' : '';
                        const def = p.defaultValue ? ` Default: \`${p.defaultValue}\`` : '';
                        lines.push(`| \`${p.name}\`${opt} | \`${p.type}\` | ${p.description}${def} |`);
                    }
                    lines.push('');
                }
                if (m.returns) {
                    lines.push(`**Returns:** ${m.returns}`);
                    lines.push('');
                }
                if (m.example) {
                    lines.push('**Example:**');
                    lines.push('```typescript');
                    lines.push(m.example);
                    lines.push('```');
                    lines.push('');
                }
                if (m.seeAlso && m.seeAlso.length > 0) {
                    lines.push(`**See also:** ${m.seeAlso.map(s => `\`${s}\``).join(', ')}`);
                    lines.push('');
                }
                if (m.since) {
                    lines.push(`*Since: ${m.since}*`);
                    lines.push('');
                }
                lines.push('---');
                lines.push('');
            }
        }
        return lines.join('\n');
    }
    /** Generate full Markdown documentation for all modules. */
    generateFullMarkdown() {
        const lines = [];
        lines.push('# nice2dev Game Engine — API Reference');
        lines.push('');
        // Table of contents
        lines.push('## Table of Contents');
        lines.push('');
        const categories = ['core', 'ecs', 'rendering', 'physics', 'audio', 'input', 'ui', 'scene', 'multiplayer', 'editor', 'legendary', 'other'];
        for (const cat of categories) {
            const mods = this.getModulesByCategory(cat);
            if (mods.length === 0)
                continue;
            lines.push(`### ${cat.charAt(0).toUpperCase() + cat.slice(1)}`);
            for (const mod of mods) {
                lines.push(`- [${mod.name}](#${mod.name.toLowerCase().replace(/[^a-z0-9]+/g, '-')})`);
            }
            lines.push('');
        }
        // Module docs
        for (const mod of this.modules.values()) {
            lines.push(this.generateModuleMarkdown(mod.name));
            lines.push('');
        }
        return lines.join('\n');
    }
    /** Generate a JSON index for interactive docs browser. */
    generateSearchIndex() {
        var _a;
        const index = [];
        for (const mod of this.modules.values()) {
            for (const m of mod.members) {
                index.push({
                    name: m.name,
                    module: mod.name,
                    kind: m.kind,
                    description: m.description,
                    tags: (_a = m.tags) !== null && _a !== void 0 ? _a : [],
                });
            }
        }
        return index;
    }
    /** Total number of documented members. */
    get totalMembers() {
        let count = 0;
        for (const mod of this.modules.values())
            count += mod.members.length;
        return count;
    }
    /** Reset. */
    clear() {
        this.modules.clear();
    }
}
/* ══════════════════════════════════════════════════════════════
   Built-in ECS Module Docs (example)
   ══════════════════════════════════════════════════════════════ */
const DOCS_ECS = {
    name: 'ECS',
    category: 'ecs',
    description: 'Entity-Component-System architecture. The core of the game engine.',
    members: [
        {
            name: 'World',
            kind: 'class',
            description: 'The ECS world manages entities, components, and systems.',
            signature: 'class World',
            tags: ['ecs', 'entity', 'system'],
            example: "const world = new World();\nconst id = world.createEntity();\nworld.addComponent(id, 'Transform', { x: 0, y: 0 });\nworld.addSystem('move', (dt, w) => { /* ... */ });",
            seeAlso: ['System', 'Entity'],
        },
        {
            name: 'World.createEntity',
            kind: 'function',
            description: 'Create a new entity and return its numeric ID.',
            signature: 'createEntity(): number',
            returns: 'The new entity ID.',
            tags: ['ecs', 'entity', 'create'],
        },
        {
            name: 'World.addComponent',
            kind: 'function',
            description: 'Add a component to an entity.',
            signature: "addComponent(entityId: number, type: string, data: object): void",
            params: [
                { name: 'entityId', type: 'number', description: 'The entity to add the component to.' },
                { name: 'type', type: 'string', description: "Component type name (e.g. 'Transform', 'Sprite')." },
                { name: 'data', type: 'object', description: 'Component data.' },
            ],
            tags: ['ecs', 'component'],
        },
        {
            name: 'World.getComponent',
            kind: 'function',
            description: 'Get a single component from an entity.',
            signature: "getComponent<T>(entityId: number, type: string): T | undefined",
            params: [
                { name: 'entityId', type: 'number', description: 'Entity ID.' },
                { name: 'type', type: 'string', description: 'Component type name.' },
            ],
            returns: 'The component data or undefined.',
            tags: ['ecs', 'component', 'query'],
        },
        {
            name: 'World.query',
            kind: 'function',
            description: 'Query entities that have all specified component types.',
            signature: "query(...types: string[]): number[]",
            params: [
                { name: 'types', type: 'string[]', description: 'Component types (spread args, not array!).' },
            ],
            returns: 'Array of entity IDs matching the query.',
            example: "const ids = world.query('Transform', 'Sprite');\n// NOT world.query(['Transform', 'Sprite'])",
            tags: ['ecs', 'query', 'entity'],
        },
        {
            name: 'World.addSystem',
            kind: 'function',
            description: 'Register a system that runs every frame.',
            signature: "addSystem(name: string, updateFn: (dt: number, world: World) => void, priority?: number): void",
            params: [
                { name: 'name', type: 'string', description: 'System name.' },
                { name: 'updateFn', type: 'function', description: 'Update function called each frame.' },
                { name: 'priority', type: 'number', description: 'Execution order (lower = earlier).', optional: true },
            ],
            tags: ['ecs', 'system'],
        },
        {
            name: 'World.destroyEntity',
            kind: 'function',
            description: 'Destroy an entity and all its components.',
            signature: 'destroyEntity(entityId: number): void',
            tags: ['ecs', 'entity', 'destroy'],
        },
        {
            name: 'World.allEntities',
            kind: 'function',
            description: 'Returns all entity IDs. Note: use allEntities(), NOT getAllEntities().',
            signature: 'allEntities(): number[]',
            returns: 'Array of all entity IDs.',
            tags: ['ecs', 'entity', 'query'],
        },
    ],
};
const DOCS_RENDERING = {
    name: 'Rendering',
    category: 'rendering',
    description: '2D Canvas rendering pipeline with sprite batching, cameras, and post-processing.',
    members: [
        {
            name: 'Camera2D',
            kind: 'class',
            description: '2D camera with zoom, pan, and shake support.',
            signature: 'class Camera2D',
            tags: ['camera', 'rendering', '2d'],
            example: "const cam = new Camera2D(canvas.width, canvas.height);\ncam.follow(playerEntity);\ncam.shake(5, 300); // intensity=5, duration=300ms",
            seeAlso: ['Renderer2D', 'SpriteRenderer'],
        },
        {
            name: 'Camera2D.worldToScreen',
            kind: 'function',
            description: 'Convert world coordinates to screen coordinates.',
            signature: 'worldToScreen(worldPos: Vec2): Vec2',
            params: [
                { name: 'worldPos', type: 'Vec2', description: 'Takes a Vec2, not separate x,y!' },
            ],
            returns: 'Screen-space Vec2.',
            tags: ['camera', 'coordinate'],
        },
    ],
};

exports.DOCS_ECS = DOCS_ECS;
exports.DOCS_RENDERING = DOCS_RENDERING;
exports.DocRegistry = DocRegistry;
//# sourceMappingURL=DocGenerator.js.map
