/**
 * pres/grid — slide geometry + layout math.
 *
 * pptxgenjs uses inches as its default unit. The 16:9 wide layout is
 * 13.333 × 7.5 inches. Everything in the new presentation system is
 * expressed against this grid so the agent never has to think in pixels
 * or coordinates — it picks an archetype + spacing density, and the
 * grid resolves to (x, y, w, h) tuples for pptxgenjs to consume.
 *
 * Grid model:
 *   - 12-column layout (rounded to PPTX-friendly inch fractions)
 *   - safe-area = full slide minus pageMargin on all sides
 *   - vertical baseline of 0.25" so type sits on a rhythm
 *
 * spacing presets dial the same five knobs (page margin, content gutter,
 * paragraph gap, header-to-body gap, footer reservation). Changing one
 * preset restyles every archetype because every archetype reads from
 * `metrics` and never hardcodes numbers.
 */

export const SLIDE_DIMENSIONS = {
  width:  13.333,
  height: 7.5,
};

const SPACING_PRESETS = {
  tight: {
    pageMargin:       0.4,
    contentGutter:    0.2,
    paragraphGap:     0.08,
    headerBodyGap:    0.2,
    footerReserve:    0.35,
    blockPadding:     0.18,
  },
  cozy: {
    pageMargin:       0.6,
    contentGutter:    0.35,
    paragraphGap:     0.14,
    headerBodyGap:    0.35,
    footerReserve:    0.45,
    blockPadding:     0.28,
  },
  airy: {
    pageMargin:       0.9,
    contentGutter:    0.55,
    paragraphGap:     0.22,
    headerBodyGap:    0.55,
    footerReserve:    0.6,
    blockPadding:     0.4,
  },
};

/**
 * Resolve a spacing preset to absolute metrics + derived helpers.
 * The agent passes 'tight' | 'cozy' | 'airy' (or omits for 'cozy').
 */
export function resolveSpacing(preset = 'cozy') {
  const base = SPACING_PRESETS[preset] || SPACING_PRESETS.cozy;
  const { width, height } = SLIDE_DIMENSIONS;
  const m = base.pageMargin;

  // Safe-area inside the page margins.
  const safe = {
    x: m,
    y: m,
    w: width  - m * 2,
    h: height - m * 2,
  };

  // 12-column grid inside the safe area.
  const colCount = 12;
  const colW = (safe.w - base.contentGutter * (colCount - 1)) / colCount;

  /**
   * Convert a (col, span) pair → { x, w }. Both are 1-based for
   * readability (col 1 starts at the left margin). Useful for the
   * two-column / three-column archetypes that the agent can pick
   * without thinking in inches.
   */
  function col(start, span) {
    const c0 = Math.max(1, Math.min(colCount, start));
    const cs = Math.max(1, Math.min(colCount - c0 + 1, span));
    const x = safe.x + (c0 - 1) * (colW + base.contentGutter);
    const w = cs * colW + (cs - 1) * base.contentGutter;
    return { x, w };
  }

  /** Standard header band the title sits in. */
  const header = {
    x: safe.x,
    y: safe.y,
    w: safe.w,
    h: 0.9,
  };

  /** Body area below the header. */
  const body = {
    x: safe.x,
    y: header.y + header.h + base.headerBodyGap,
    w: safe.w,
    h: safe.h - (header.h + base.headerBodyGap + base.footerReserve),
  };

  /** Footer strip reserved at the bottom. */
  const footer = {
    x: safe.x,
    y: height - m - base.footerReserve,
    w: safe.w,
    h: base.footerReserve,
  };

  return {
    preset,
    ...base,
    slide: SLIDE_DIMENSIONS,
    safe,
    header,
    body,
    footer,
    colCount,
    colWidth: colW,
    col,
  };
}

/**
 * Centered box inside a region — used for hero / quote / closing
 * archetypes where the content sits in the middle of the slide.
 */
export function centerBox(region, w, h) {
  return {
    x: region.x + (region.w - w) / 2,
    y: region.y + (region.h - h) / 2,
    w, h,
  };
}
