/**
 * Shared design tokens, scroll-phase thresholds and the cinematic camera path
 * for the "Logistics Brain" scroll-storytelling section.
 *
 * The whole experience is driven by ONE normalized scroll progress value
 * (0 → 1) shared between GSAP ScrollTrigger, the R3F render loop and the
 * Framer-Motion HTML overlay — so every layer stays perfectly in sync and the
 * journey reads as one continuous shot with no scene cuts.
 */

/**
 * Doormile brand palette: near-black + brand red, with green reserved for the
 * "delivered / optimized" success state.
 *
 * NOTE ON TOKEN NAMES: the keys below (cyan/blue/violet/…) are the original
 * cool-palette slot names, kept ONLY so the many `C.cyan`-style references in
 * the scene files don't all have to change. Their *values* are now brand reds
 * and neutral steels — read the inline comment, not the key name. New code
 * should prefer the semantic aliases (red / redBright / redSoft / steel).
 */
export const C = {
  bg: "#08080c", // near-black scene background

  red: "#C01227", // PRIMARY brand red
  cyan: "#E2354A", // redBright — main glowing red accent (roads, rings, brain, scooter)
  blue: "#7E1420", // crimson — dim deep-red structural glow (grid, links, soft glows)
  sky: "#F2667A", // redSoft — light coral highlight points
  magenta: "#C8102E", // secondary brand red
  violet: "#3c3c46", // steel — neutral grey structure (losing routes, secondary shell)
  purple: "#6a6a76", // steelLight — lighter neutral grey

  steel: "#43434d", // losing-route grey
  gray: "#7c7c86", // losing-route grey (lighter)

  green: "#22C55E", // success / delivered (unchanged)
  amber: "#F59E0B", // transitional (battery mid-charge) (unchanged)
  white: "#FFFFFF",
} as const;

/**
 * Palette for the six competing route simulations. Index 0 (Multi-Trip) is the
 * winner and gets the brand red so it stands out; the five losing strategies
 * are neutral greys that recede, then fade out entirely.
 */
export const ROUTE_COLORS = [
  C.red, // 0 — the eventual winner (brand red)
  C.steel,
  C.gray,
  C.steel,
  C.gray,
  C.steel,
] as const;

/**
 * The six strategies the "Parallel Universe Engine" benchmarks (index-aligned
 * to ROUTE_COLORS). Index 0 = Multi-Trip is the winner — it's also what solves
 * the EV paradox (59/59 vs 34/59), tying the routes beat to the EV beat.
 */
export const STRATEGIES = [
  "Multi-Trip",
  "Proximity",
  "Balanced",
  "Fuel Saver",
  "EV-Aware",
  "Time-Aware",
] as const;
export const WINNER_INDEX = 0;

/** The constraints the VRP solver optimizes together (Mathematical Precision). */
export const CONSTRAINTS = ["Capacity", "Distance", "Battery", "Traffic", "SLA"] as const;

/** Plain-language constraints shown in the EV / constraints beat. */
export const CONSTRAINT_LIST = [
  { icon: "🔋", label: "Battery", note: "EV range & recharge stops" },
  { icon: "📍", label: "Distance", note: "Total km per route" },
  { icon: "📦", label: "Capacity", note: "Orders each vehicle can carry" },
  { icon: "⏱️", label: "Time / SLA", note: "Promised delivery windows" },
] as const;

/**
 * Scored leaderboard for the "Score & Compare" beat. Higher = better total
 * delivery cost/outcome. Multi-Trip wins; EV-Aware (the naive baseline) scores
 * worst — it's the one that only delivered 34/59 in the EV paradox beat.
 */
export const STRATEGY_SCORES: { name: string; score: number; win?: boolean }[] = [
  { name: "Multi-Trip", score: 98, win: true },
  { name: "Time-Aware", score: 90 },
  { name: "Balanced", score: 84 },
  { name: "Proximity", score: 76 },
  { name: "Fuel Saver", score: 68 },
  { name: "EV-Aware", score: 58 },
];

/** Layout anchors (world units). */
export const BRAIN_Y = 3.0; // depot beacon hovers low over the map centre
export const CITY_RADIUS = 19;

/**
 * Scroll-phase thresholds (normalized 0 → 1). These are *story beats*, not hard
 * cuts — every element cross-fades across a window around its beat so the scene
 * morphs continuously.
 */
