// EndingScene：E1-E4 四结局演出 + 病历 + 「回到标题」按钮（PRD §9）。

import Phaser from 'phaser';
import { director } from '../core/CorruptionDirector';
import { audio } from '../audio/AudioEngine';
import { GAME_W, GAME_H, NAMED_NPCS, NPC_DEFS, type EndingId } from '../types';
import {
  ENDING_TITLES, E1_SUBTITLES, E2_SUBTITLE, E4_SUBTITLE, E3_RECORD,
} from '../data/endings';

export class EndingScene extends Phaser.Scene {
  private ending: EndingId = 'E1';
  private cm: Phaser.FX.ColorMatrix | null = null;

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

  create(data: { ending?: EndingId }): void {
    this.ending = data?.ending ?? 'E1';
    if (this.scene.isActive('UIScene')) this.scene.stop('UIScene');
    this.cameras.main.clearFX();
    this.cm = this.cameras.main.postFX.addColorMatrix();
    this.cameras.main.fadeIn(400, 0, 0, 0);

    switch (this.ending) {
      case 'E1': void this.playE1(); break;
      case 'E2': void this.playE2(); break;
      case 'E3': void this.playE3(); break;
      case 'E4': void this.playE4(); break;
    }
  }

  private wait(ms: number): Promise<void> {
    return new Promise((resolve) => this.time.delayedCall(ms, resolve));
  }

  private subtitle(text: string, y = GAME_H - 24): Phaser.GameObjects.Text {
    return this.add.text(GAME_W / 2, y, text, {
      fontFamily: 'monospace', fontSize: '9px', color: '#ffffff',
      stroke: '#000000', strokeThickness: 2,
    }).setOrigin(0.5);
  }

  private endScreen(): void {
    this.add.rectangle(GAME_W / 2, GAME_H - 9, GAME_W, 14, 0x000000, 0.7);
    this.add.text(GAME_W / 2 - 40, GAME_H - 9, ENDING_TITLES[this.ending], {
      fontFamily: 'monospace', fontSize: '8px', color: '#cccccc',
    }).setOrigin(0.5);
    const btn = this.add.text(GAME_W / 2 + 56, GAME_H - 9, '【回到标题】', {
      fontFamily: 'monospace', fontSize: '8px', color: '#F5A623',
    }).setOrigin(0.5).setInteractive({ useHandCursor: true });
    btn.on('pointerdown', () => {
      // 重开即从 Day 1 全新开始，无继承
      this.cameras.main.fadeOut(300, 0, 0, 0);
      this.cameras.main.once('camerafadeoutcomplete', () => {
        this.scene.start('TitleScene');
      });
    });
  }

  /** E1 糖衣：全村微笑合影定格，饱和度缓慢推到 1.5 */
  private async playE1(): Promise<void> {
    this.cameras.main.setBackgroundColor('#8FD3FF');
    this.add.rectangle(GAME_W / 2, GAME_H - 40, GAME_W, 80, 0x7dc95e);
    this.add.rectangle(GAME_W / 2, 30, 200, 20, 0xf7b7cb).setStrokeStyle(2, 0xf5a623);
    this.add.text(GAME_W / 2, 30, '第 413 届丰收庆典', {
      fontFamily: 'monospace', fontSize: '10px', color: '#fff',
    }).setOrigin(0.5);

    // 全村微笑合影（7 组 NPC + 主角）
    const all: string[] = [...NAMED_NPCS.map((id) => NPC_DEFS[id].spriteKey), 'player'];
    all.forEach((key, i) => {
      const x = 40 + i * 34;
      this.add.sprite(x, GAME_H - 60, key, 0).setOrigin(0.5, 1).setScale(1.5);
    });
    // 主角头像永远同一帧微笑（支柱 2）
    this.add.image(GAME_W / 2, GAME_H - 100, 'portrait_player_smile').setScale(2);

    // 饱和度缓慢推到 1.5
    let sat = 1.0;
    this.tweens.addCounter({
      from: 1.0, to: 1.5, duration: 5000,
      onUpdate: (tw) => {
        sat = tw.getValue() ?? 1;
        this.cm?.reset();
        this.cm?.saturate(sat);
      },
    });

    await this.wait(3500);
    this.subtitle(E1_SUBTITLES[0]);
    await this.wait(2500);
    this.subtitle(E1_SUBTITLES[1], GAME_H - 40);
    await this.wait(2000);
    this.endScreen();
  }

  /** E2 回收：画面骤停，负片 2 秒，心电滴一响；回到 Day 1 清晨的床上 */
  private async playE2(): Promise<void> {
    // 骤停：黑场
    this.cameras.main.setBackgroundColor('#000000');
    await this.wait(600);

    // 负片 2 秒 + 心电滴声一响
    this.cm?.negative();
    audio.ecg();
    await this.wait(2000);
    this.cm?.reset();

    // 回到 Day 1 清晨的床上（小屋地图做背景），日历翻回同一天
    this.cameras.main.setBackgroundColor('#1a1a3a');
    const map = this.make.tilemap({ key: 'map_house' });
    const tsName = map.tilesets.length > 0 ? map.tilesets[0].name : 'candy';
    const tiles = map.addTilesetImage(tsName, 'tileset');
    if (tiles) {
      map.createLayer('ground', tiles, 80, 30);
      map.createLayer('obstacles', tiles, 80, 30);
    }
    this.add.sprite(120, 96, 'player', 0).setOrigin(0.5, 1);
    // 日历（tiles16 帧 64）
    this.add.image(150, 60, 'tiles16', 64);
    this.tweens.add({
      targets: this.add.image(150, 60, 'tiles16', 64).setAlpha(0.6),
      alpha: 0, duration: 1500, yoyo: true, repeat: 1,
    });

    await this.wait(1800);
    this.subtitle(E2_SUBTITLE);
    await this.wait(2200);
    this.endScreen();
  }

