/**
 * pres — themed presentation builder.
 *
 * Public entry. Takes the spec the agent provides + an output path,
 * builds the pptx via pptxgenjs, writes to disk, returns metadata.
 *
 * Spec shape:
 *   {
 *     title, subject, author, company,
 *     theme: 'editorial-warm' | 'tech-bold' | 'data-heavy',
 *     palette, spacing, shape, background,   // optional overrides
 *     slides: [
 *       { archetype: 'hero', title, subtitle, eyebrow, ... },
 *       { archetype: 'agenda', items: [...] },
 *       ...
 *     ]
 *   }
 *
 * The new system is opt-in by passing a STRING `theme`. The legacy
 * shape (theme as an object) is still routed to the old createPres
 * by the caller in officePres.js.
 */
import fs from 'fs/promises';
import { createRequire } from 'module';

import { resolveTheme, listThemes } from './themes/index.js';
import { renderArchetype, listArchetypes } from './archetypes/index.js';
import { listBackgrounds } from './backgrounds/index.js';
import { defineMasters, buildDeckContext, usesChrome } from './master.js';

const localRequire = createRequire(import.meta.url);
let pptxgen = null;
function loadPptx() {
  if (pptxgen) return pptxgen;
  const mod = localRequire('pptxgenjs');
  pptxgen = mod.default || mod;
  return pptxgen;
}

/**
 * Detect the new-format spec — distinguishes from the legacy shape so
 * officePres.createPres() can route appropriately.
 */
export function isThemedSpec(spec) {
  return !!(spec && typeof spec.theme === 'string');
}

/** Discovery helpers — used by the verifier + tool description builder. */
export function listSystem() {
  return {
    themes: listThemes(),
    archetypes: listArchetypes(),
    backgrounds: listBackgrounds(),
  };
}

/**
 * Build a themed presentation. Returns {path, size, slideCount, theme}.
 */
export async function buildThemedPres(spec, outputPath) {
  const Pptx = loadPptx();
  const pptx = new Pptx();

  pptx.title = spec.title || '';
  pptx.subject = spec.subject || '';
  pptx.author = spec.author || 'Loxia Agent';
  pptx.company = spec.company || '';
  pptx.layout = 'LAYOUT_WIDE';

  const resolved = resolveTheme(spec);
  const { slides, context } = buildDeckContext(spec);

  // Two slide masters per deck so we can apply consistent bg/chrome
  // and let pptxgenjs dedupe the static parts at file-size level.
  const masters = defineMasters(pptx, resolved);

  for (let i = 0; i < slides.length; i++) {
    const slideSpec = slides[i];
    const ctx = context[i];
    const masterName = usesChrome(slideSpec.archetype || 'freeform')
      ? masters.CHROME
      : masters.BARE;
    const slide = pptx.addSlide({ masterName });
    renderArchetype(slide, resolved, slideSpec, pptx, ctx);
  }

  const buf = await pptx.write({ outputType: 'nodebuffer' });
  await fs.writeFile(outputPath, buf);
  const stat = await fs.stat(outputPath);
  return {
    path: outputPath,
    size: stat.size,
    slideCount: slides.length,
    theme: resolved.theme.id,
    palette: resolved.palette.name,
    spacing: resolved.spacing.preset,
    shape: resolved.shape.preset,
    background: resolved.bg,
  };
}
