// 常驻 UI 场景：对话框（说话者名+头像+文本+三选项）、向日葵表盘、提示、横幅、过渡
import Phaser from "phaser";
import { director } from "../core/director";
import { audio } from "../core/audio";
import { corruptText } from "../core/textcorrupt";
import { NPC_NAMES } from "../data/story";

export interface UiChoice { label: string; cb?: () => void; }
export interface SayOpts {
  choices?: UiChoice[];
  onDone?: () => void;
  clean?: boolean;       // 免腐蚀（公告/系统文本）
  speakerName?: string;  // 覆盖显示名
}

const FONT = { fontFamily: '"PingFang SC","Hiragino Sans GB",sans-serif', fontSize: "9px", color: "#4a3828" };
const FONT_W = { ...FONT, color: "#fff8e8" };

export class UIScene extends Phaser.Scene {
  private sunflower!: Phaser.GameObjects.Sprite;
  private boxG!: Phaser.GameObjects.Graphics;
  private nameText!: Phaser.GameObjects.Text;
  private lineText!: Phaser.GameObjects.Text;
  private portrait!: Phaser.GameObjects.Image;
  private moreHint!: Phaser.GameObjects.Text;
  private choiceTexts: Phaser.GameObjects.Text[] = [];
  private promptText!: Phaser.GameObjects.Text;
  private bannerText!: Phaser.GameObjects.Text;
  private toastText!: Phaser.GameObjects.Text;
  private duskRect!: Phaser.GameObjects.Rectangle;
  private fadeRect!: Phaser.GameObjects.Rectangle;
  private glitchTxt!: Phaser.GameObjects.Text;

  dialogOpen = false;
  private lines: { speaker: string; text: string }[] = [];
  private lineIdx = 0;
  private typing = false;
  private typeEvent?: Phaser.Time.TimerEvent;
  private curOpts: SayOpts = {};
  private choiceMode = false;
  private choiceIdx = 0;
  private keyE!: Phaser.Input.Keyboard.Key;
  private keyEnter!: Phaser.Input.Keyboard.Key;
  private keyUp!: Phaser.Input.Keyboard.Key;
  private keyDown!: Phaser.Input.Keyboard.Key;
  private keyW!: Phaser.Input.Keyboard.Key;
  private keyS!: Phaser.Input.Keyboard.Key;

  constructor() { super("ui"); }

  create() {
    const kb = this.input.keyboard!;
    this.keyE = kb.addKey("E"); this.keyEnter = kb.addKey("ENTER");
    this.keyUp = kb.addKey("UP"); this.keyDown = kb.addKey("DOWN");
    this.keyW = kb.addKey("W"); this.keyS = kb.addKey("S");

    // 黄昏色调
    this.duskRect = this.add.rectangle(160, 90, 320, 180, 0xd06a2a, 0).setDepth(5);
    // 向日葵表盘（不显示任何数字）
    this.sunflower = this.add.sprite(17, 17, "sunflower", 3).setDepth(10);
    // 对话框
    this.boxG = this.add.graphics().setDepth(20).setVisible(false);
    this.portrait = this.add.image(24, 155, "portrait_smile").setDepth(21).setScale(1.4).setVisible(false);
    this.nameText = this.add.text(44, 136, "", { ...FONT, fontSize: "9px", color: "#a05c28" }).setDepth(21).setVisible(false);
    this.lineText = this.add.text(44, 148, "", { ...FONT, wordWrap: { width: 250 } }).setDepth(21).setVisible(false).setLineSpacing(3);
    this.moreHint = this.add.text(306, 168, "▼", { ...FONT, fontSize: "8px" }).setDepth(21).setVisible(false);
    // 提示 / 横幅 / 小告示
    this.promptText = this.add.text(160, 122, "", { ...FONT_W, fontSize: "9px" }).setOrigin(0.5).setDepth(15)
      .setStroke("#4a3828", 3).setVisible(false);
    this.bannerText = this.add.text(160, 70, "", { ...FONT_W, fontSize: "16px" }).setOrigin(0.5).setDepth(30)
      .setStroke("#4a3828", 4).setAlpha(0);
    this.toastText = this.add.text(316, 6, "", { ...FONT_W, fontSize: "8px", align: "right" }).setOrigin(1, 0).setDepth(30)
      .setStroke("#4a3828", 3).setAlpha(0);
    this.glitchTxt = this.add.text(160, 100, "", { ...FONT, fontSize: "12px", color: "#e84860" }).setOrigin(0.5).setDepth(40)
      .setStroke("#1a1a22", 3).setVisible(false);
    // 全屏渐变遮罩
    this.fadeRect = this.add.rectangle(160, 90, 320, 180, 0x000000, 0).setDepth(50);

    director.on("happiness", this.updateSunflower, this);
    director.on("stage", this.updateSunflower, this);
    director.on("quest", this.onQuest, this);
    director.on("dusk", this.onDusk, this);
    director.on("day", this.onDay, this);
    this.updateSunflower();

    this.events.on("shutdown", () => {
      director.off("happiness", this.updateSunflower, this);
      director.off("stage", this.updateSunflower, this);
      director.off("quest", this.onQuest, this);
      director.off("dusk", this.onDusk, this);
      director.off("day", this.onDay, this);
    });
  }

