#!/usr/bin/env node
/**
 * pres-showcase — generate a showcase deck for every theme.
 *
 * Each theme gets its own .pptx file demonstrating every archetype
 * the design system ships. Open them in PowerPoint / Keynote / Google
 * Slides to visually QA the system. When you change a theme / token /
 * archetype, re-run this and diff the output decks visually.
 *
 *   node scripts/verify/pres-showcase.mjs              # all themes
 *   node scripts/verify/pres-showcase.mjs tech-bold    # one theme
 *   node scripts/verify/pres-showcase.mjs --out=foo/   # custom dir
 *
 * Also produces a per-theme "compact" deck (8 slides) used in the
 * agent-facing example library.
 */
import path from 'path';
import fs from 'fs/promises';
import { fileURLToPath } from 'url';

import { buildThemedPres, listSystem } from '../../src/tools/office/pres/index.js';
import { readPres } from '../../src/tools/office/pres/edit/read.js';
import { fillPres } from '../../src/tools/office/pres/edit/fill.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname  = path.dirname(__filename);
const args = process.argv.slice(2);

const outFlag = args.find(a => a.startsWith('--out='));
const outDir  = outFlag
  ? path.resolve(outFlag.slice('--out='.length))
  : path.resolve(__dirname, '../../bench-out/pres-showcase');

const onlyTheme = args.find(a => !a.startsWith('-'));

const SAMPLE_CHART_DATA = {
  donut: {
    type: 'donut',
    data: [
      { label: 'Pro',         value: 62 },
      { label: 'Team',        value: 28 },
      { label: 'Enterprise',  value: 10 },
    ],
  },
  bar: {
    type: 'bar',
    categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
    series: [
      { name: 'Self-serve',  data: [120, 145, 168, 182, 207] },
      { name: 'Sales-led',   data: [40,  58,  72,  91,  112] },
    ],
  },
  line: {
    type: 'line',
    categories: ['Q1 24', 'Q2 24', 'Q3 24', 'Q4 24', 'Q1 25', 'Q2 25', 'Q3 25', 'Q4 25'],
    series: [
      { name: 'Net retention', data: [102, 108, 115, 121, 128, 133, 138, 142] },
    ],
  },
};

