import Phaser from 'phaser';
import { Difficulty } from '../game/types';
import { GameSceneData, loadAudioPreferences } from '../game/preferences';
import { SettingsScene } from './SettingsScene';

type MenuButtonPalette = {
  base: number;
  hover: number;
};

type DifficultyOption = {
  label: string;
  subtitle: string;
  value: Difficulty;
  palette: MenuButtonPalette;
};

type RuleSection = {
  heading: string;
  lines: string[];
};

const TITLE_STYLE: Phaser.Types.GameObjects.Text.TextStyle = {
  fontFamily: 'Georgia, serif',
  fontSize: '52px',
  color: '#ffd700',
  stroke: '#000000',
  strokeThickness: 4,
  resolution: 2,
};

const PANEL_TITLE_STYLE: Phaser.Types.GameObjects.Text.TextStyle = {
  fontFamily: 'Georgia, serif',
  fontSize: '24px',
  color: '#ffd700',
  resolution: 2,
};

const BODY_STYLE: Phaser.Types.GameObjects.Text.TextStyle = {
  fontFamily: 'Georgia, serif',
  fontSize: '18px',
  color: '#f8f5e6',
  resolution: 2,
};

export class MenuScene extends Phaser.Scene {
  constructor() {
    super({ key: 'MenuScene' });
  }

  create(): void {
    const width = this.scale.width;
    const height = this.scale.height;
    const audioPreferences = loadAudioPreferences();

    this.drawBackground(width, height);
    this.drawDecorativeCards(width, height);
    this.ensureSettingsSceneAvailable();

    this.add.text(width / 2, 92, 'Scopone Scientifico', TITLE_STYLE).setOrigin(0.5);
    this.add.text(width / 2, 142, 'Due squadre da due, una mano intera e lettura del tavolo fino all’ultimo punto.', {
      fontFamily: 'Georgia, serif',
      fontSize: '21px',
      color: '#d9f2d2',
      resolution: 2,
    }).setOrigin(0.5);

    this.createRulesPanel(width, height);
    this.createControlPanel(width, height, audioPreferences);
  }

  private drawBackground(width: number, height: number): void {
    this.add.rectangle(0, 0, width, height, 0x123d22).setOrigin(0);
    this.add.rectangle(width / 2, height / 2, width - 60, height - 60, 0x0b2916, 0.28)
      .setStrokeStyle(2, 0xe8c25d, 0.35);
    this.add.rectangle(width * 0.34, height * 0.58, width * 0.46, height * 0.50, 0x0d2215, 0.82)
      .setStrokeStyle(2, 0xc8a445, 0.4);
    this.add.rectangle(width * 0.77, height * 0.58, width * 0.24, height * 0.50, 0x10261b, 0.86)
      .setStrokeStyle(2, 0xc8a445, 0.4);
  }

  private drawDecorativeCards(width: number, height: number): void {
    const positions = [
      [width * 0.08, height * 0.85],
      [width * 0.14, height * 0.87],
      [width * 0.92, height * 0.85],
      [width * 0.86, height * 0.87],
    ];

    positions.forEach(([x, y]) => {
      this.add.image(x, y, 'retro').setScale(0.08).setAngle(Phaser.Math.Between(-15, 15)).setAlpha(0.9);
    });
  }

  private createRulesPanel(width: number, height: number): void {
    const panelX = width * 0.12;
    const panelY = 206;
    const sections: RuleSection[] = [
      {
        heading: 'Tavolo e squadre',
        lines: [
          'Si gioca in coppia: Sud e Nord contro Ovest ed Est.',
          'Nel vero scopone si distribuiscono tutte le 40 carte, 10 a giocatore.',
        ],
      },
      {
        heading: 'Come si prende',
        lines: [
          'Ogni carta cattura una carta dello stesso valore oppure una combinazione equivalente.',
          'Se sul tavolo c’è una presa diretta dello stesso valore, quella ha sempre la precedenza.',
        ],
      },
      {
        heading: 'Punteggio partita',
        lines: [
          'A fine mano contano carte, denari, settebello, primiera e scope.',
          'La sfida prosegue mano dopo mano finché una squadra arriva ad almeno 11 punti.',
        ],
      },
    ];

    this.add.text(panelX, panelY, 'Regolamento essenziale', PANEL_TITLE_STYLE).setOrigin(0, 0.5);

    let currentY = panelY + 44;
    sections.forEach((section) => {
      this.add.text(panelX, currentY, section.heading, {
        fontFamily: 'Georgia, serif',
        fontSize: '20px',
        color: '#ffffff',
        resolution: 2,
      }).setOrigin(0, 0.5);
      currentY += 30;

      section.lines.forEach((line) => {
        this.add.text(panelX, currentY, `• ${line}`, {
          ...BODY_STYLE,
          wordWrap: { width: width * 0.40 },
          lineSpacing: 5,
        }).setOrigin(0, 0);
        currentY += 54;
      });

      currentY += 6;
    });

    this.add.text(panelX, height - 92, 'Scegli la difficoltà quando vuoi iniziare: le preferenze audio vengono lette al momento della partita.', {
      ...BODY_STYLE,
      fontSize: '16px',
      color: '#cfe5cd',
      wordWrap: { width: width * 0.41 },
    }).setOrigin(0, 0.5);
  }

