/**
 * templateScreenshots.js — генерирует PNG-скриншоты шаблонов offscreen.
 *
 * Запускается dev-кнопкой «Перегенерировать превью» в KubikonStudio.
 * Для каждого шаблона:
 *   1) создаёт оффскрин Babylon engine + scene
 *   2) грузит state шаблона через scene.loadFromState
 *   3) ждёт следующего кадра (модели подгружаются async)
 *   4) делает canvas.toDataURL('image/jpeg')
 *   5) триггерит скачивание файла
 *
 * Полученные PNG-файлы пользователь кладёт в
 *   public/assets/kubikon-templates/<id>.jpg
 * И они подхватываются как обычные статические картинки.
 */

import { BabylonScene } from '../editor/engine/BabylonScene';
import { TEMPLATES } from './templates';

const SCREENSHOT_W = 640;
const SCREENSHOT_H = 360;

/**
 * Сгенерировать скриншот одного шаблона. Возвращает Promise<dataUrl>.
 */
async function captureOne(template) {
    // Временный canvas, добавляем в DOM (Babylon engine требует видимый canvas
    // для GL-контекста — но мы скрываем визуально через position:absolute + opacity:0).
    const canvas = document.createElement('canvas');
    canvas.width = SCREENSHOT_W;
    canvas.height = SCREENSHOT_H;
    canvas.style.position = 'fixed';
    canvas.style.left = '-9999px';
    canvas.style.top = '0';
    canvas.style.width = `${SCREENSHOT_W}px`;
    canvas.style.height = `${SCREENSHOT_H}px`;
    canvas.style.opacity = '0';
    canvas.style.pointerEvents = 'none';
    canvas.tabIndex = -1;
    document.body.appendChild(canvas);

    let scene = null;
    try {
        scene = new BabylonScene(canvas);
        scene.init();

        // Стандартная камера для красивого ракурса (3/4 сверху)
        if (scene.camera) {
            scene.camera.position.set(60, 60, 60);
            // Нацеливаем камеру в (0, 5, 0) через yaw/pitch.
            // UniversalCamera использует rotation.y = yaw, rotation.x = pitch.
            const tx = 0, ty = 5, tz = 0;
            const dx = tx - scene.camera.position.x;
            const dy = ty - scene.camera.position.y;
            const dz = tz - scene.camera.position.z;
            scene.camera.rotation.y = Math.atan2(dx, dz);
            const horiz = Math.sqrt(dx * dx + dz * dz);
            scene.camera.rotation.x = -Math.atan2(dy, horiz);
            scene.camera.rotation.z = 0;
        }

        const state = template.build();
        await scene.loadFromState(state);

        // Прогреваем 3 кадра и ждём — модели подгружаются async, материалы
        // компилятся в первом render-loop.
        for (let i = 0; i < 8; i++) {
            scene.scene.render();
            await new Promise(res => requestAnimationFrame(res));
        }

        // Дополнительная пауза 500мс для GLB-моделей
        await new Promise(res => setTimeout(res, 500));
        for (let i = 0; i < 4; i++) {
            scene.scene.render();
            await new Promise(res => requestAnimationFrame(res));
        }

        // Снимок
        const dataUrl = canvas.toDataURL('image/jpeg', 0.85);
        return dataUrl;
    } finally {
        // Чистим
        try { scene?.dispose?.(); } catch (e) { /* ignore */ }
        try { document.body.removeChild(canvas); } catch (e) { /* ignore */ }
    }
}

/**
 * Триггер скачивания PNG-файла в браузере.
 */
function downloadDataUrl(dataUrl, filename) {
    const a = document.createElement('a');
    a.href = dataUrl;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
}

/**
 * Сгенерировать скриншоты ВСЕХ шаблонов и скачать их по одному.
 * Возвращает Promise который резолвится массивом dataUrl'ов.
 *
 * @param {(progress:{current:number,total:number,id:string}) => void} onProgress
 */
export async function generateAllTemplateScreenshots(onProgress) {
    const results = [];
    for (let i = 0; i < TEMPLATES.length; i++) {
        const tpl = TEMPLATES[i];
        if (onProgress) onProgress({ current: i + 1, total: TEMPLATES.length, id: tpl.id });
        // eslint-disable-next-line no-await-in-loop
        const dataUrl = await captureOne(tpl);
        downloadDataUrl(dataUrl, `${tpl.id}.jpg`);
        results.push({ id: tpl.id, dataUrl });
        // Небольшая пауза между генерациями чтобы браузер не тормозил
        // eslint-disable-next-line no-await-in-loop
        await new Promise(res => setTimeout(res, 200));
    }
    return results;
}
