// The Cut-Off judgement matrix. Pure — no Phaser, no bus. The scene decides
// what to do with the result; this only decides what the room thinks of you.

import type { DrunkStage } from '../../data/types';
import {
  CUTOFF_REPLY_CLEAN,
  CUTOFF_REPLY_SCENE,
  CUTOFF_REPLY_SOFT,
  ESCALATION_LINES,
  type EscalationLine,
} from '../../data/strings/floor';

export type EscalationOutcome = 'clean' | 'scene' | 'staggerFree';

export interface EscalationResult {
  outcome: EscalationOutcome;
  vibeDelta: number;
  aggroDelta: number;
  /** What you said (from ESCALATION_LINES). */
  line: string;
  /** What they said back (from CUTOFF_REPLY_*). */
  reply: string;
  /** Eject: attach them to the escort-out walk. */
  eject: boolean;
  /** Resolved: stop treating them as an open infraction. */
  resolved: boolean;
}

/** Softest first — comparing rungs is the whole judgement. */
const RUNG: Readonly<Record<EscalationLine, number>> = {
  water: 0,
  done: 1,
  escort: 2,
};

/** The correct rung for each drunk stage. */
export const CORRECT_LINE: Readonly<Record<DrunkStage, EscalationLine>> = {
  sober: 'water',
  tipsy: 'water',
  loose: 'water',
  messy: 'done',
  maggot: 'escort',
};

// Deliberately small. Being right about a drunk shouldn't feel like a jackpot,
// and overreach should sting more than restraint pays (design doc §4.3).
const CLEAN_VIBE = 4;
const SCENE_VIBE_PER_RUNG = -3;
const SCENE_AGGRO_PER_RUNG = 5;
const SOFT_VIBE = -1;

export function judgeEscalation(stage: DrunkStage, line: EscalationLine): EscalationResult {
  const said = ESCALATION_LINES[line];
  const overreach = RUNG[line] - RUNG[CORRECT_LINE[stage]];

  if (overreach === 0) {
    return {
      outcome: 'clean',
      vibeDelta: CLEAN_VIBE,
      aggroDelta: 0,
      line: said,
      reply: CUTOFF_REPLY_CLEAN[stage],
      // Water is a kindness, not an exit — only the top two stages walk.
      eject: stage === 'messy' || stage === 'maggot',
      resolved: true,
    };
  }

  if (overreach > 0) {
    return {
      outcome: 'scene',
      vibeDelta: SCENE_VIBE_PER_RUNG * overreach,
      aggroDelta: SCENE_AGGRO_PER_RUNG * overreach,
      line: said,
      reply: CUTOFF_REPLY_SCENE[stage],
      // They're not going anywhere with you now, but the moment is spent.
      eject: false,
      resolved: true,
    };
  }

  return {
    outcome: 'staggerFree',
    vibeDelta: SOFT_VIBE,
    aggroDelta: 0,
    line: said,
    reply: CUTOFF_REPLY_SOFT[stage],
    eject: false,
    resolved: false,
  };
}

/** A maggot left alone too long becomes a deferred heat risk. */
export const MAGGOT_GRACE_MIN = 25;

export function maggotOverdue(spottedAtClockMin: number, nowClockMin: number): boolean {
  return nowClockMin - spottedAtClockMin > MAGGOT_GRACE_MIN;
}