  private createControlPanel(width: number, height: number, audioPreferences: ReturnType<typeof loadAudioPreferences>): void {
    const panelCenterX = width * 0.77;
    const difficultyOptions: DifficultyOption[] = [
      {
        label: 'Principiante',
        subtitle: 'AI prudente e leggibile',
        value: 'beginner',
        palette: { base: 0x2e7d32, hover: 0x43a047 },
      },
      {
        label: 'Avanzato',
        subtitle: 'Pressione costante sul tavolo',
        value: 'advanced',
        palette: { base: 0xd97706, hover: 0xf59e0b },
      },
      {
        label: 'Maestro',
        subtitle: 'Massima lettura e priorità alle prese forti',
        value: 'master',
        palette: { base: 0xb91c1c, hover: 0xdc2626 },
      },
    ];

    this.add.text(panelCenterX, 214, 'Inizia una partita', PANEL_TITLE_STYLE).setOrigin(0.5);
    this.add.text(panelCenterX, 250, 'Ogni partita usa la difficoltà scelta qui sotto e le preferenze audio salvate.', {
      ...BODY_STYLE,
      fontSize: '16px',
      color: '#d7ead1',
      align: 'center',
      wordWrap: { width: 250 },
    }).setOrigin(0.5, 0);

    difficultyOptions.forEach((option, index) => {
      const y = 340 + index * 96;
      this.createButton(panelCenterX, y, 260, 64, option.label, option.subtitle, option.palette, () => {
        this.startGame(option.value);
      });
    });

    const musicLabel = audioPreferences.musicEnabled ? 'attiva' : 'disattivata';
    const effectsLabel = audioPreferences.effectsEnabled ? 'attivi' : 'disattivati';

    this.add.text(panelCenterX, height - 154, `Musica ${musicLabel} · Effetti ${effectsLabel}`, {
      ...BODY_STYLE,
      fontSize: '16px',
      color: '#cfe5cd',
      align: 'center',
    }).setOrigin(0.5);

    this.createButton(
      panelCenterX,
      height - 100,
      260,
      58,
      'Impostazioni audio',
      'Modifica musica ed effetti in modo indipendente',
      { base: 0x1f6f78, hover: 0x2f8f99 },
      () => {
        this.openSettings();
      },
    );
  }

  private createButton(
    x: number,
    y: number,
    width: number,
    height: number,
    label: string,
    subtitle: string,
    palette: MenuButtonPalette,
    onClick: () => void,
  ): void {
    const background = this.add.rectangle(x, y, width, height, palette.base, 1)
      .setStrokeStyle(2, 0xf5e1a4, 0.4)
      .setInteractive({ useHandCursor: true });

    this.add.text(x, y - 10, label, {
      fontFamily: 'Georgia, serif',
      fontSize: '21px',
      color: '#ffffff',
      stroke: '#000000',
      strokeThickness: 2,
      resolution: 2,
    }).setOrigin(0.5);

    this.add.text(x, y + 14, subtitle, {
      fontFamily: 'Georgia, serif',
      fontSize: '13px',
      color: '#f7f1d5',
      resolution: 2,
      align: 'center',
    }).setOrigin(0.5);

    background.on('pointerover', () => background.setFillStyle(palette.hover));
    background.on('pointerout', () => background.setFillStyle(palette.base));
    background.on('pointerdown', onClick);
  }

  private startGame(difficulty: Difficulty): void {
    const gameData: GameSceneData = {
      difficulty,
      audioPreferences: loadAudioPreferences(),
    };

    this.cameras.main.fadeOut(300, 0, 30, 0);
    this.cameras.main.once('camerafadeoutcomplete', () => {
      this.scene.start('GameScene', gameData);
    });
  }

  private openSettings(): void {
    this.ensureSettingsSceneAvailable();
    this.cameras.main.fadeOut(250, 0, 30, 0);
    this.cameras.main.once('camerafadeoutcomplete', () => {
      this.scene.start('SettingsScene', { returnSceneKey: 'MenuScene' });
    });
  }

  private ensureSettingsSceneAvailable(): void {
    let existingScene: Phaser.Scene | null = null;

    try {
      existingScene = this.scene.get('SettingsScene');
    } catch {
      existingScene = null;
    }

    if (existingScene instanceof SettingsScene) {
      return;
    }

    if (existingScene) {
      this.scene.remove('SettingsScene');
    }

    this.scene.add('SettingsScene', SettingsScene, false);
  }
}
