/**
 * Era skins for the clean programming (round 5 Part A).
 *
 * THE SCREEN's SUBSTRATE ages with the highest ratified era; the corruption on top stays
 * era-agnostic. Media history is geology (codex §1), so the test pattern itself is a fossil
 * of whatever format the player has climbed to. Codex §8 era skins drive the palette.
 *
 * Pure and data-only so it is trivially unit-testable and carries no DOM — the base feed
 * consumes an EraSkin, it does not decide one.
 */

export type Era = 'reel' | 'broadcast' | 'disc' | 'stream' | 'fortress';

/** Deepest → shallowest, i.e. oldest → newest. "Highest ratified" = last of these unlocked. */
export const ERA_ORDER: readonly Era[] = ['reel', 'broadcast', 'disc', 'stream', 'fortress'];

export interface EraSkin {
  /** the seven SMPTE bars, era-recoloured */
  bars: string[];
  /** the castellation strip under the bars */
  casts: string[];
  /** backdrop behind the pattern (matters where bars don't cover) */
  bg: string;
  /** overlay text + timecode colour */
  ink: string;
  /** rec-dot / accent colour */
  accent: string;
  /**
   * A full-canvas post-treatment applied after the pattern is drawn. Kept as a tagged union
   * (not a callback) so it stays pure data — the base feed interprets it.
   */
  treatment:
    | { kind: 'none' }
    | { kind: 'sepia'; sprockets: true } // reel: warm film, sprocket holes
    | { kind: 'phosphor' } // broadcast: green cast + interlace
    | { kind: 'gloss' } // disc: rainbow-on-black sheen
    | { kind: 'bleach' }; // fortress: blinding matte white
}

const STREAM_BARS = ['#c0c0c0', '#c0c000', '#00c0c0', '#00c000', '#c000c0', '#c00000', '#0000c0'];
const STREAM_CASTS = ['#0000c0', '#131313', '#c000c0', '#131313', '#00c0c0', '#131313', '#c0c0c0'];

const SKINS: Record<Era, EraSkin> = {
  reel: {
    bars: ['#b9a67c', '#c7b06a', '#9c9a72', '#8f9a63', '#a98c6e', '#a06a4e', '#6e5c46'],
    casts: ['#5a4a34', '#241d14', '#6e5240', '#241d14', '#5c5a44', '#241d14', '#b9a67c'],
    bg: '#181008',
    ink: '#f0e0c0',
    accent: '#d8a24a',
    treatment: { kind: 'sepia', sprockets: true },
  },
  broadcast: {
    // NTSC bars, but everything sunk into a phosphor-green cathode glow.
    bars: ['#8fce8f', '#b6c664', '#4fb7b7', '#4fb44f', '#8a5aa8', '#9a4a4a', '#3a4fb0'],
    casts: ['#12300f', '#0a140a', '#2a3a20', '#0a140a', '#1a3a30', '#0a140a', '#8fce8f'],
    bg: '#03120a',
    ink: '#c8ffce',
    accent: '#8fffa0',
    treatment: { kind: 'phosphor' },
  },
  disc: {
    // Rigid, glossy, rainbow-on-black. DVD menu energy.
    bars: ['#d0d0d0', '#d8d800', '#00d8d8', '#00d800', '#d800d8', '#e00000', '#2020ff'],
    casts: ['#2020ff', '#000000', '#d800d8', '#000000', '#00d8d8', '#000000', '#d0d0d0'],
    bg: '#000000',
    ink: '#ffffff',
    accent: '#ff3fd4',
    treatment: { kind: 'gloss' },
  },
  stream: {
    // The surface world / the original prototype look — the game's "now".
    bars: STREAM_BARS,
    casts: STREAM_CASTS,
    bg: '#101010',
    ink: '#f4f4f4',
    accent: '#ff4444',
    treatment: { kind: 'none' },
  },
  fortress: {
    // The DCP citadel: mathematically perfect, blinding matte white, near-invisible bars.
    bars: ['#f7f7f7', '#f2f2e8', '#e8f2f2', '#e8f2e8', '#f2e8f2', '#f2e8e8', '#e8e8f4'],
    casts: ['#e6e6ee', '#f4f4f4', '#eee6ee', '#f4f4f4', '#e6eeee', '#f4f4f4', '#f7f7f7'],
    bg: '#fbfbfb',
    ink: '#20242a',
    accent: '#2f7d3f',
    treatment: { kind: 'bleach' },
  },
};

/** The highest ratified era from a set of unlocked tech, given a tech→era lookup. */
export function highestEra(unlocked: readonly string[], eraOf: (tech: string) => Era | undefined): Era {
  let best = 0; // default: reel (the world starts in the deepest stratum you can reach)
  for (const t of unlocked) {
    const e = eraOf(t);
    if (e === undefined) continue;
    const idx = ERA_ORDER.indexOf(e);
    if (idx > best) best = idx;
  }
  return ERA_ORDER[best];
}

export function eraSkin(era: Era): EraSkin {
  return SKINS[era];
}