  // ---- 向日葵表盘（§6.1 分段点亮，满格花心黑籽） ----
  private updateSunflower() {
    const h = director.happiness;
    let petals: number;
    if (h <= 20) petals = Math.floor(h / 7);
    else if (h <= 50) petals = 3 + Math.floor(((h - 21) * 3) / 29);
    else if (h <= 80) petals = 7 + Math.floor(((h - 51) * 2) / 29);
    else if (h <= 99) petals = 10 + Math.floor(((h - 81) * 2) / 18);
    else petals = 12;
    const frame = h >= 100 ? 13 : petals;
    this.sunflower.setFrame(frame);
    // S3：花瓣过亮
    if (director.stage >= 3) this.sunflower.setTintFill();
    this.sunflower.clearTint();
    if (director.stage >= 3) this.sunflower.setTint(0xffffd8);
  }

  private onQuest(id: string) {
    if (director.questStatus[id] === "done") {
      audio.sfxDing();
      this.toast("任务完成");
    } else {
      this.toast("（拒绝被记录了）");
    }
  }
  private onDusk() {
    audio.sfxBell();
    this.tweens.add({ targets: this.duskRect, fillAlpha: 0.22, duration: 2500 });
    this.toast("黄昏了。回屋睡觉吧。");
  }
  private onDay(d: number) {
    this.duskRect.setFillStyle(0xd06a2a, 0);
    this.banner(`第 ${d} 日`);
  }

  banner(text: string) {
    this.bannerText.setText(text).setAlpha(0);
    this.tweens.add({ targets: this.bannerText, alpha: 1, duration: 600, hold: 1400, yoyo: true });
  }
  toast(text: string) {
    this.toastText.setText(text).setAlpha(1);
    this.tweens.killTweensOf(this.toastText);
    this.tweens.add({ targets: this.toastText, alpha: 0, delay: 2200, duration: 600 });
  }
  glitchText(text: string, ms: number) {
    this.glitchTxt.setText(text).setVisible(true);
    this.time.delayedCall(ms, () => this.glitchTxt.setVisible(false));
  }
  prompt(text: string | null) {
    if (text) this.promptText.setText(text).setVisible(true);
    else this.promptText.setVisible(false);
  }
  fadeOut(ms: number, cb?: () => void) {
    this.tweens.add({ targets: this.fadeRect, fillAlpha: 1, duration: ms, onComplete: () => cb?.() });
  }
  fadeIn(ms: number) {
    this.tweens.add({ targets: this.fadeRect, fillAlpha: 0, duration: ms });
  }

  // ---- 对话 ----
  say(speaker: string, rawLines: string[], opts: SayOpts = {}) {
    this.lines = rawLines.map(t => ({ speaker, text: t }));
    this.lineIdx = 0;
    this.curOpts = opts;
    this.dialogOpen = true;
    this.choiceMode = false;
    this.drawBox();
    this.showLine();
  }

  private drawBox() {
    this.boxG.clear().setVisible(true);
    this.boxG.fillStyle(0xfff4da, 0.96).fillRect(4, 130, 312, 46);
    this.boxG.lineStyle(2, 0xa05c28, 1).strokeRect(4, 130, 312, 46);
    this.portrait.setVisible(true);
    this.nameText.setVisible(true);
    this.lineText.setVisible(true);
  }

  private portraitFor(speaker: string) {
    if (speaker === "me") { this.portrait.setTexture("portrait_smile").setScale(1.4); return; }
    if (speaker === "meReal") { this.portrait.setTexture("portrait_real").setScale(1.4); return; }
    const base = speaker.startsWith("bird") ? "bird" : speaker;
    if (this.textures.exists("npc_" + base)) {
      // 用 NPC 立绘当前表情档作为头像
      const expr = director.npcExpr(base);
      const frame = expr === "flat" ? 1 : 0;
      this.portrait.setTexture("npc_" + base, frame).setScale(1.5);
    } else if (base === "bird") {
      this.portrait.setTexture("bird", 0).setScale(1.8);
    } else {
      this.portrait.setTexture("portrait_smile").setScale(1.4);
      if (speaker !== "me") this.portrait.setVisible(false);
    }
  }

