import type { BreadId } from '../sim/bread';
import type { AmountClass, SpreadId } from '../sim/spreads';
import type { ToolId } from '../sim/cutlery';

export interface Order {
  day: number;
  bread: BreadId;
  spread: SpreadId;
  amount: AmountClass;
  /** Target mean browning, 0..1. */
  browning: number;
  browningName: string;
  /** The customer specifically does not want char. Some don't care. */
  noChar: boolean;
  /** What the drawer will make you find. */
  tool: ToolId;
  /** 0 = fridge-hard, 1 = soft. The single cruellest dial in the game. */
  butterSoftness: number;
  /** How the customer says it. */
  text: string;
  /** Who's asking. */
  who: string;
}

export const BROWNING_NAMES: [number, string][] = [
  [0.18, 'barely warmed through'],
  [0.34, 'light'],
  [0.5, 'golden'],
  [0.66, 'well done'],
  [0.8, 'dark'],
];

export function nameBrowning(v: number): string {
  let best = BROWNING_NAMES[0];
  for (const b of BROWNING_NAMES) if (Math.abs(b[0] - v) < Math.abs(best[0] - v)) best = b;
  return best[1];
}

/**
 * The handwritten first week. The curve is deliberate: day 1 is butter on white
 * with a butter knife and butter that's been out all morning — every dial set to
 * "forgiving". By day 7 you're doing a translucent film of MITEY on thick wet
 * sourdough with fridge-hard butter... and a steak knife, because the drawer is
 * the drawer.
 */
export const DAYS: Order[] = [
  {
    day: 1,
    bread: 'white',
    spread: 'butter',
    amount: 'normal',
    browning: 0.5,
    browningName: 'golden',
    noChar: true,
    tool: 'butter_knife',
    butterSoftness: 0.85,
    who: 'Deidre',
    text: 'Just golden, love. Butter. Normal amount of butter.',
  },
  {
    day: 2,
    bread: 'white',
    spread: 'butter',
    amount: 'thin',
    browning: 0.66,
    browningName: 'well done',
    noChar: true,
    tool: 'dinner_knife',
    butterSoftness: 0.55,
    who: 'Ray',
    text: "Well done. Scrape of butter — I said a scrape, not a shovel.",
  },
  {
    day: 3,
    bread: 'multigrain',
    spread: 'peanut',
    amount: 'thick',
    browning: 0.42,
    browningName: 'light',
    noChar: true,
    tool: 'dessert_spoon',
    butterSoftness: 0.5,
    who: 'a child',
    text: 'PEANUT BUTTER. LOTS. Bread barely toasted please.',
  },
  {
    day: 4,
    bread: 'raisin',
    spread: 'butter',
    amount: 'normal',
    browning: 0.44,
    browningName: 'light',
    noChar: true,
    tool: 'butter_knife',
    butterSoftness: 0.3,
    who: 'Deidre',
    text: "Raisin loaf. Careful — it catches. I'll know if it catches.",
  },
  {
    day: 5,
    bread: 'white',
    spread: 'mitey',
    amount: 'normal',
    browning: 0.62,
    browningName: 'well done',
    noChar: true,
    tool: 'teaspoon',
    butterSoftness: 0.4,
    who: 'Ray',
    text: 'MITEY. Proper amount. You know what proper means.',
  },
  {
    day: 6,
    bread: 'sourdough',
    spread: 'crunchy',
    amount: 'normal',
    browning: 0.72,
    browningName: 'dark',
    noChar: false,
    tool: 'steak_knife',
    butterSoftness: 0.25,
    who: 'a man in a hurry',
    text: "Dark. Sourdough. Crunchy peanut butter — the PROPER kind. Don't care if it catches a bit.",
  },
  {
    day: 7,
    bread: 'sourdough',
    spread: 'mitey',
    amount: 'thin',
    browning: 0.68,
    browningName: 'well done',
    noChar: true,
    tool: 'steak_knife',
    butterSoftness: 0.0,
    who: 'the inspector himself',
    text: "Thick sourdough, well done, and a *scrape* of MITEY. I want to see the toast through it.",
  },
  {
    day: 8,
    bread: 'white',
    spread: 'marmalade',
    amount: 'normal',
    browning: 0.55,
    browningName: 'golden',
    noChar: true,
    tool: 'spreader',
    butterSoftness: 0.5,
    who: 'Deidre',
    text: 'Marmalade! And mind the rind, love — a piece in every bite, not a pile in one corner.',
  },
];

/** Days 9+ — keep going, with everything cranked. */
export function proceduralOrder(day: number, rand: () => number): Order {
  const breads: BreadId[] = ['white', 'multigrain', 'raisin', 'sourdough'];
  const spreads: SpreadId[] = ['butter', 'peanut', 'crunchy', 'mitey', 'marmalade'];
  const amounts: AmountClass[] = ['thin', 'normal', 'thick'];
  const tools: ToolId[] = [
    'butter_knife',
    'dinner_knife',
    'steak_knife',
    'spreader',
    'dinner_fork',
    'dessert_fork',
    'teaspoon',
    'dessert_spoon',
    'soup_spoon',
  ];
  const pick = <T>(a: T[]): T => a[Math.floor(rand() * a.length)];
  const spread = pick(spreads);
  const amount: AmountClass =
    spread === 'mitey' ? (rand() < 0.75 ? 'thin' : 'normal') : pick(amounts);
  const browning = 0.3 + rand() * 0.5;
  return {
    day,
    bread: pick(breads),
    spread,
    amount,
    browning,
    browningName: nameBrowning(browning),
    noChar: rand() < 0.8,
    tool: pick(tools),
    // It only gets colder from here.
    butterSoftness: Math.max(0, 0.4 - (day - 9) * 0.08) * rand(),
    who: pick(['Deidre', 'Ray', 'a regular', 'someone new', 'the inspector himself']),
    text: '',
  };
}
