// UIScene：常驻 UI（CONTRACT §4）。
// 向日葵表盘（12 瓣 Graphics，不显示任何数字；满格花心黑籽）、「按 E」提示、
// 底部对话框（说话者名 + 头像 + 文本，E 推进，温柔/迟疑/否定三选项）、
// 文本腐蚀渲染层（§6.5）、C4 乱码闪显。

import Phaser from 'phaser';
import { director } from '../core/CorruptionDirector';
import { corruptText } from '../core/TextCorruptor';
import { audio } from '../audio/AudioEngine';
import { GAME_W, GAME_H, NPC_DEFS, type DialoguePayload, type Stage } from '../types';

/** §6.4 UI 列：0–20→0–2 瓣，21–50→3–6，51–80→7–9，81–99→10–12，100→12+黑籽 */
export function petalCount(h: number): number {
  if (h >= 100) return 12;
  if (h >= 81) return 10 + Math.min(2, Math.floor((h - 81) / 7));
  if (h >= 51) return 7 + Math.min(2, Math.floor((h - 51) / 11));
  if (h >= 21) return 3 + Math.min(3, Math.floor((h - 21) / 8));
  return Math.min(2, Math.floor(h / 8));
}

export class UIScene extends Phaser.Scene {
  private dial!: Phaser.GameObjects.Graphics;
  private promptText!: Phaser.GameObjects.Text;
  private flashTextObj!: Phaser.GameObjects.Text;
  /** 表盘当前是否显示黑籽（满格），验收脚本读取 */
  seedsShown = false;

  // 对话
  private dlgBox: Phaser.GameObjects.Container | null = null;
  private dlgBody!: Phaser.GameObjects.Text;
  private dlgName!: Phaser.GameObjects.Text;
  private dlgPortrait!: Phaser.GameObjects.Image;
  private dlgChoices: Phaser.GameObjects.Text[] = [];
  private payload: DialoguePayload | null = null;
  private lineIdx = 0;
  private fullLine = '';
  private typing = false;
  private typeTimer: Phaser.Time.TimerEvent | null = null;
  private choiceIdx = 0;
  private showingChoices = false;
  private openAt = 0;

  private keys!: {
    E: Phaser.Input.Keyboard.Key;
    UP: Phaser.Input.Keyboard.Key;
    DOWN: Phaser.Input.Keyboard.Key;
    W: Phaser.Input.Keyboard.Key;
    S: Phaser.Input.Keyboard.Key;
    N1: Phaser.Input.Keyboard.Key;
    N2: Phaser.Input.Keyboard.Key;
    N3: Phaser.Input.Keyboard.Key;
  };

  constructor() {
    super('UIScene');
  }

  create(): void {
    this.dial = this.add.graphics().setDepth(10);
    this.promptText = this.add.text(GAME_W / 2, GAME_H - 14, '', {
      fontFamily: 'monospace', fontSize: '8px', color: '#ffffff',
      stroke: '#5c4a2e', strokeThickness: 2,
    }).setOrigin(0.5).setDepth(10);

    this.flashTextObj = this.add.text(GAME_W / 2, GAME_H / 2, '', {
      fontFamily: 'monospace', fontSize: '10px', color: '#ff3366',
      stroke: '#000000', strokeThickness: 2,
    }).setOrigin(0.5).setDepth(30).setVisible(false);

    this.keys = this.input.keyboard!.addKeys('E,UP,DOWN,W,S') as typeof this.keys;
    this.keys.N1 = this.input.keyboard!.addKey('ONE');
    this.keys.N2 = this.input.keyboard!.addKey('TWO');
    this.keys.N3 = this.input.keyboard!.addKey('THREE');

    // 场景会被 stop/launch（结局、debug），监听器必须在 shutdown 时摘除
    const redraw = (): void => this.drawDial();
    const onPrompt = (text: string | null): void => { this.promptText.setText(text ?? ''); };
    const onDialogue = (p: DialoguePayload): void => this.openDialogue(p);
    const onFlash = (text: string, ms: number): void => this.flash(text, ms);
    director.on('happiness', redraw);
    director.on('stage', redraw);
    director.on('day', redraw);
    director.on('prompt', onPrompt);
    director.on('dialogue', onDialogue);
    director.on('flashText', onFlash);
    this.events.once('shutdown', () => {
      director.off('happiness', redraw);
      director.off('stage', redraw);
      director.off('day', redraw);
      director.off('prompt', onPrompt);
      director.off('dialogue', onDialogue);
      director.off('flashText', onFlash);
    });

    this.drawDial();
  }