  /** E3 苏醒：病历特写 → 最后一帧微笑消失 + 窗外灰麻雀 */
  private async playE3(): Promise<void> {
    this.cameras.main.setBackgroundColor('#f5f5f5');
    this.cameras.main.fadeIn(1000, 255, 255, 255);
    await this.wait(1200);

    // 病房背景：白床 + 监护仪
    this.add.image(60, 100, 'tiles16', 87).setOrigin(0).setScale(2);
    this.add.image(92, 100, 'tiles16', 88).setOrigin(0).setScale(2);
    this.add.image(60, 132, 'tiles16', 89).setOrigin(0).setScale(2);
    this.add.image(92, 132, 'tiles16', 90).setOrigin(0).setScale(2);
    this.add.image(140, 96, 'tiles16', 92).setOrigin(0).setScale(2);

    // 病历特写
    const card = this.add.rectangle(GAME_W / 2, GAME_H / 2, 240, 120, 0xffffff)
      .setStrokeStyle(2, 0xbdbdbd);
    void card;
    const lines = [
      E3_RECORD.header,
      '─────────────────',
      `${E3_RECORD.labels.name}：${director.playerName}`,
      `${E3_RECORD.labels.no}：${E3_RECORD.no}`,
      `${E3_RECORD.labels.duration}：${director.playTimeFormatted}`,
    ];
    this.add.text(GAME_W / 2, GAME_H / 2, lines.join('\n'), {
      fontFamily: 'monospace', fontSize: '10px', color: '#333333',
      align: 'center', lineSpacing: 6,
    }).setOrigin(0.5);
    await this.wait(5000);

    // 最后一帧：微笑消失，变成一张疲惫而真实的脸（支柱 2 全流程唯一一次变化）
    this.cameras.main.fadeOut(800, 0, 0, 0);
    await this.wait(850);
    this.children.removeAll();
    this.cameras.main.setBackgroundColor('#dadada');
    this.cameras.main.fadeIn(600, 0, 0, 0);
    // 窗
    this.add.rectangle(GAME_W / 2, 80, 120, 80, 0xf5f5f5).setStrokeStyle(2, 0x9e9e9e);
    // 窗外，一只灰色的、真的麻雀
    const sparrow = this.add.graphics();
    sparrow.fillStyle(0x777777, 1);
    sparrow.fillCircle(GAME_W / 2 + 30, 96, 3);       // 身
    sparrow.fillCircle(GAME_W / 2 + 33, 93, 2);       // 头
    sparrow.fillStyle(0x555555, 1);
    sparrow.fillTriangle(GAME_W / 2 + 27, 96, GAME_W / 2 + 22, 94, GAME_W / 2 + 27, 99); // 尾
    sparrow.fillStyle(0x333333, 1);
    sparrow.fillCircle(GAME_W / 2 + 34, 92, 0.5);     // 眼
    // 真实的脸
    this.add.image(GAME_W / 2, GAME_H - 60, 'portrait_player_real').setScale(2);
    this.subtitle('（疗程结束。欢迎回来。）', GAME_H - 24);
    await this.wait(3000);
    this.endScreen();
  }

  /** E4 静默：空广场，彩带在没有风的空气里飘 */
  private async playE4(): Promise<void> {
    this.cameras.main.setBackgroundColor('#cfcfcf');
    // 空广场（plaza 地图做背景，无 NPC）
    const map = this.make.tilemap({ key: 'map_plaza' });
    const tsName = map.tilesets.length > 0 ? map.tilesets[0].name : 'candy';
    const tiles = map.addTilesetImage(tsName, 'tileset');
    if (tiles) {
      map.createLayer('ground', tiles, 0, -60);
      map.createLayer('obstacles', tiles, 0, -60);
    }
    this.cm?.saturate(0.4);

    // 彩带在没有风的空气里飘
    const ribbons: Phaser.GameObjects.Image[] = [];
    for (let i = 0; i < 6; i++) {
      const r = this.add.image(40 + i * 50, 30 + (i % 3) * 20, 'tiles16', [29, 30, 31][i % 3]);
      ribbons.push(r);
      this.tweens.add({
        targets: r, y: r.y + 6, duration: 2200 + i * 300,
        yoyo: true, repeat: -1, ease: 'Sine.easeInOut',
      });
    }

    await this.wait(3500);
    this.subtitle(E4_SUBTITLE);
    await this.wait(2500);
    // 黑屏
    this.cameras.main.fadeOut(1500, 0, 0, 0);
    await this.wait(1600);
    this.endScreen();
  }
}
