/**
 * Сниппеты для Monaco-редактора скриптов (Фаза 6.1.3).
 *
 * Каждый сниппет — короткое имя (триггер) + готовый код с табстопами
 * (`${1:placeholder}`, `${2:...}`), который раскрывается по Tab.
 *
 * Регистрируется один раз через monaco.languages.registerCompletionItemProvider
 * для языка 'javascript' в ScriptEditor.jsx.
 *
 * Цель Фазы 6.1: новый юзер пишет первый скрипт и видит готовые шаблоны
 * на типичные задачи, не изобретая велосипед.
 */
export const SCRIPT_SNIPPETS = [
    {
        label: 'on touch',
        detail: 'Игрок коснулся объекта (для скрипта на блоке/примитиве/модели)',
        body: [
            "game.self.onTouch(() => {",
            "\t${1:// твой код когда игрок коснулся}",
            "\tgame.ui.showText('Привет!', 2);",
            "});",
        ],
    },
    {
        label: 'on click',
        detail: 'Игрок кликнул по объекту (луч от прицела)',
        body: [
            "game.self.onClick(() => {",
            "\t${1:// действие на клик}",
            "});",
        ],
    },
    {
        label: 'on key',
        detail: 'Нажатие клавиши',
        body: [
            "game.onKey('${1:e}', () => {",
            "\t${2:// действие на клавишу}",
            "});",
        ],
    },
    {
        label: 'on tick',
        detail: 'Каждый кадр (для постоянной логики)',
        body: [
            "game.onTick((dt) => {",
            "\t${1:// логика каждый кадр; dt — секунды с прошлого кадра}",
            "});",
        ],
    },
    {
        label: 'tween',
        detail: 'Плавный переход свойств (движение, поворот, цвет)',
        body: [
            "game.tween(${1:ref}, { ${2:y: 5} }, {",
            "\tduration: ${3:1},",
            "\teasing: '${4|ease,linear,bounce,elastic,back|}',",
            "\tonDone: () => { ${5:// после завершения} },",
            "});",
        ],
    },
    {
        label: 'after',
        detail: 'Выполнить через N секунд',
        body: [
            "game.after(${1:3}, () => {",
            "\t${2:game.ui.showText('Прошло 3 секунды', 2);}",
            "});",
        ],
    },
    {
        label: 'every',
        detail: 'Повторять каждые N секунд',
        body: [
            "const ${1:timerId} = game.every(${2:1}, () => {",
            "\t${3:// тик}",
            "});",
            "// game.cancel(${1:timerId}); — остановить",
        ],
    },
    {
        label: 'door',
        detail: 'Дверь, открывающаяся по нажатию E',
        body: [
            "// Скрипт привязать к двери. Клавиша E открывает.",
            "let isOpen = false;",
            "game.self.onInteract(() => {",
            "\tconst targetY = isOpen ? 0 : ${1:Math.PI / 2};",
            "\tgame.tween(game.self.ref, { rotationY: targetY }, { duration: 0.5, easing: 'ease' });",
            "\tisOpen = !isOpen;",
            "}, { text: isOpen ? 'Закрыть' : 'Открыть', distance: 4, key: 'e' });",
        ],
    },
    {
        label: 'chest',
        detail: 'Сундук с наградой',
        body: [
            "let opened = false;",
            "game.self.onInteract(() => {",
            "\tif (opened) return;",
            "\topened = true;",
            "\tgame.ui.showText('Ты получил ${1:сокровище}!', 2);",
            "\tgame.sound.play('coin');",
            "\tgame.economy.reward('${2:found_chest_1}');",
            "}, { text: 'Открыть сундук', key: 'e' });",
        ],
    },
    {
        label: 'coin',
        detail: 'Монета — собирается и исчезает при касании',
        body: [
            "game.self.onTouch(() => {",
            "\tgame.sound.play('coin');",
            "\tgame.ui.score = (game.ui.score || 0) + ${1:1};",
            "\tgame.self.delete();",
            "});",
        ],
    },
    {
        label: 'spike',
        detail: 'Шип — наносит урон при касании',
        body: [
            "game.self.onTouch(() => {",
            "\tgame.player.damage(${1:25});",
            "});",
        ],
    },
    {
        label: 'portal',
        detail: 'Телепорт игрока в точку',
        body: [
            "game.self.onTouch(() => {",
            "\tgame.player.teleport(${1:0}, ${2:5}, ${3:0});",
            "\tgame.sound.play('pickup');",
            "});",
        ],
    },
    {
        label: 'npc',
        detail: 'Дружественный NPC с патрулём',
        body: [
            "const ${1:trader} = game.scene.spawnNpc('${2:character-a}', {",
            "\tx: ${3:0}, y: ${4:1}, z: ${5:5},",
            "\tname: '${6:Торговец}',",
            "});",
            "${1:trader}.say('Привет, путник!', 3);",
            "// каждые 5 секунд идёт в случайную точку",
            "game.every(5, () => {",
            "\tconst x = game.random(-10, 10);",
            "\tconst z = game.random(-10, 10);",
            "\t${1:trader}.moveTo(x, z);",
            "});",
        ],
    },
    {
        label: 'enemy',
        detail: 'Враг с патрулём вокруг точки',
        body: [
            "const ${1:enemy} = game.scene.spawnNpc('${2:zombie}', {",
            "\tx: ${3:0}, y: ${4:1}, z: ${5:0},",
            "\thp: 50,",
            "});",
            "${1:enemy}.follow('player');",
            "${1:enemy}.onDeath(() => {",
            "\tgame.ui.showText('Враг повержен!', 1.5);",
            "\tgame.ui.score = (game.ui.score || 0) + 10;",
            "});",
        ],
    },
    {
        label: 'quest',
        detail: 'Простой квест с шагами',
        body: [
            "let step = 1;",
            "function showQuest() {",
            "\tconst steps = {",
            "\t\t1: 'Найди ${1:сундук}',",
            "\t\t2: 'Принеси ${2:торговцу}',",
            "\t\t3: 'Готово!',",
            "\t};",
            "\tgame.ui.set('quest', `Квест: ${steps[step] || ''}`, { x: 50, y: 10, color: '#ffd700' });",
            "}",
            "showQuest();",
            "// продвинуть шаг — game.broadcast('quest_step', { step: 2 });",
            "game.onMessage('quest_step', (data) => {",
            "\tstep = data.step;",
            "\tshowQuest();",
            "});",
        ],
    },
    {
        label: 'save',
        detail: 'Сохранить прогресс игрока',
        body: [
            "// Прочитать сохранение",
            "game.save.get('progress', (data) => {",
            "\tconst level = (data && data.level) || 1;",
            "\tgame.ui.showText(`Уровень: ${level}`, 2);",
            "});",
            "// Записать (после успеха)",
            "game.save.merge('progress', {",
            "\tincrement: { level: 1, coins: ${1:10} },",
            "\tmax: { bestTime: ${2:47.3} },",
            "});",
        ],
    },
    {
        label: 'spawn',
        detail: 'Создать объект на сцене',
        body: [
            "const ${1:obj} = game.scene.spawn('primitive:${2|cube,sphere,cylinder,cone|}', {",
            "\tx: ${3:0}, y: ${4:5}, z: ${5:0},",
            "\tcolor: '${6:#ff0000}',",
            "\tname: '${7:MyObject}',",
            "});",
        ],
    },
    // === UI-шаблоны (Phase 6.3.5) ===
    {
        label: 'ui-mainmenu',
        detail: 'Главное меню: заголовок + 3 кнопки по центру',
        body: [
            "// Главное меню (Phase 6.3 шаблон)",
            "const menu = game.gui.create('frame', {",
            "\tname: 'MainMenu',",
            "\tx: 50, y: 50, w: 30, h: 50,",
            "\tanchor: 'center', anchorPoint: { x: 0.5, y: 0.5 },",
            "\tbgColor: '#1a1a2e', bgOpacity: 0.9,",
            "\tborderColor: '#4f74ff', borderWidth: 2, borderRadius: 12,",
            "\tlayout: 'vertical', layoutGap: 4, layoutPad: 5,",
            "});",
            "game.gui.create('text', {",
            "\tparentId: menu, text: '${1:Игра}',",
            "\ttextColor: '#ffd166', textSize: 28, fontWeight: 800, h: 15,",
            "});",
            "const playBtn = game.gui.create('button', { parentId: menu, text: 'Играть', h: 12 });",
            "const settBtn = game.gui.create('button', { parentId: menu, text: 'Настройки', h: 12 });",
            "const exitBtn = game.gui.create('button', { parentId: menu, text: 'Выйти', h: 12 });",
            "game.gui.onClick(playBtn, () => { game.gui.hide(menu); });",
        ],
    },
    {
        label: 'ui-hp-bar',
        detail: 'HP-бар + патроны в углу (HUD)',
        body: [
            "// HP-бар (Phase 6.3 шаблон)",
            "const hpBg = game.gui.create('frame', {",
            "\tname: 'HpBg', x: 2, y: 2, w: 22, h: 4, anchor: 'top-left',",
            "\tbgColor: '#222', bgOpacity: 0.8, borderRadius: 6,",
            "});",
            "const hpFill = game.gui.create('frame', {",
            "\tparentId: hpBg, x: 0, y: 0, w: 100, h: 100, anchor: 'top-left',",
            "\tanchorPoint: { x: 0, y: 0 },",
            "\tbgColor: '#22d97a', borderRadius: 6,",
            "});",
            "game.onHpChange(() => {",
            "\tconst pct = (game.player.hp / game.player.maxHp) * 100;",
            "\tgame.tween(hpFill, { w: pct }, { duration: 0.3, easing: 'ease' });",
            "});",
        ],
    },
    {
        label: 'ui-shop',
        detail: 'Магазин со списком предметов (Grid)',
        body: [
            "// Магазин со списком (Phase 6.3 шаблон)",
            "const shop = game.gui.create('frame', {",
            "\tname: 'Shop', x: 50, y: 50, w: 60, h: 70, anchor: 'center',",
            "\tbgColor: '#222', bgOpacity: 0.95, borderRadius: 12,",
            "\tlayout: 'grid', layoutCellW: 18, layoutCellH: 22, layoutCols: 4,",
            "\tlayoutGap: 2, layoutPad: 3,",
            "});",
            "const items = ${1:['меч', 'лук', 'щит', 'зелье', 'кольцо', 'плащ', 'броня', 'еда']};",
            "items.forEach((name) => {",
            "\tconst slot = game.gui.create('button', { parentId: shop, text: name, bgColor: '#3a3a5a' });",
            "\tgame.gui.onClick(slot, () => game.log('купил:', name));",
            "});",
        ],
    },
    {
        label: 'ui-dialog',
        detail: 'Диалог NPC: рамка + текст + 2 кнопки',
        body: [
            "// Диалог NPC (Phase 6.3 шаблон)",
            "const dlg = game.gui.create('frame', {",
            "\tname: 'Dialog', x: 50, y: 80, w: 60, h: 25, anchor: 'center',",
            "\tbgColor: '#1a1a2e', bgOpacity: 0.95, borderColor: '#ffd166', borderWidth: 2, borderRadius: 12,",
            "});",
            "game.gui.create('text', {",
            "\tparentId: dlg, x: 50, y: 25, w: 90, h: 40, anchor: 'center',",
            "\ttext: '${1:Привет, путник!}', textColor: '#fff', textSize: 18,",
            "});",
            "const yes = game.gui.create('button', {",
            "\tparentId: dlg, x: 30, y: 75, w: 30, h: 20, anchor: 'center', text: '${2:Да}',",
            "});",
            "const no = game.gui.create('button', {",
            "\tparentId: dlg, x: 70, y: 75, w: 30, h: 20, anchor: 'center', text: '${3:Нет}',",
            "});",
            "game.gui.onClick(yes, () => game.gui.remove(dlg));",
            "game.gui.onClick(no, () => game.gui.remove(dlg));",
        ],
    },
    {
        label: 'ui-victory',
        detail: 'Экран победы с tween-появлением',
        body: [
            "// Победа (Phase 6.3 шаблон)",
            "function showVictory(score) {",
            "\tconst panel = game.gui.create('frame', {",
            "\t\tname: 'Victory', x: 50, y: 50, w: 40, h: 30, anchor: 'center',",
            "\t\tbgColor: '#22d97a', bgOpacity: 0, borderRadius: 16,",
            "\t});",
            "\tgame.gui.create('text', {",
            "\t\tparentId: panel, x: 50, y: 30, w: 90, h: 30, anchor: 'center',",
            "\t\ttext: '\\u041f\\u041e\\u0411\\u0415\\u0414\\u0410!', textColor: '#fff', textSize: 36, fontWeight: 800,",
            "\t});",
            "\tgame.gui.create('text', {",
            "\t\tparentId: panel, x: 50, y: 70, w: 90, h: 20, anchor: 'center',",
            "\t\ttext: 'Счёт: ' + score, textColor: '#fff', textSize: 18,",
            "\t});",
            "\t// Tween-появление",
            "\tgame.tween(panel, { bgOpacity: 0.95 }, { duration: 0.5, easing: 'ease' });",
            "}",
            "showVictory(${1:100});",
        ],
    },
    {
        label: 'ui-inventory',
        detail: 'Инвентарь 4×3 grid с tooltip',
        body: [
            "// Инвентарь (Phase 6.3 шаблон)",
            "const inv = game.gui.create('frame', {",
            "\tname: 'Inventory', x: 50, y: 50, w: 50, h: 60, anchor: 'center',",
            "\tbgColor: '#222', bgOpacity: 0.95, borderRadius: 12,",
            "\tlayout: 'grid', layoutCellW: 22, layoutCellH: 30, layoutCols: 4,",
            "});",
            "for (let i = 0; i < ${1:12}; i++) {",
            "\tgame.gui.create('button', { parentId: inv, text: '[пусто]', bgColor: '#3a3a5a' });",
            "}",
        ],
    },
    {
        label: 'ui-leaderboard',
        detail: 'Лидерборд: топ-N игроков',
        body: [
            "// Лидерборд (Phase 6.3 шаблон)",
            "const lb = game.gui.create('frame', {",
            "\tname: 'Leaderboard', x: 98, y: 50, w: 22, h: 60, anchor: 'top-right',",
            "\tanchorPoint: { x: 1, y: 0.5 },",
            "\tbgColor: '#1a1a2e', bgOpacity: 0.9, borderRadius: 10,",
            "\tlayout: 'vertical', layoutGap: 1, layoutPad: 3,",
            "});",
            "game.gui.create('text', {",
            "\tparentId: lb, text: 'ТОП', textColor: '#ffd166', textSize: 18, h: 8, fontWeight: 800,",
            "});",
            "game.save.leaderboard.top('${1:score}', 10, (rows) => {",
            "\trows.forEach((r, i) => {",
            "\t\tgame.gui.create('text', {",
            "\t\t\tparentId: lb, h: 8,",
            "\t\t\ttext: `${i+1}. ${r.username}: ${r.value}`,",
            "\t\t\ttextColor: '#fff', textSize: 13, textAlign: 'left',",
            "\t\t});",
            "\t});",
            "});",
        ],
    },
    {
        label: 'ui-loading',
        detail: 'Загрузочный экран с прогресс-баром',
        body: [
            "// Загрузочный экран (Phase 6.3 шаблон)",
            "const overlay = game.gui.create('frame', {",
            "\tname: 'Loading', x: 50, y: 50, w: 100, h: 100, anchor: 'center',",
            "\tbgColor: '#000', bgOpacity: 0.85,",
            "});",
            "game.gui.create('text', {",
            "\tparentId: overlay, x: 50, y: 40, w: 60, h: 10, anchor: 'center',",
            "\ttext: '${1:Загрузка...}', textColor: '#ffd166', textSize: 24,",
            "});",
            "const barBg = game.gui.create('frame', {",
            "\tparentId: overlay, x: 50, y: 55, w: 40, h: 4, anchor: 'center',",
            "\tbgColor: '#222', borderRadius: 4,",
            "});",
            "const bar = game.gui.create('frame', {",
            "\tparentId: barBg, x: 0, y: 0, w: 0, h: 100, anchor: 'top-left',",
            "\tanchorPoint: { x: 0, y: 0 },",
            "\tbgColor: '#22d97a', borderRadius: 4,",
            "});",
            "// Tween-заполнение",
            "game.tween(bar, { w: 100 }, { duration: ${2:3}, onDone: () => game.gui.remove(overlay) });",
        ],
    },
    {
        label: 'ui-settings',
        detail: 'Настройки: громкость + графика',
        body: [
            "// Настройки (Phase 6.3 шаблон)",
            "const set = game.gui.create('frame', {",
            "\tname: 'Settings', x: 50, y: 50, w: 40, h: 50, anchor: 'center',",
            "\tbgColor: '#1a1a2e', bgOpacity: 0.95, borderRadius: 12,",
            "\tlayout: 'vertical', layoutGap: 3, layoutPad: 5,",
            "});",
            "game.gui.create('text', { parentId: set, text: 'Настройки', textColor: '#ffd166', textSize: 22, h: 12 });",
            "const volBtn = game.gui.create('button', { parentId: set, text: 'Звук: ВКЛ', h: 10 });",
            "const muted = { value: false };",
            "game.gui.onClick(volBtn, () => {",
            "\tmuted.value = !muted.value;",
            "\tgame.audio.setMuted(muted.value);",
            "\tgame.gui.update(volBtn, { text: muted.value ? 'Звук: ВЫКЛ' : 'Звук: ВКЛ' });",
            "});",
            "const closeBtn = game.gui.create('button', { parentId: set, text: 'Закрыть', h: 10 });",
            "game.gui.onClick(closeBtn, () => game.gui.remove(set));",
        ],
    },
    {
        label: 'ui-card',
        detail: 'Карточка персонажа: аватар + ник + статы',
        body: [
            "// Карточка персонажа (Phase 6.3 шаблон)",
            "const card = game.gui.create('frame', {",
            "\tname: 'Card', x: 2, y: 50, w: 18, h: 30, anchor: 'left',",
            "\tanchorPoint: { x: 0, y: 0.5 },",
            "\tbgColor: '#1a1a2e', bgOpacity: 0.9, borderRadius: 10,",
            "});",
            "game.gui.create('image', {",
            "\tparentId: card, x: 50, y: 25, w: 50, h: 40, anchor: 'center',",
            "\timageUrl: '${1:}', bgColor: '#3a3a5a',",
            "});",
            "game.gui.create('text', {",
            "\tparentId: card, x: 50, y: 60, w: 90, h: 12, anchor: 'center',",
            "\ttext: '${2:Стив}', textColor: '#fff', textSize: 16, fontWeight: 800,",
            "});",
            "game.gui.create('text', {",
            "\tparentId: card, x: 50, y: 80, w: 90, h: 12, anchor: 'center',",
            "\ttext: 'HP: ' + game.player.hp + ' / ' + game.player.maxHp,",
            "\ttextColor: '#22d97a', textSize: 13,",
            "});",
        ],
    },
    {
        label: 'loading.transition',
        detail: 'Экран загрузки: переход на новый уровень (фейковый прогресс)',
        body: [
            "await game.loading.transition({",
            "\tcover: { sceneSnapshot: true },   // снимок текущей сцены как превью",
            "\tduration: ${1:4},                 // секунд заполняется бар",
            "\tskipButton: true,",
            "\tspinner: true,",
            "});",
            "${2:game.player.teleport(100, 1, 100);}   // после загрузки",
        ],
    },
    {
        label: 'loading.realProgress',
        detail: 'Экран загрузки: реальный прогресс подгрузки (ручной setProgress)',
        body: [
            "const lo = game.loading.show({ progressBar: true, spinner: true });",
            "const total = ${1:10};",
            "let i = 0;",
            "const step = () => {",
            "\ti++;",
            "\t${2:// подгрузить i-й ресурс}",
            "\tlo.setProgress(i / total);",
            "\tif (i < total) game.after(${3:0.2}, step); else lo.close();",
            "};",
            "step();",
        ],
    },
    {
        label: 'loading.minigame',
        detail: 'Экран загрузки: короткая пауза перед мини-игрой',
        body: [
            "await game.loading.transition({",
            "\ttext: '${1:Загружаем мини-игру...}',",
            "\tduration: ${2:1.5},",
            "\tskipButton: false,",
            "});",
            "${3:// запустить мини-игру}",
        ],
    },
];

/**
 * Регистрируем сниппеты в Monaco. Вызывается ОДИН раз для всего приложения
 * при первом монтировании редактора.
 */
export function registerSnippets(monaco) {
    if (monaco.__kubikonSnippetsRegistered) return;
    monaco.__kubikonSnippetsRegistered = true;
    monaco.languages.registerCompletionItemProvider('javascript', {
        triggerCharacters: [],
        provideCompletionItems(model, position) {
            const word = model.getWordUntilPosition(position);
            const range = {
                startLineNumber: position.lineNumber,
                endLineNumber: position.lineNumber,
                startColumn: word.startColumn,
                endColumn: word.endColumn,
            };
            return {
                suggestions: SCRIPT_SNIPPETS.map((s) => ({
                    label: s.label,
                    kind: monaco.languages.CompletionItemKind.Snippet,
                    detail: s.detail,
                    documentation: { value: '```js\n' + s.body.join('\n') + '\n```' },
                    insertText: s.body.join('\n'),
                    insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
                    range,
                })),
            };
        },
    });
}