  // ---------- 向日葵表盘（无数字） ----------
  private drawDial(): void {
    const g = this.dial;
    g.clear();
    const cx = 24;
    const cy = 24;
    const h = director.happiness;
    const lit = petalCount(h);
    const bright = director.params.petalBright;
    const litColor = bright ? 0xfff3b0 : 0xffd93d; // S3 起花瓣过亮
    const unlitColor = 0x4a3f2a;

    for (let i = 0; i < 12; i++) {
      const ang = -Math.PI / 2 + (i * Math.PI) / 6;
      const px = cx + Math.cos(ang) * 13;
      const py = cy + Math.sin(ang) * 13;
      const w = 4;
      const len = 7;
      // 旋转矩形（花瓣）
      const ux = Math.cos(ang);
      const uy = Math.sin(ang);
      const nx = -uy;
      const ny = ux;
      const pts = [
        new Phaser.Math.Vector2(px + nx * w / 2, py + ny * w / 2),
        new Phaser.Math.Vector2(px - nx * w / 2, py - ny * w / 2),
        new Phaser.Math.Vector2(px - nx * w / 2 + ux * len, py - ny * w / 2 + uy * len),
        new Phaser.Math.Vector2(px + nx * w / 2 + ux * len, py + ny * w / 2 + uy * len),
      ];
      g.fillStyle(i < lit ? litColor : unlitColor, 1);
      g.fillPoints(pts, true);
    }
    // 花心
    g.fillStyle(0x8b5a2b, 1);
    g.fillCircle(cx, cy, 7);
    // 满格：花心浮现过熟的黑籽
    this.seedsShown = h >= 100;
    if (h >= 100) {
      g.fillStyle(0x1a1208, 1);
      const seeds = [[-3, -2], [2, -3], [0, 1], [-2, 3], [3, 2]];
      for (const [sx, sy] of seeds) g.fillCircle(cx + sx, cy + sy, 1);
    }
  }

  // ---------- C4 乱码闪显 ----------
  private flash(text: string, ms: number): void {
    this.flashTextObj.setText(text).setVisible(true);
    this.time.delayedCall(ms, () => this.flashTextObj.setVisible(false));
  }

  // ---------- 对话框 ----------
  private openDialogue(p: DialoguePayload): void {
    this.closeDialogueOnly();
    this.payload = p;
    this.lineIdx = 0;
    this.openAt = this.time.now;

    const boxY = GAME_H - 56;
    const c = this.add.container(0, 0).setDepth(20);
    const bg = this.add.rectangle(GAME_W / 2, boxY + 28, GAME_W - 8, 52, 0xfff3d6, 0.96)
      .setStrokeStyle(2, 0x8b5a2b);
    c.add(bg);

    const speaker = p.speakerId;
    const def = speaker && speaker !== 'narrator' ? NPC_DEFS[speaker] : null;

    this.dlgPortrait = this.add.image(24, boxY + 28, def?.portraitKey || 'portrait_player_smile')
      .setDisplaySize(32, 32);
    this.dlgPortrait.setVisible(!!def);
    c.add(this.dlgPortrait);

    this.dlgName = this.add.text(46, boxY + 6, def ? def.name : '', {
      fontFamily: 'monospace', fontSize: '8px', color: '#8B5A2B',
    });
    c.add(this.dlgName);

    this.dlgBody = this.add.text(46, boxY + 17, '', {
      fontFamily: 'monospace', fontSize: '8px', color: '#3a2c18',
      wordWrap: { width: GAME_W - 62, useAdvancedWrap: true },
      lineSpacing: 3,
    });
    c.add(this.dlgBody);

    this.dlgBox = c;
    this.showLine();
  }

