// 村广场（30×20）：公告板、花坛、双子鸟树、庆典场地。
// 代码补充交互区：C3 邮筒信件、T13 彩带 ×4、T14 站立点、T15 庆典场地。
// D6 T14 保持微笑 60 秒；D6 傍晚脚本雨；D7 结局分歧；雾墙门 D5 前劝离。

import { MapScene, type InteractZone } from './MapScene';
import { director } from '../core/CorruptionDirector';
import { audio } from '../audio/AudioEngine';
import { CLUES } from '../data/clues';
import {
  MAILBOX_BEFORE, WIPE_ASK, WIPE_ACCEPT, WIPE_REFUSE,
  RIBBON_LINES, RIBBON_DONE, T14_INTRO, T14_MOVE_WARN, T14_DONE,
  T15_INTRO, FOG_DISSUADE, NARRATOR,
} from '../data/dialogues';

export class PlazaScene extends MapScene {
  readonly mapKey = 'plaza';

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

  private t14State: 'idle' | 'running' = 'idle';
  private t14Ms = 0;
  private t14Faded = false;
  private t14WarnCd = 0;

  protected onReady(): void {
    this.t14State = 'idle';
    this.t14Ms = 0;
    this.t14Faded = false;
    this.t14WarnCd = 0;
  }

  protected extraInteractZones(): InteractZone[] {
    const nb = this.interactZones.find((z) => z.id === 'noticeboard') ?? { id: '', x: 240, y: 160 };
    return [
      // C3：邮筒旁散落信件（邮筒瓦片 46 在公告板附近，代码补不可见交互区）
      { id: 'mailbox_c3', x: nb.x - 48, y: nb.y + 24 },
      // T13：在广场挂彩带 ×4（对齐彩带瓦片中心 (11,7)/(18,7)/(11,13)/(18,13)）
      { id: 'ribbon_1', x: nb.x - 48, y: nb.y - 32 },
      { id: 'ribbon_2', x: nb.x + 64, y: nb.y - 32 },
      { id: 'ribbon_3', x: nb.x - 48, y: nb.y + 64 },
      { id: 'ribbon_4', x: nb.x + 64, y: nb.y + 64 },
      // T14：保持微笑站立点（避开花坛与公告板 24px 交互圈）
      { id: 'smile_spot', x: nb.x, y: nb.y + 32 },
      // T15：庆典场地
      { id: 'celebration_site', x: nb.x, y: nb.y - 72 },
    ];
  }

  protected async canUseDoor(target: string): Promise<boolean> {
    if (target === 'fog' && director.day < 5) {
      await this.say({ lines: FOG_DISSUADE });
      return false;
    }
    if (this.t14State === 'running') {
      this.cancelT14();
    }
    return true;
  }

