import { runAll, summarize, allChecks } from './framework.js';
import { runSceneGate } from './scene-gate.js';
import {
    varietyReportLines, songVarietyReportLines, experimentReportLines, poolSweepLines,
    decomposeReportLines,
} from './variety/print.js';

// Registering a phase's checks is a side effect of importing it.
import './phase0.js';
import './phase1.js';
import './phase2.js';
import './phase3.js';
import './phase4.js';
import './phase5.js';
import './phase6.js';
import './phase7.js';
import './phase8.js';
import './phase9.js';
import './phase10.js';
import './phase11.js';
import './phase12.js';

const out = document.getElementById('results');
const summaryEl = document.getElementById('summary');

function row(result) {
    const el = document.createElement('div');
    el.className = 'row ' + (result.pass ? 'pass' : result.manual ? 'manual' : 'fail');
    el.innerHTML = `
        <span class="badge">${result.pass ? 'PASS' : 'FAIL'}</span>
        <span class="phase">P${result.phase}</span>
        <span class="name">${result.name}</span>
        <span class="ms">${result.ms}ms</span>
        <div class="detail">${result.detail || ''}</div>`;
    out.appendChild(el);
}

async function main() {
    const params = new URLSearchParams(location.search);

    // Single-scene mode: the per-scene acceptance battery for one scene, in a
    // form that is cheap to run and cheap to read. This is the loop you are in
    // while writing a scene; running all ten phases to find out whether one new
    // shader is alive is both slow and a page of output to wade through.
    const sceneArg = params.get('scene');
    if (sceneArg) {
        summaryEl.textContent = `gating "${sceneArg}"…`;
        const { ok, lines } = runSceneGate(sceneArg);
        out.innerHTML = `<pre class="scene-gate">${lines.join('\n')}</pre>`;
        summaryEl.textContent = `${sceneArg}: ${ok ? 'PASS' : 'FAIL'} — ` +
            `${lines.filter((l) => l.startsWith('PASS')).length}/${lines.length} criteria`;
        summaryEl.className = ok ? 'ok' : 'bad';
        window.__CHECKS__ = { scene: sceneArg, ok, lines };
        window.__CHECKS_DONE__ = true;
        console.log('[scene-gate]', sceneArg, ok ? 'PASS' : 'FAIL', '\n' + lines.join('\n'));
        return;
    }

    // Seed variety mode: the full diagnostic table rather than a pass/fail.
    // Phase 12 gates on this measurement, but a gate answers "is it bad" and
    // this answers "which axis is flat", which is the question you have while
    // fixing it.
    //
    //   checks.html?variety=1              8 seeds, plus the whole library
    //   checks.html?variety=1&seeds=16     slower, tighter
    //   checks.html?variety=1&library=0    skip the library sweep (much faster)
    if (params.get('variety')) {
        summaryEl.textContent = 'seed variety: rendering seeds and sweeping the library…';
        const started = Date.now();
        const { lines, ok, headline } = await varietyReportLines({
            seeds: Number(params.get('seeds')) || 8,
            probes: Number(params.get('probes')) || 5,
            library: params.get('library') !== '0',
        });
        out.innerHTML = `<pre class="scene-gate">${lines.join('\n')}</pre>`;
        summaryEl.textContent = `${headline} · ${((Date.now() - started) / 1000).toFixed(1)}s`;
        summaryEl.className = ok ? 'ok' : 'bad';
        window.__CHECKS__ = { variety: true, ok, lines };
        window.__CHECKS_DONE__ = true;
        console.log('[variety]\n' + lines.join('\n'));
        return;
    }

    // Song variety mode: the same instrument, with the SONG as the variable.
    //
    //   checks.html?songs=1            6 songs from the bank
    //   checks.html?songs=1&count=10   more of the bank, slower
    if (params.get('songs')) {
        summaryEl.textContent = 'song variety: synthesising the bank and rendering each song…';
        const started = Date.now();
        const { lines, ok, headline } = await songVarietyReportLines({
            songs: Number(params.get('count')) || 6,
            probes: Number(params.get('probes')) || 5,
        });
        out.innerHTML = `<pre class="scene-gate">${lines.join('\n')}</pre>`;
        summaryEl.textContent = `${headline} · ${((Date.now() - started) / 1000).toFixed(1)}s`;
        summaryEl.className = ok ? 'ok' : 'bad';
        window.__CHECKS__ = { songs: true, ok, lines };
        window.__CHECKS_DONE__ = true;
        console.log('[song-variety]\n' + lines.join('\n'));
        return;
    }

    // The Epic 3 A/B: stages against comparable legacy scenes.
    //   checks.html?experiment=1
    if (params.get('experiment')) {
        summaryEl.textContent = 'epic 3 experiment: rendering three arms across the song bank…';
        const started = Date.now();
        const { lines, ok, headline } = await experimentReportLines({
            songs: Number(params.get('count')) || 6,
            probes: Number(params.get('probes')) || 4,
            repeats: Number(params.get('repeats')) || 3,
        });
        out.innerHTML = `<pre class="scene-gate">${lines.join('\n')}</pre>`;
        summaryEl.textContent = `${headline} · ${((Date.now() - started) / 1000).toFixed(1)}s`;
        summaryEl.className = ok ? 'ok' : 'bad';
        window.__CHECKS__ = { experiment: true, ok, lines };
        window.__CHECKS_DONE__ = true;
        console.log('[experiment]\n' + lines.join('\n'));
        return;
    }

    // checks.html?sweep=1 — how big a track's casting pool should be.
    if (params.get('sweep')) {
        summaryEl.textContent = 'sweeping casting pool size across the song bank…';
        const started = Date.now();
        const { lines, ok, headline } = await poolSweepLines({
            songs: Number(params.get('count')) || 6,
            sizes: params.get('sizes') ? params.get('sizes').split(',').map(Number) : null,
            repeats: Number(params.get('repeats')) || 1,
        });
        out.innerHTML = `<pre class="scene-gate">${lines.join('\n')}</pre>`;
        summaryEl.textContent = `${headline} · ${((Date.now() - started) / 1000).toFixed(1)}s`;
        summaryEl.className = ok ? 'ok' : 'bad';
        window.__CHECKS__ = { sweep: true, ok, lines };
        window.__CHECKS_DONE__ = true;
        console.log('[sweep]\n' + lines.join('\n'));
        return;
    }

    // checks.html?decompose=1 — identity against container, measured apart.
    if (params.get('decompose')) {
        summaryEl.textContent = 'decomposing identity vs container…';
        const started = Date.now();
        const { lines, ok, headline } = await decomposeReportLines({
            songs: Number(params.get('count')) || 6,
        });
        out.innerHTML = `<pre class="scene-gate">${lines.join('\n')}</pre>`;
        summaryEl.textContent = `${headline} · ${((Date.now() - started) / 1000).toFixed(1)}s`;
        summaryEl.className = ok ? 'ok' : 'bad';
        window.__CHECKS__ = { decompose: true, ok, lines };
        window.__CHECKS_DONE__ = true;
        console.log('[decompose]\n' + lines.join('\n'));
        return;
    }

    const phaseArg = params.get('phase');
    const phases = phaseArg ? phaseArg.split(',').map(Number) : null;
    const skipSlow = params.get('slow') !== '1';

    summaryEl.textContent = `running ${allChecks().length} checks…`;

    const results = await runAll({ phases, skipSlow, onResult: row });
    const s = summarize(results);

    summaryEl.textContent =
        `${s.passed}/${s.total} passed · ${s.failed} failed` + (skipSlow ? ' · slow checks skipped (?slow=1 to include)' : '');
    summaryEl.className = s.ok ? 'ok' : 'bad';

    // Read by the browser automation that drives these gates.
    window.__CHECKS__ = { results, summary: s };
    window.__CHECKS_DONE__ = true;
    console.log('[checks]', JSON.stringify(s, null, 2));
}

main();