  private showLine(): void {
    if (!this.payload) return;
    const raw = this.payload.lines[this.lineIdx] ?? '';
    // 渲染层腐蚀（§6.5）
    this.fullLine = corruptText(raw, this.payload.speakerId, director.stage as Stage);
    this.typing = true;
    this.dlgBody.setText('');
    if (this.fullLine.length === 0) {
      this.typing = false;
      return;
    }
    let i = 0;
    this.typeTimer?.remove();
    this.typeTimer = this.time.addEvent({
      delay: 28,
      repeat: this.fullLine.length - 1,
      callback: () => {
        i += 1;
        this.dlgBody.setText(this.fullLine.slice(0, i));
        if (i % 3 === 0) audio.beep();
        if (i >= this.fullLine.length) this.typing = false;
      },
    });
  }

  private finishTyping(): void {
    this.typeTimer?.remove();
    this.typeTimer = null;
    this.typing = false;
    this.dlgBody.setText(this.fullLine);
  }

  private advance(): void {
    if (!this.payload) return;
    if (this.typing) {
      this.finishTyping();
      return;
    }
    audio.beep();
    this.lineIdx += 1;
    if (this.lineIdx < this.payload.lines.length) {
      this.showLine();
      return;
    }
    // 文本结束 → 选项或关闭
    if (this.payload.choices && this.payload.choices.length > 0 && !this.showingChoices) {
      this.renderChoices();
      return;
    }
    const result = this.showingChoices ? this.choiceIdx : null;
    const chosen = this.payload.choices?.[this.choiceIdx];
    this.closeDialogueOnly();
    director.resolveDialogue(result);
    void chosen;
  }

  private renderChoices(): void {
    if (!this.payload?.choices || !this.dlgBox) return;
    this.showingChoices = true;
    this.choiceIdx = 0;
    this.dlgChoices = [];
    const baseY = GAME_H - 56 + 20;
    this.payload.choices.forEach((ch, i) => {
      const t = this.add.text(58, baseY + i * 10, `${i === 0 ? '▶ ' : '　 '}${ch.label}`, {
        fontFamily: 'monospace', fontSize: '8px',
        color: i === 0 ? '#c0392b' : '#3a2c18',
      });
      this.dlgBox!.add(t);
      this.dlgChoices.push(t);
    });
    this.dlgBody.setVisible(false);
  }

  private moveChoice(dir: number): void {
    if (!this.showingChoices || !this.payload?.choices) return;
    const n = this.payload.choices.length;
    this.choiceIdx = (this.choiceIdx + dir + n) % n;
    this.dlgChoices.forEach((t, i) => {
      t.setText(`${i === this.choiceIdx ? '▶ ' : '　 '}${this.payload!.choices![i].label}`);
      t.setColor(i === this.choiceIdx ? '#c0392b' : '#3a2c18');
    });
  }

  private closeDialogueOnly(): void {
    this.typeTimer?.remove();
    this.typeTimer = null;
    if (this.dlgBox) {
      this.dlgBox.destroy(true);
      this.dlgBox = null;
    }
    this.dlgChoices = [];
    this.showingChoices = false;
    this.payload = null;
  }

  update(): void {
    if (!this.payload) return;
    // 打开后 250ms 内忽略 E，避免触发对话的同一按键直接推进
    const justOpened = this.time.now - this.openAt < 250;

    if (this.showingChoices) {
      if (Phaser.Input.Keyboard.JustDown(this.keys.UP) || Phaser.Input.Keyboard.JustDown(this.keys.W)) this.moveChoice(-1);
      if (Phaser.Input.Keyboard.JustDown(this.keys.DOWN) || Phaser.Input.Keyboard.JustDown(this.keys.S)) this.moveChoice(1);
      if (Phaser.Input.Keyboard.JustDown(this.keys.N1)) this.selectChoice(0);
      if (Phaser.Input.Keyboard.JustDown(this.keys.N2)) this.selectChoice(1);
      if (Phaser.Input.Keyboard.JustDown(this.keys.N3)) this.selectChoice(2);
      if (!justOpened && Phaser.Input.Keyboard.JustDown(this.keys.E)) this.advance();
    } else if (!justOpened && Phaser.Input.Keyboard.JustDown(this.keys.E)) {
      this.advance();
    }
  }

  private selectChoice(i: number): void {
    if (!this.payload?.choices || i >= this.payload.choices.length) return;
    this.choiceIdx = i;
    this.advance();
  }
}