function showcaseSlides(themeId) {
  const slides = [
    // Hero
    {
      archetype: 'hero',
      eyebrow: `Theme · ${themeId}`,
      title: 'Designed by default.',
      subtitle: 'Pick a theme, pick an archetype per slide, fill the slots. The system handles the rest — typography, colour, spacing, chrome, charts.',
      author: 'Loxia presentation system',
      date: new Date().toISOString().slice(0, 10),
    },
    // Agenda
    {
      archetype: 'agenda',
      title: 'What you\'re looking at',
      items: [
        { title: 'Section transitions',          hint: 'sectionHeader archetype' },
        { title: 'Stats that breathe',           hint: 'statCallout' },
        { title: 'Side-by-side narrative',       hint: 'twoColText' },
        { title: 'Charts inside the same grid',  hint: 'twoColChart' },
        { title: 'Quotes that land',             hint: 'quote' },
        { title: 'Tables that don\'t feel like Excel', hint: 'table' },
        { title: 'Closing the loop',             hint: 'closing' },
      ],
    },
    // Section
    {
      archetype: 'sectionHeader',
      number: '01',
      title: 'Headlines & callouts',
      subtitle: 'Big numbers, single-message slides, the stuff a deck rides on.',
    },
    // Big stat (NEW archetype) — single number filling the slide
    {
      archetype: 'bigStat',
      eyebrow: 'Headline metric',
      stat: '47',
      unit: '%',
      label: 'Less time the agent spends wrestling pptxgenjs',
      delta: { value: '+12pp vs Q3', direction: 'up' },
      tags: [
        { label: 'design system', kind: 'highlight' },
        { label: 'tested',         kind: 'subtle' },
      ],
      footnote: 'vs. hand-placing every text box in a blank deck.',
    },
    // Stat trio (NEW archetype) — KPI dashboard glance
    {
      archetype: 'statTrio',
      title: 'The dashboard view',
      subtitle: 'Three KPI cards in one row, deltas + units styled by the theme.',
      stats: [
        { label: 'Themes',     value: '3',  delta: '+3 since v1', deltaDirection: 'up' },
        { label: 'Archetypes', value: '15', delta: '+3 modern',   deltaDirection: 'up' },
        { label: 'Backgrounds', value: '6', delta: '+6 styles',   deltaDirection: 'up' },
      ],
      footnote: 'Counted from src/tools/office/pres/',
    },
    // Comparison grid (NEW archetype) — 2x2 cells
    {
      archetype: 'comparisonGrid',
      title: 'Before vs after',
      subtitle: 'Same agent, same prompt, different system.',
      cells: [
        { eyebrow: 'Before', headline: 'Hand-placed',  accent: 'subtle',    body: 'Agent picks coordinates, colours, fonts ad-hoc. Decks come out inconsistent — some slides feel finished, others feel like wireframes.' },
        { eyebrow: 'After',  headline: 'Curated',       accent: 'primary',   body: 'Agent picks a theme + an archetype per slide. Every choice is from a vocabulary that\'s already been designed to work together.' },
        { eyebrow: 'Before', headline: '60pt titles',   accent: 'subtle',    body: 'Hero titles read fine on a laptop but disappear on a projector. Body text feels like a Word document.' },
        { eyebrow: 'After',  headline: '120pt display', accent: 'highlight', body: 'Hero titles fill the slide. Body copy is conference-readable. Type scale and spacing are tuned per theme.' },
      ],
    },
    // Bullets
    {
      archetype: 'bullets',
      title: 'What each slide is about',
      subtitle: 'Pick the archetype; the rest is rhythm.',
      items: [
        'Every archetype reads its colour from one of 6 semantic palette roles.',
        'Spacing comes from one of three presets — tight / cozy / airy.',
        'Shape comes from one of four — sharp / soft / round / pill.',
        'Background style is the slide\'s mood; theme default per slide.',
        'Charts inherit the theme\'s palette + gridline policy automatically.',
      ],
    },
    // Two-col text
    {
      archetype: 'twoColText',
      title: 'Two ways to think about it',
      left:  { headline: 'Before',
        body: 'Agent picks coordinates, colours, fonts ad-hoc. Decks come out inconsistent — some slides feel finished, others feel like wireframes. The deck never reads as one document.' },
      right: { headline: 'After',
        body: 'Agent picks a theme + a slot per slide. Every choice is from a curated set. The deck reads as one document because every choice is hand-tuned in advance.' },
    },
    // Section transition (with theme-default background style)
    {
      archetype: 'sectionHeader',
      number: '02',
      title: 'Charts & data',
      subtitle: 'Theme-aware chart styling, no manual colour-picking.',
    },
    // Two-col chart — donut
    {
      archetype: 'twoColChart',
      title: 'Revenue mix',
      leftText: {
        headline: 'Composition shifted',
        body: 'Self-serve became the dominant motion — but enterprise contracts now have the largest average annual contract value.',
      },
      chart: SAMPLE_CHART_DATA.donut,
    },
    // Two-col chart — bar
    {
      archetype: 'twoColChart',
      title: 'Acquisition over time',
      leftText: {
        headline: 'Both motions compound',
        body: 'Self-serve growth is the engine; sales-led growth amplifies it as the enterprise pipeline matures.',
      },
      chart: SAMPLE_CHART_DATA.bar,
    },
    // Two-col chart — line
    {
      archetype: 'twoColChart',
      title: 'Net retention',
      leftText: {
        headline: 'Trending right',
        body: 'Cohort net retention crossed 140% in Q4 — driven by mid-market expansion as integrations matured.',
      },
      chart: SAMPLE_CHART_DATA.line,
    },
    // Table
    {
      archetype: 'table',
      title: 'By segment',
      headers: ['Segment', 'ARR',    'Customers', 'NRR'],
      rows: [
        ['Pro',         '$4.1M',    '8,420',     '118%'],
        ['Team',        '$1.8M',    '912',       '133%'],
        ['Enterprise',  '$2.4M',    '34',        '141%'],
        ['Total',       '$8.3M',    '9,366',     '124%'],
      ],
    },
    // Quote
    {
      archetype: 'sectionHeader',
      number: '03',
      title: 'Voice & moments',
      subtitle: 'Where the deck has to feel human.',
    },
    {
      archetype: 'quote',
      quote: 'The first time I used the new system, I genuinely thought a designer had made the deck. I closed PowerPoint and opened it again to double-check.',
      attribution: 'Internal beta — May 2026',
      subtext: 'Quote archetype renders pull-quotes with theme-aware quote marks and an attribution rule.',
    },
    // Image (uses fallback since we don't have a sample image)
    {
      archetype: 'imageFullBleed',
      title: 'Full-bleed for chapter dividers',
      eyebrow: 'imageFullBleed',
      overlay: 'dark',
      // no imagePath → falls back to a solid primary panel — proves
      // the deck still builds without missing-asset errors.
    },
    // Closing
    {
      archetype: 'closing',
      eyebrow: 'Thank you',
      title: 'Decks that look designed.',
      cta:  { label: 'See the spec', url: 'https://github.com/loxia/autopilot' },
      contact: [
        { label: 'Theme',     value: themeId },
        { label: 'Archetypes', value: '12' },
        { label: 'Backgrounds', value: '6' },
      ],
    },
  ];
  return slides;
}