  protected async onInteract(id: string): Promise<boolean> {
    // 公告板：阿福公告（逐字）+ 当日任务；D5 可擦拭（T12，可拒绝）
    if (id === 'noticeboard') {
      await this.showNoticeBoard();
      if (director.isTaskActive('T12')) {
        const c = await this.say({ lines: WIPE_ASK, choices: [
          { label: '（拿起抹布擦拭）', kind: 'accept' },
          { label: '（放下抹布）', kind: 'refuse' },
        ] });
        if (c === 0) {
          director.addClue('C6'); // 擦到一半浮现旧字迹
          await this.say({ lines: WIPE_ACCEPT });
          director.completeTask('T12');
          audio.ding();
        } else {
          await this.say({ lines: WIPE_REFUSE });
          director.refuseTask('T12');
        }
      }
      return true;
    }

    // C3：邮筒旁散落信件（D2 起）
    if (id === 'mailbox_c3') {
      if (director.day < 2) {
        await this.say({ lines: MAILBOX_BEFORE });
      } else {
        director.addClue('C3');
        await this.say({ lines: CLUES.C3.lines });
      }
      return true;
    }

    // T13：挂彩带 ×4
    if (id.startsWith('ribbon_')) {
      if (!director.isTaskActive('T13')) {
        await this.say({ lines: ['这里还不需要彩带。'] });
        return true;
      }
      const done = director.taskSetProgress['ribbons'] ?? new Set<string>();
      if (done.has(id)) {
        await this.say({ lines: RIBBON_DONE });
        return true;
      }
      done.add(id);
      director.taskSetProgress['ribbons'] = done;
      // 挂上彩带（tiles16 帧 29/30/31 红/黄/蓝；地图上挂点是路灯，挂上后才出现彩带）
      const z = this.interactZones.find((zz) => zz.id === id);
      if (z) {
        const frame = [29, 30, 31, 29][done.size - 1]; // tiles16 帧 = 瓦片 id（彩带红/黄/蓝）
        const deco = this.add.image(z.x, z.y, 'tiles16', frame);
        deco.setDepth(z.y - 8);
      }
      await this.say({ lines: RIBBON_LINES });
      if (done.size >= 4) {
        director.completeTask('T13');
        audio.ding();
      }
      return true;
    }

    // T14：保持微笑 60 秒
    if (id === 'smile_spot') {
      if (!director.isTaskActive('T14')) {
        await this.say({ lines: ['广场中央很暖和。'] });
        return true;
      }
      if (this.t14State === 'running') return true;
      await this.say({ speakerId: 'afu', lines: T14_INTRO });
      this.startT14();
      return true;
    }

    // T15：参加第 413 届丰收庆典 → 结局分歧（E4/E2/E1；E3 需走向雾墙）
    if (id === 'celebration_site') {
      if (director.day !== 7 || !director.isTaskActive('T15')) {
        await this.say({ lines: ['庆典场地空空的。等庆典那天再来吧。'] });
        return true;
      }
      await this.say({ lines: T15_INTRO });
      director.completeTask('T15');
      const ending = director.evaluateEnding(false);
      director.startEnding(ending);
      this.scene.start('EndingScene', { ending });
      return true;
    }

    return false;
  }

  // ---------- T14 ----------
  private startT14(): void {
    this.t14State = 'running';
    this.t14Ms = 0;
    this.t14Faded = false;
    director.t14Active = true;
    for (const a of this.actors) a.stareAtPlayer = true; // 全村 NPC 转身注视
    this.cameras.main.zoomTo(1.35, 60_000); // 镜头缓慢拉近
  }

  private cancelT14(): void {
    this.t14State = 'idle';
    this.t14Ms = 0;
    director.t14Active = false;
    for (const a of this.actors) a.stareAtPlayer = false;
    this.cameras.main.zoomTo(1, 500);
    audio.restoreMaster(1000);
  }

  private async finishT14(): Promise<void> {
    this.t14State = 'idle';
    director.t14Active = false;
    for (const a of this.actors) a.stareAtPlayer = false;
    this.cameras.main.zoomTo(1, 2000);
    audio.restoreMaster(3000);
    // 先结算任务（此时 T13+T14 齐全会触发黄昏钟声，钟声对话会等空档播放），
    // 避免任务完成依赖玩家关闭后续对话
    director.completeTask('T14');
    audio.ding();
    await this.say({ speakerId: 'afu', lines: T14_DONE });
    // 傍晚脚本雨（村里第一次下雨，NPC 台词对雨零反应）
    director.setRain(true);
    await this.say({ lines: [NARRATOR.rainStart] });
  }

  protected extraUpdate(_time: number, delta: number): void {
    if (this.t14State !== 'running') return;
    const moving = (this.player.body?.velocity.lengthSq() ?? 0) > 1;
    if (moving || director.dialogueActive) {
      if (moving) {
        this.t14Ms = 0; // 原地站立：移动则重来
        if (this.t14Faded) {
          this.t14Faded = false;
          audio.restoreMaster(1000);
        }
        this.t14WarnCd -= delta;
        if (this.t14WarnCd <= 0) {
          this.t14WarnCd = 6000;
          void this.say({ speakerId: 'afu', lines: T14_MOVE_WARN });
        }
      }
      return;
    }
    this.t14Ms += delta;
    if (!this.t14Faded && this.t14Ms >= 40_000) {
      this.t14Faded = true;
      audio.fadeAllToZero(20_000); // 第 40–60 秒所有声音渐隐至零
    }
    if (this.t14Ms >= 60_000) {
      void this.finishT14();
    }
  }
}
