import Phaser from 'phaser';
import { sfx, music } from '../game/audio';
import { STRING_STYLES, type StringStyle } from '../sim/marionette';
import { loadProgress } from '../game/progress';
import { DAYS } from '../game/game';
import { fetchTop } from '../game/scores';

/**
 * Title card, launched as an overlay over the live stage so the dev harness is
 * available underneath from frame one. Pick your strings (difficulty modifier),
 * then click to begin — the stage restarts with the chosen string style, and
 * that first click also unblocks audio so the shamisen sting lands.
 */
export class Title extends Phaser.Scene {
  constructor() {
    super('title');
  }

  create(): void {
    const W = this.scale.width, H = this.scale.height;
    this.add.rectangle(W / 2, H / 2, W, H, 0x0a0705, 0.82);

    if (this.textures.exists('title_art')) {
      this.add.image(W / 2, H * 0.34, 'title_art').setScale(0.56).setDepth(1);
    }

    this.add.text(W / 2, H * 0.6, 'サンドニエット', { fontFamily: 'serif', fontSize: '52px', color: '#efe4cb' })
      .setOrigin(0.5).setDepth(1);
    this.add.text(W / 2, H * 0.66, 'S A N D O N I E T T E', { fontFamily: 'serif', fontSize: '18px', color: '#c8a24a' })
      .setOrigin(0.5).setDepth(1);

    // ---- string select: the unlockables-as-difficulty row ----
    const styles = Object.keys(STRING_STYLES) as StringStyle[];
    const picked = ((this.registry.get('sando.style') as StringStyle) ?? 'hemp');
    const labels = new Map<StringStyle, Phaser.GameObjects.Text>();
    const paint = (sel: StringStyle): void => {
      for (const [k, t] of labels) {
        t.setColor(k === sel ? '#e8b84a' : '#8a7a5a');
        t.setText(k === sel ? `▸ ${k.toUpperCase()} ◂` : k.toUpperCase());
      }
      blurb.setText(STRING_STYLES[sel].blurb);
    };
    styles.forEach((k, i) => {
      const t = this.add.text(W / 2 + (i - (styles.length - 1) / 2) * 150, H * 0.76, k.toUpperCase(), {
        fontFamily: 'monospace', fontSize: '18px', color: '#8a7a5a',
      }).setOrigin(0.5).setDepth(2).setInteractive({ useHandCursor: true });
      t.on('pointerdown', (_p: unknown, __x: unknown, ___y: unknown, ev?: { stopPropagation?: () => void }) => {
        ev?.stopPropagation?.();
        this.registry.set('sando.style', k);
        sfx.enable();
        sfx.shamisen();
        paint(k);
      });
      labels.set(k, t);
    });
    const blurb = this.add.text(W / 2, H * 0.81, '', { fontFamily: 'serif', fontSize: '14px', color: '#9a8a6a', fontStyle: 'italic' })
      .setOrigin(0.5).setDepth(1);
    paint(picked);

    // week select — only once the Shogun has been met
    if (loadProgress().ura) {
      const uraOn = ((this.registry.get('sando.ura') as boolean) ?? false);
      const weekBtn = this.add.text(W / 2, H * 0.855, '', { fontFamily: 'monospace', fontSize: '16px', color: '#e04a30' })
        .setOrigin(0.5).setDepth(2).setInteractive({ useHandCursor: true });
      const paintWeek = (on: boolean): void => {
        weekBtn.setText(on ? '▸ 裏 URA WEEK — the Shogun ◂' : '表 the week — (click for 裏)');
        weekBtn.setColor(on ? '#e04a30' : '#8a7a5a');
      };
      weekBtn.on('pointerdown', (_p: unknown, __x: unknown, ___y: unknown, ev?: { stopPropagation?: () => void }) => {
        ev?.stopPropagation?.();
        const next = !((this.registry.get('sando.ura') as boolean) ?? false);
        this.registry.set('sando.ura', next);
        this.registry.set('sando.day', 0);
        this.registry.set('sando.score', 0);
        sfx.enable();
        sfx.shamisen();
        paintWeek(next);
      });
      paintWeek(uraOn);
    }

    const shout = this.add.text(W / 2, H * 0.89, 'SHUBATTO!!  SANDONIETTE!!!', {
      fontFamily: 'serif', fontSize: '22px', color: '#e8b84a', fontStyle: 'bold',
    }).setOrigin(0.5).setDepth(1);
    this.tweens.add({ targets: shout, scale: 1.12, duration: 600, yoyo: true, repeat: -1, ease: 'Sine.inOut' });

    const hint = this.add.text(W / 2, H * 0.95, 'click to begin', { fontFamily: 'serif', fontSize: '15px', color: '#9a8a6a' })
      .setOrigin(0.5).setDepth(1);
    this.tweens.add({ targets: hint, alpha: 0.3, duration: 900, yoyo: true, repeat: -1 });

    // the trophy shelf: best-grade hanko stamps per day — base week right edge,
    // ura week (keys 100+) one column in, tinted the Shogun's red.
    const best = loadProgress().best;
    if (Object.keys(best).length > 0) {
      DAYS.forEach((_, i) => {
        for (const [off, x] of [[0, W - 46], [100, W - 104]] as [number, number][]) {
          const g = best[i + off];
          if (g === undefined) continue;
          const y = 90 + i * 56;
          if (this.textures.exists('day_stamp')) {
            this.add.image(x, y, 'day_stamp').setDisplaySize(44, 44).setAlpha(0.85).setDepth(2).setTint(off ? 0xff5040 : 0xffffff);
          } else this.add.circle(x, y, 20, off ? 0x5a0a20 : 0x8a1a12, 0.8).setDepth(2);
          this.add.text(x, y, g, { fontFamily: 'serif', fontSize: '20px', color: '#f4e8c4' }).setOrigin(0.5).setDepth(3);
          if (!off) this.add.text(x - 90, y, `${i + 1}`, { fontFamily: 'monospace', fontSize: '11px', color: '#8a7a5a' }).setOrigin(0.5).setDepth(2);
        }
      });
    }

    // the global board, bottom-left — top 5 of the week (async; blank offline)
    const board = this.add.text(28, H - 150, '', { fontFamily: 'monospace', fontSize: '12px', color: '#8a7a5a', lineSpacing: 5 })
      .setDepth(2);
    void fetchTop(((this.registry.get('sando.ura') as boolean) ?? false) ? 'ura' : 'omote').then((top) => {
      if (!board.active || !top.length) return;
      board.setText(['  TOP CHEFS', ...top.slice(0, 5).map((r, i) => `${i + 1}. ${r.name.padEnd(13)} ${r.score.toFixed(1)}`)].join('\n'));
    });

    // begin: anywhere that isn't a style button. Restart the stage so the puppet
    // is strung with the chosen style, then drop the overlay.
    this.input.on('pointerdown', (_p: Phaser.Input.Pointer, over: unknown[]) => {
      if (over.length > 0) return; // that click was a style pick
      sfx.enable();
      sfx.gong();
      sfx.shamisen();
      music.start();
      this.registry.set('sando.started', true);
      this.scene.get('stage').scene.restart();
      this.scene.stop();
    });
  }
}
