import Phaser from 'phaser';
import type { DoorDressCodeRule } from '../../rules/dressCode';
import { DOOR_UI } from '../../data/strings/door';
import { DOOR_PALETTE, MONO, panel, text } from './ui';

// The laminated card on the desk. Rules land the moment Dazza's text arrives
// (design §3.1), so the NEW badge is the only warning the player gets that the
// punter they are already looking at just became a violation.

const NEW_BADGE_MS = 12_000;

interface Row {
  rule: DoorDressCodeRule;
  label: Phaser.GameObjects.Text;
  badge: Phaser.GameObjects.Text;
  addedAt: number;
  /** Rescinded by Dazza (rules cap at ACTIVE_RULE_CAP) — greyed, never judged. */
  retired?: boolean;
}

export class DressCodeCard {
  private readonly root: Phaser.GameObjects.Container;
  private readonly emptyText: Phaser.GameObjects.Text;
  private readonly rows: Row[] = [];
  private readonly x: number;
  private readonly y: number;

  constructor(scene: Phaser.Scene, x: number, y: number, w: number, h: number) {
    this.x = x;
    this.y = y;
    this.root = scene.add.container(0, 0).setDepth(50);

    this.root.add(panel(scene, x, y, w, h, 0x1a2018, 0x3c4a38));
    this.emptyText = text(scene, x + 5, y + 6, DOOR_UI.dressCodeEmpty, 7, DOOR_PALETTE.inkDim);
    this.root.add(this.emptyText);
  }

  add(scene: Phaser.Scene, rule: DoorDressCodeRule, nowMs: number): void {
    if (this.rows.some((r) => r.rule.id === rule.id)) return;
    this.emptyText.setVisible(false);

    const y = this.y + 6 + this.rows.length * 11;
    const label = scene.add.text(this.x + 5, y, `· ${rule.short}`, {
      fontFamily: MONO,
      fontSize: '7px',
      color: '#e0e8c8',
      wordWrap: { width: 150 },
    });
    const badge = scene.add.text(this.x + 5, y, 'NEW', {
      fontFamily: MONO,
      fontSize: '7px',
      color: '#ffd050',
    });
    badge.x = this.x + 5 + label.width + 4;
    this.root.add([label, badge]);

    // A flash on arrival — the card is peripheral vision, it has to shout once.
    scene.tweens.add({ targets: badge, alpha: { from: 1, to: 0.25 }, duration: 400, yoyo: true, repeat: 8 });
    this.rows.push({ rule, label, badge, addedAt: nowMs });
  }

  /** Highlight the rules the patron currently in front of you is breaking. */
  highlight(violatedIds: readonly string[]): void {
    for (const r of this.rows) {
      if (r.retired) continue;
      const hit = violatedIds.includes(r.rule.id);
      r.label.setColor(hit ? '#ff9090' : '#e0e8c8');
    }
  }

  /** Dazza moved on: grey the rule out. It stays on the card as a monument. */
  retire(ruleId: string): void {
    const row = this.rows.find((r) => r.rule.id === ruleId && !r.retired);
    if (!row) return;
    row.retired = true;
    row.label.setColor('#4a5a48');
    row.label.setText(`- ${row.rule.short}`);
    row.badge.setVisible(false);
  }

  update(nowMs: number): void {
    for (const r of this.rows) {
      if (r.badge.visible && nowMs - r.addedAt > NEW_BADGE_MS) r.badge.setVisible(false);
    }
  }

  /** The clipboard tab shares this panel's footprint — see ClipboardPanel. */
  setVisible(on: boolean): void {
    this.root.setVisible(on);
  }

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