export const P = {
  birth: 0.0, // glowing brain + city form, energy roads grow
  routes: 0.13, // six route simulations race through the city
  ev: 0.28, // EV battery drains → recalc → charging station → green route
  network: 0.44, // camera rises to eagle-eye; full live network
  sla: 0.6, // holographic SLA clock; delayed routes dissolve
  ecosystem: 0.74, // pull back; warehouses + fleet come alive
  finale: 0.88, // fly up; stats + logo + tagline reveal
} as const;

export type PhaseKey = keyof typeof P;

/**
 * The six steps of the routing engine, in plain language — the spine of the
 * on-screen story. The persistent step rail and the per-beat content cards both
 * read from this so a non-technical viewer can follow the workflow. `at` is the
 * scroll-progress threshold where each step becomes the active one.
 */
export const ENGINE_STEPS = [
  { n: "01", at: P.routes, title: "Generate Routes", caption: "Many delivery plans created at once" },
  { n: "02", at: P.ev, title: "Check Constraints", caption: "Battery, distance, capacity & time" },
  { n: "03", at: P.network, title: "Score & Compare", caption: "Every plan ranked by total cost" },
  { n: "04", at: P.sla, title: "Guarantee On-Time", caption: "Late plans rejected automatically" },
  { n: "05", at: P.ecosystem, title: "Pick & Dispatch", caption: "Best plan sent to the fleet" },
  { n: "06", at: P.finale, title: "Delivered", caption: "Real business results" },
] as const;

export const PHASE_CAPTIONS: Record<PhaseKey, string> = {
  birth: "Initializing the logistics brain",
  routes: "Simulating delivery strategies",
  ev: "Recalculating around EV constraints",
  network: "Mapping the live delivery network",
  sla: "Enforcing on-time SLA reliability",
  ecosystem: "Autonomous fleet in motion",
  finale: "",
};

export function captionFor(p: number): string {
  if (p >= P.finale) return PHASE_CAPTIONS.finale;
  if (p >= P.ecosystem) return PHASE_CAPTIONS.ecosystem;
  if (p >= P.sla) return PHASE_CAPTIONS.sla;
  if (p >= P.network) return PHASE_CAPTIONS.network;
  if (p >= P.ev) return PHASE_CAPTIONS.ev;
  if (p >= P.routes) return PHASE_CAPTIONS.routes;
  return PHASE_CAPTIONS.birth;
}

/**
 * Camera waypoints sampled by scroll progress. Each has an eye position and a
 * look-at target. The rig lerps between adjacent waypoints (smoothstep eased)
 * and then exponentially damps toward the result — giving a smooth spline-like
 * dolly with no jerk on fast scroll.
 */
export type Waypoint = {
  at: number;
  pos: [number, number, number];
  look: [number, number, number];
};

/**
 * NEAR-STATIC MAP VIEW. The camera holds a consistent elevated 3/4 "control
 * room" angle on the depot/map the whole way through — only small, slow shifts
 * between beats (≈70% less travel than a cinematic fly-through). The story is
 * told by the OBJECTS on the map (nodes, candidate routes, scores, vehicles),
 * not by camera moves. Keep these positions clustered; large deltas reintroduce
 * the "city fly-through" feel we're removing.
 */
export const WAYPOINTS: Waypoint[] = [
  { at: 0.0, pos: [0, 20, 27], look: [0, 1.4, 0] }, // establish the map
  { at: 0.13, pos: [-2.5, 20, 26.5], look: [-0.5, 1.2, 0] }, // routes generate
  { at: 0.28, pos: [3, 18.5, 25.5], look: [0.6, 0.8, -0.8] }, // constraints — ease toward street
  { at: 0.44, pos: [0, 23, 24.5], look: [0, 1.0, 0] }, // score — lift slightly to read labels
  { at: 0.6, pos: [2.5, 21, 25.5], look: [0, 1.2, 0] }, // SLA — small lateral drift
  { at: 0.74, pos: [-2, 20, 26.5], look: [0, 1.2, 0] }, // dispatch
  { at: 0.88, pos: [0, 22, 25.5], look: [0, 1.8, 0] }, // results
  { at: 1.0, pos: [0, 21.5, 25.5], look: [0, 2.0, 0] },
];
