import Phaser from 'phaser';
import { renderDoll } from '../../../patrons/doll';
import type { Patron } from '../../../data/types';

// A reusable three-verb modal for floor scenarios (docs/SCENARIOS.md): the
// joint bust today, whatever the yard produces next. Same shell discipline as
// the other overlays: the scene routes keys, the overlay owns no listeners of
// its own beyond pointer hits on its rows.

const W = 640;
const H = 360;
const PANEL_X = 96;
const PANEL_Y = 52;
const PANEL_W = 448;
const PANEL_H = 236;
const ROW_X = PANEL_X + 118;
const ROW_W = PANEL_W - 136;
const ROW_TOP = PANEL_Y + 86;
const ROW_GAP = 34;
const AMBER = 0xd8a020;

const mono = (size: number, colour: string): Phaser.Types.GameObjects.Text.TextStyle => ({
  fontFamily: 'monospace',
  fontSize: `${size}px`,
  color: colour,
});

export interface ChoiceDef {
  id: string;
  label: string;
  detail: string;
}

export interface ChoiceArgs {
  title: string;
  /** What the person at the centre of it says. */
  line: string;
  patron: Patron;
  choices: readonly ChoiceDef[]; // up to 3
}

export class ChoiceOverlay {
  private readonly scene: Phaser.Scene;
  private readonly root: Phaser.GameObjects.Container;
  private readonly titleText: Phaser.GameObjects.Text;
  private readonly lineText: Phaser.GameObjects.Text;
  private readonly doll: Phaser.GameObjects.Image;
  private readonly rows: Array<{
    box: Phaser.GameObjects.Rectangle;
    label: Phaser.GameObjects.Text;
    detail: Phaser.GameObjects.Text;
  }> = [];
  private choices: readonly ChoiceDef[] = [];
  private done: ((id: string | null) => void) | null = null;
  private open_ = false;

  constructor(scene: Phaser.Scene) {
    this.scene = scene;
    this.root = scene.add.container(0, 0).setDepth(5000).setScrollFactor(0).setVisible(false);
    this.root.add(scene.add.rectangle(W / 2, H / 2, W, H, 0x000000, 0.82));
    this.root.add(
      scene.add.rectangle(W / 2, PANEL_Y + PANEL_H / 2, PANEL_W, PANEL_H, 0x101018).setStrokeStyle(1, 0x6080a0, 0.7),
    );

    this.titleText = scene.add.text(W / 2, PANEL_Y + 16, '', mono(11, '#9fc0e8')).setOrigin(0.5, 0);
    this.lineText = scene.add
      .text(PANEL_X + 118, PANEL_Y + 44, '', mono(8, '#cfc6d8'))
      .setOrigin(0, 0)
      .setWordWrapWidth(ROW_W);
    this.doll = scene.add.image(PANEL_X + 58, PANEL_Y + 120, '__DEFAULT').setScale(2);
    this.root.add([this.titleText, this.lineText, this.doll]);

    for (let i = 0; i < 3; i++) {
      const y = ROW_TOP + i * ROW_GAP;
      const box = scene.add
        .rectangle(ROW_X + ROW_W / 2, y, ROW_W, 28, 0x14141f)
        .setStrokeStyle(1, 0x2a2a3a)
        .setInteractive({ useHandCursor: true });
      const label = scene.add.text(ROW_X + 10, y - 6, '', mono(9, '#e8e0d0')).setOrigin(0, 0.5);
      const detail = scene.add.text(ROW_X + 10, y + 7, '', mono(7, '#6a7a8a')).setOrigin(0, 0.5);
      box.on('pointerover', () => box.setStrokeStyle(1, AMBER));
      box.on('pointerout', () => box.setStrokeStyle(1, 0x2a2a3a));
      box.on('pointerup', () => this.pick(i));
      this.root.add([box, label, detail]);
      this.rows.push({ box, label, detail });
    }

    this.root.add(
      scene.add
        .text(W / 2, PANEL_Y + PANEL_H - 16, '1/2/3 choose · ESC walk away', mono(7, '#5a5a70'))
        .setOrigin(0.5, 0),
    );
  }

  get isOpen(): boolean {
    return this.open_;
  }

  open(args: ChoiceArgs, done: (id: string | null) => void): void {
    this.done = done;
    this.choices = args.choices.slice(0, 3);
    this.open_ = true;
    this.titleText.setText(args.title);
    this.lineText.setText(`"${args.line}"`);
    this.doll.setTexture(renderDoll(this.scene, args.patron, 'queue'));
    this.rows.forEach((r, i) => {
      const c = this.choices[i];
      r.box.setVisible(!!c);
      r.label.setVisible(!!c).setText(c ? `${i + 1}   ${c.label}` : '');
      r.detail.setVisible(!!c).setText(c ? c.detail : '');
    });
    this.root.setVisible(true);
  }

  handleKey(key: string): void {
    if (!this.open_) return;
    if (key === 'ESCAPE' || key === 'ESC') return this.close(null);
    const idx = Number(key) - 1;
    if (idx >= 0 && idx < this.choices.length) this.pick(idx);
  }

  update(_dtMs: number): void {}

  private pick(i: number): void {
    const c = this.choices[i];
    if (c) this.close(c.id);
  }

  private close(id: string | null): void {
    this.open_ = false;
    this.root.setVisible(false);
    const done = this.done;
    this.done = null;
    done?.(id);
  }

  destroy(): void {
    this.root.destroy();
  }
}