async function buildForTheme(themeId) {
  await fs.mkdir(outDir, { recursive: true });
  const outputPath = path.join(outDir, `showcase-${themeId}.pptx`);
  const r = await buildThemedPres({
    title: `Loxia Presentation System — ${themeId}`,
    author: 'Loxia',
    company: 'Loxia',
    theme: themeId,
    slides: showcaseSlides(themeId),
  }, outputPath);
  return r;
}

async function buildFillExample() {
  const sysDir = path.dirname(__filename);
  const templatePath = path.resolve(sysDir, '../../bench-out/pres-showcase/template-customer.pptx');
  const filledPath   = path.resolve(sysDir, '../../bench-out/pres-showcase/filled-customer.pptx');

  // Step 1: create a template with {{tokens}}.
  await buildThemedPres({
    title: 'Customer template',
    theme: 'editorial-warm',
    slides: [
      {
        archetype: 'hero',
        eyebrow: '{{reportType}}',
        title: 'Hello, {{customerName}}',
        subtitle: 'Your quarterly recap, ready for {{date}}.',
        author: '{{authorName}}',
        date: '{{date}}',
      },
      {
        archetype: 'statCallout',
        eyebrow: '{{metricLabel}}',
        stat: '{{metricValue}}',
        label: 'For the period ending {{date}}',
        footnote: 'Source: {{sourceName}}',
      },
      {
        archetype: 'closing',
        eyebrow: 'Thank you',
        title: 'Until next time, {{customerName}}.',
        contact: [
          { label: 'Account manager', value: '{{authorName}}' },
          { label: 'Email',           value: '{{authorEmail}}' },
        ],
      },
    ],
  }, templatePath);

  // Step 2: read the template back to discover tokens.
  const outline = await readPres(templatePath);

  // Step 3: fill it.
  const filled = await fillPres({
    sourcePath: templatePath,
    outputPath: filledPath,
    values: {
      reportType: 'Q4 2026 RECAP',
      customerName: 'Acme Industries',
      date: 'May 28, 2026',
      authorName: 'Riley Chen',
      authorEmail: 'riley@loxia.ai',
      metricLabel: 'Net retention',
      metricValue: '142%',
      sourceName: 'internal',
    },
  });

  return { template: templatePath, outline, filled };
}

async function main() {
  const sys = listSystem();
  const themes = onlyTheme
    ? sys.themes.filter(t => t.id === onlyTheme)
    : sys.themes;

  if (!themes.length) {
    console.error(`No theme matched "${onlyTheme}". Available: ${sys.themes.map(t => t.id).join(', ')}`);
    process.exit(1);
  }

  console.log('Loxia Presentation Showcase');
  console.log(`Output dir: ${outDir}\n`);

  for (const t of themes) {
    process.stdout.write(`  • ${t.id} … `);
    const t0 = Date.now();
    const r = await buildForTheme(t.id);
    const ms = Date.now() - t0;
    console.log(`✔  ${(r.size / 1024).toFixed(1)} KB  ${r.slideCount} slides  ${ms}ms`);
    console.log(`        ${r.path}`);
    console.log(`        palette=${r.palette}  spacing=${r.spacing}  shape=${r.shape}  bg=${r.background}`);
  }

  // Always demo the fill flow once (theme-agnostic).
  if (!onlyTheme) {
    process.stdout.write('\n  • pres.fill demo … ');
    const t0 = Date.now();
    const r = await buildFillExample();
    const ms = Date.now() - t0;
    console.log(`✔  ${ms}ms`);
    console.log(`        template:  ${r.template}`);
    console.log(`        tokens:    ${r.outline.tokens.join(', ')}`);
    console.log(`        filled:    ${r.filled.path}  (${(r.filled.size / 1024).toFixed(1)} KB)`);
    console.log(`        replaced:  ${JSON.stringify(r.filled.replaced)}`);
    if (r.filled.unresolved.length) {
      console.log(`        UNRESOLVED tokens: ${r.filled.unresolved.join(', ')}`);
    }
  }

  console.log(`\nOpen these in PowerPoint / Keynote / Google Slides to visually QA.`);
}

main().catch(err => {
  console.error('Showcase failed:', err);
  process.exit(1);
});
