/**
 * Archetype: bigStat — one HUGE number that fills the slide.
 *
 * For when the data is the entire message. The number renders at
 * the theme's `stat` size (200pt+) with optional ghosted backdrop
 * numeral behind it for drama. A small label sits underneath, a
 * footnote at the bottom edge.
 *
 * Slots:
 *   eyebrow   (optional) small label above the stat
 *   stat      (required) the number itself — e.g. "+143%" or "$4.2B"
 *   unit      (optional) shown smaller next to the stat ("%", "M", "x")
 *   label     (required) one-line description of what the stat measures
 *   footnote  (optional) source / methodology
 *   tags      (optional) [{label, kind}] — tag chips below the label
 *   delta     (optional) {value, direction: 'up'|'down'}
 */
import { applyChrome, eyebrow, rule, placeText } from './_helpers.js';
import { textStyle } from '../typography.js';
import { backdropNumeral, tag } from '../components.js';

export const id = 'bigStat';
export const slots = ['eyebrow', 'stat', 'unit', 'label', 'footnote', 'tags', 'delta'];

export default function render(slide, resolved, content, _pptx, ctx) {
  applyChrome(slide, resolved, { bgOverride: content.background, seed: 103, ctx });

  const { safe } = resolved.spacing;
  const palette = resolved.palette;

  // Backdrop ghost numeral — first digit of the stat, sitting behind
  // the foreground. Editorial themes skip this for cleaner look.
  if (resolved.theme.family !== 'editorial' && content.stat) {
    const firstDigit = String(content.stat).match(/[0-9]/);
    if (firstDigit) {
      backdropNumeral(slide, resolved, {
        text: firstDigit[0],
        x: safe.x + safe.w * 0.45,
        y: safe.y - safe.h * 0.15,
        w: safe.w * 0.6,
        h: safe.h,
        color: palette.primary,
        transparency: 90,
        size: 560,
      });
    }
  }

  // Eyebrow + optional tags row at the top.
  let cursorY = safe.y + safe.h * 0.18;
  if (content.eyebrow) {
    eyebrow(slide, resolved, content.eyebrow, {
      x: safe.x, y: cursorY, w: safe.w * 0.6, color: palette.primary,
    });
    cursorY += 0.5;
  }

  // Layout slots — anchor everything to fixed rows so nothing overlaps.
  // Top  : eyebrow band (already drawn above)
  // Mid  : stat + delta
  // Lower-mid : label (one line)
  // Bottom-ish: tags row
  // Footer: footnote
  const statY = safe.y + safe.h * 0.28;
  const statH = safe.h * 0.40;
  const chunks = [{
    text: String(content.stat ?? ''),
    options: {
      fontFace: resolved.typography.display.fontFace,
      fontSize: resolved.typography.stat.fontSize,
      bold: true,
      color: palette.ink,
      charSpacing: -4,
    },
  }];
  if (content.unit) {
    chunks.push({
      text: ' ' + String(content.unit),
      options: {
        fontFace: resolved.typography.body.fontFace,
        fontSize: resolved.typography.stat.fontSize * 0.32,
        bold: true,
        color: palette.subtle,
      },
    });
  }
  slide.addText(chunks, {
    x: safe.x, y: statY, w: safe.w * 0.65, h: statH,
    align: 'left', valign: 'middle', fit: 'shrink', wrap: false,
  });

  // Delta — to the right of the stat (not below) so it doesn't push
  // the label down. Vertically baseline-aligned with the stat.
  if (content.delta) {
    const d = content.delta;
    const direction = d.direction || (String(d.value || d).startsWith('-') ? 'down' : 'up');
    const arrowColor = direction === 'down' ? palette.highlight : palette.primary;
    const arrow = direction === 'down' ? '▼' : '▲';
    slide.addText(`${arrow}  ${d.value ?? d}`, {
      x: safe.x + safe.w * 0.65, y: statY,
      w: safe.w * 0.35, h: statH,
      fontFace: resolved.typography.subtitle.fontFace,
      fontSize: 26,
      bold: true,
      color: arrowColor,
      align: 'left',
      valign: 'middle',
    });
  }

  // Label — fixed slot well below the stat band.
  const labelY = statY + statH + 0.25;
  const labelH = 0.8;
  if (content.label) {
    placeText(slide, resolved, 'subtitle', content.label, {
      x: safe.x, y: labelY, w: safe.w * 0.85, h: labelH,
    }, { color: palette.text, align: 'left' });
  }

  // Tags row — fixed slot below the label, well above the footnote.
  if (Array.isArray(content.tags) && content.tags.length) {
    let tagX = safe.x;
    const tagY = labelY + labelH + 0.15;
    for (const t of content.tags) {
      const placed = tag(slide, resolved, {
        x: tagX, y: tagY,
        label: typeof t === 'string' ? t : t.label,
        kind: typeof t === 'object' ? (t.kind || 'subtle') : 'subtle',
      });
      tagX += placed.w + 0.12;
    }
  }

  // Footnote at the very bottom of the safe area, with a hairline above.
  if (content.footnote) {
    const footY = safe.y + safe.h - 0.45;
    rule(slide, safe.x, footY - 0.08, 0.5, palette.subtle, 0.5);
    placeText(slide, resolved, 'caption', content.footnote, {
      x: safe.x, y: footY, w: safe.w, h: 0.35,
    }, { color: palette.subtle, align: 'left' });
  }
}