  private showLine() {
    const entry = this.lines[this.lineIdx];
    const disp = this.curOpts.clean ? entry.text : corruptText(entry.text, entry.speaker);
    const name = this.curOpts.speakerName ?? NPC_NAMES[entry.speaker] ?? entry.speaker;
    this.nameText.setText(name);
    this.portraitFor(entry.speaker);
    this.lineText.setText("");
    this.moreHint.setVisible(false);
    this.typing = true;
    let i = 0;
    this.typeEvent?.remove();
    this.typeEvent = this.time.addEvent({
      delay: 28, repeat: disp.length - 1,
      callback: () => {
        i++;
        this.lineText.setText(disp.slice(0, i));
        if (i % 3 === 1 && !entry.text.startsWith("（")) audio.sfxTalk();
        if (i >= disp.length) { this.typing = false; this.moreHint.setVisible(true); }
      },
    });
    (this as any)._fullLine = disp;
  }

  private advance() {
    if (this.typing) {
      this.typeEvent?.remove();
      this.typing = false;
      this.lineText.setText((this as any)._fullLine);
      this.moreHint.setVisible(true);
      return;
    }
    if (this.lineIdx < this.lines.length - 1) {
      this.lineIdx++;
      this.showLine();
      return;
    }
    if (this.curOpts.choices && !this.choiceMode) {
      this.enterChoices();
      return;
    }
    this.closeDialog();
  }

  private enterChoices() {
    this.choiceMode = true;
    this.choiceIdx = 0;
    this.portraitFor("me"); // 选择时显示主角微笑头像（永远同一帧）
    this.nameText.setText(director.playerName);
    const cs = this.curOpts.choices!;
    cs.forEach((c, i) => {
      const t = this.add.text(60, 92 + i * 12, c.label, { ...FONT, backgroundColor: "#fff4da", padding: { x: 4, y: 2 } })
        .setDepth(25);
      this.choiceTexts.push(t);
    });
    this.renderChoiceSel();
  }
  private renderChoiceSel() {
    this.choiceTexts.forEach((t, i) => {
      t.setText((i === this.choiceIdx ? "▶ " : "  ") + this.curOpts.choices![i].label);
      t.setColor(i === this.choiceIdx ? "#c04818" : "#4a3828");
    });
  }
  private confirmChoice() {
    const c = this.curOpts.choices![this.choiceIdx];
    this.choiceTexts.forEach(t => t.destroy());
    this.choiceTexts = [];
    const done = this.curOpts.onDone;
    this.curOpts = {};
    this.dialogOpen = false;
    this.hideBox();
    c.cb?.();
    // 若选项回调未开启新对话，则触发 onDone
    if (!this.dialogOpen) done?.();
  }

  // 场景切换时强制关闭残留对话
  forceClose() {
    if (!this.dialogOpen && !this.choiceTexts.length) return;
    this.typeEvent?.remove();
    this.typing = false;
    this.choiceTexts.forEach(t => t.destroy());
    this.choiceTexts = [];
    this.choiceMode = false;
    this.curOpts = {};
    this.dialogOpen = false;
    this.hideBox();
  }

  private closeDialog() {
    const done = this.curOpts.onDone;
    this.curOpts = {};
    this.dialogOpen = false;
    this.hideBox();
    done?.();
  }
  private hideBox() {
    this.boxG.setVisible(false);
    this.portrait.setVisible(false);
    this.nameText.setVisible(false);
    this.lineText.setVisible(false);
    this.moreHint.setVisible(false);
  }

  update(_t: number, dt: number) {
    director.tick(_t, dt);
    if (this.dialogOpen) {
      const pressE = Phaser.Input.Keyboard.JustDown(this.keyE) || Phaser.Input.Keyboard.JustDown(this.keyEnter);
      if (this.choiceMode) {
        if (Phaser.Input.Keyboard.JustDown(this.keyUp) || Phaser.Input.Keyboard.JustDown(this.keyW)) {
          this.choiceIdx = (this.choiceIdx + this.curOpts.choices!.length - 1) % this.curOpts.choices!.length;
          this.renderChoiceSel();
        }
        if (Phaser.Input.Keyboard.JustDown(this.keyDown) || Phaser.Input.Keyboard.JustDown(this.keyS)) {
          this.choiceIdx = (this.choiceIdx + 1) % this.curOpts.choices!.length;
          this.renderChoiceSel();
        }
        if (pressE) this.confirmChoice();
      } else if (pressE) {
        this.advance();
      }
    }
  }
}
