import type { Criterion, Group } from './judging';

/**
 * The samurai's voice. Deadpan, specific, never quite cruel. Each line is a
 * subtitled Japanese bark + its broken-Engrish translation — 1997 bargain-bin
 * PS1 import energy. Keyed to the criterion that decided the verdict, so the
 * bark always names the same thing the scorecard does.
 */

interface Bark {
  jp: string;
  en: string;
}
type Bank = Record<Group, { bad: Bark[]; good: Bark[] }>;

const BANK: Bank = {
  CUT: {
    bad: [
      { jp: 'Kore wa… kizu da. Kire de wa nai.', en: 'This is a wound. Not a cut.' },
      { jp: 'Katana ga naite iru.', en: 'The blade is weeping.' },
      { jp: 'Tsubushita na.', en: 'You have crushed it.' },
      { jp: 'Ao ga chigau. Hayasa ga chigau.', en: 'Wrong angle. Wrong speed.' },
      { jp: 'Ryōri de wa naku, jiko da.', en: 'Not cooking. An accident.' },
      { jp: 'Kono kire wa… fukōhei da.', en: 'This slice. It is unfair.' },
      { jp: 'Hōchō o osore-sugi da.', en: 'You fear the knife too much.' },
      { jp: 'Migoto ni, shippai da.', en: 'A splendid failure.' },
    ],
    good: [
      { jp: 'Kire wa… tadashii.', en: 'The cut. It is correct.' },
      { jp: 'Ii ha-oto datta.', en: 'That was a good blade-sound.' },
      { jp: 'Sore de ii.', en: 'That will do.' },
    ],
  },
  SANDO: {
    bad: [
      { jp: 'Sando… ga… yugande iru.', en: 'The sandwich. It leans.' },
      { jp: 'Tō da. Sando de wa nai.', en: 'A tower. Not a sandwich.' },
      { jp: 'Jūryoku o wasureta ka.', en: 'Have you forgotten gravity.' },
      { jp: 'Chūshin ga… doko ni mo nai.', en: 'The centre is nowhere.' },
      { jp: 'Kuzure-ochiru no o mita.', en: 'I watched it fall.' },
      { jp: 'Chūmon to chigau.', en: 'This is not what was ordered.' },
      { jp: 'Kaisō ga… hanran shite iru.', en: 'The layers are in revolt.' },
      { jp: 'Kono katamuki wa… geijutsu ka.', en: 'This lean. Is it art.' },
    ],
    good: [
      { jp: 'Massugu da. Yoi.', en: 'Plumb. Good.' },
      { jp: 'Chūmon-dōri da.', en: 'Exactly as ordered.' },
      { jp: 'Sando ga… tatte iru.', en: 'The sandwich stands.' },
    ],
  },
  SERVICE: {
    bad: [
      { jp: 'Osoi. Kyaku wa toshi o totta.', en: 'Late. The customer has aged.' },
      { jp: 'Rei o shiranu ka.', en: 'Do you know no manners.' },
      { jp: 'Chigau sara da.', en: 'Wrong dish.' },
      { jp: 'Ojigi wa… doko da.', en: 'Where. Was the bow.' },
      { jp: 'Machikutabireta.', en: 'I have grown tired of waiting.' },
      { jp: 'Dashinasai. …mada ka.', en: 'Serve it. …still.' },
      { jp: 'Kono ma wa… mujō da.', en: 'This delay. It is merciless.' },
      { jp: 'Teishutsu sarezu.', en: 'Never delivered.' },
    ],
    good: [
      { jp: 'Ojigi… uketotta.', en: 'The bow. Received.' },
      { jp: 'Jikan-dōri da.', en: 'On time.' },
      { jp: 'Reigi tadashii.', en: 'Properly mannered.' },
    ],
  },
  FLOOR: {
    bad: [
      { jp: 'Yuka o miyo.', en: 'Look at the floor.' },
      { jp: 'Kore wa… genba da.', en: 'This is a crime scene.' },
      { jp: 'Nani ka ga… shinda.', en: 'Something has died.' },
      { jp: 'Suberu zo.', en: 'It is slippery.' },
      { jp: 'Sōji wa dareka ga suru.', en: 'Someone will have to clean that.' },
      { jp: 'Otoshi-sugi da.', en: 'Too much dropped.' },
      { jp: 'Mottainai.', en: 'What a waste.' },
      { jp: 'Yuka ni mo… sando ga aru.', en: 'There is sandwich on the floor too.' },
    ],
    good: [
      { jp: 'Yuka wa… kirei da.', en: 'The floor is clean.' },
      { jp: 'Nani mo kobosazu.', en: 'Nothing spilled.' },
      { jp: 'Seiketsu da.', en: 'Tidy.' },
    ],
  },
};

/** Deterministic index from a string — same detail → same bark, no RNG. */
const hash = (s: string): number => {
  let h = 2166136261;
  for (let i = 0; i < s.length; i++) h = Math.imul(h ^ s.charCodeAt(i), 16777619);
  return (h >>> 0);
};

export function barkFor(c: Criterion, good: boolean): Bark {
  const pool = BANK[c.group][good ? 'good' : 'bad'];
  return pool[hash(c.detail) % pool.length];
}
