import Phaser from 'phaser';
import {
  AudioPreferences,
  SettingsSceneData,
  loadAudioPreferences,
  saveAudioPreferences,
} from '../game/preferences';

type ToggleDefinition = {
  key: keyof AudioPreferences;
  label: string;
  description: string;
};

type ToggleVisuals = {
  background: Phaser.GameObjects.Rectangle;
  statusText: Phaser.GameObjects.Text;
};

const TOGGLE_DEFINITIONS: ToggleDefinition[] = [
  {
    key: 'musicEnabled',
    label: 'Musica del tavolo',
    description: 'Controlla il tappeto sonoro di sottofondo durante la partita.',
  },
  {
    key: 'effectsEnabled',
    label: 'Effetti di gioco',
    description: 'Attiva prese, scope e segnali sonori senza toccare la musica.',
  },
];

export class SettingsScene extends Phaser.Scene {
  private preferences: AudioPreferences = loadAudioPreferences();
  private returnSceneKey = 'MenuScene';
  private toggleVisuals = new Map<keyof AudioPreferences, ToggleVisuals>();

  constructor() {
    super({ key: 'SettingsScene' });
  }

  create(data?: SettingsSceneData): void {
    const width = this.scale.width;
    const height = this.scale.height;

    this.preferences = loadAudioPreferences();
    this.returnSceneKey = data?.returnSceneKey ?? 'MenuScene';

    this.add.rectangle(0, 0, width, height, 0x123d22).setOrigin(0);
    this.add.rectangle(width / 2, height / 2, width - 120, height - 120, 0x0d2216, 0.88)
      .setStrokeStyle(2, 0xd9b75f, 0.45);

    this.add.text(width / 2, 120, 'Impostazioni audio', {
      fontFamily: 'Georgia, serif',
      fontSize: '46px',
      color: '#ffd700',
      stroke: '#000000',
      strokeThickness: 4,
      resolution: 2,
    }).setOrigin(0.5);

    this.add.text(width / 2, 176, 'Musica ed effetti sono separati: ogni scelta viene salvata subito e sarà usata nelle prossime partite.', {
      fontFamily: 'Georgia, serif',
      fontSize: '19px',
      color: '#d7ead1',
      resolution: 2,
      align: 'center',
      wordWrap: { width: 760 },
    }).setOrigin(0.5);

    TOGGLE_DEFINITIONS.forEach((definition, index) => {
      this.createToggleRow(definition, width / 2, 286 + index * 132, 760, 96);
    });

    this.add.text(width / 2, 556, 'Puoi tornare al menu in qualsiasi momento: la difficoltà si sceglie lì, l’audio resta salvato qui.', {
      fontFamily: 'Georgia, serif',
      fontSize: '16px',
      color: '#cfe5cd',
      resolution: 2,
      align: 'center',
      wordWrap: { width: 720 },
    }).setOrigin(0.5);

    this.createButton(width / 2, height - 112, 280, 60, 'Torna al menu', 'Rientra alla schermata iniziale', () => {
      this.returnToMenu();
    });
  }

  private createToggleRow(definition: ToggleDefinition, x: number, y: number, width: number, height: number): void {
    const row = this.add.rectangle(x, y, width, height, 0x173323, 0.96)
      .setStrokeStyle(2, 0xcaa74a, 0.35)
      .setInteractive({ useHandCursor: true });

    this.add.text(x - width / 2 + 28, y - 16, definition.label, {
      fontFamily: 'Georgia, serif',
      fontSize: '24px',
      color: '#ffffff',
      resolution: 2,
    }).setOrigin(0, 0.5);

    this.add.text(x - width / 2 + 28, y + 14, definition.description, {
      fontFamily: 'Georgia, serif',
      fontSize: '16px',
      color: '#d8ead2',
      resolution: 2,
      wordWrap: { width: 470 },
    }).setOrigin(0, 0.5);

    const toggleBackground = this.add.rectangle(x + width / 2 - 106, y, 148, 46, 0x356b39, 1)
      .setStrokeStyle(2, 0xf5e1a4, 0.45);
    const statusText = this.add.text(x + width / 2 - 106, y, '', {
      fontFamily: 'Georgia, serif',
      fontSize: '20px',
      color: '#ffffff',
      resolution: 2,
    }).setOrigin(0.5);

    this.toggleVisuals.set(definition.key, {
      background: toggleBackground,
      statusText,
    });

    row.on('pointerdown', () => {
      this.togglePreference(definition.key);
    });
    row.on('pointerover', () => row.setFillStyle(0x1d402c, 1));
    row.on('pointerout', () => row.setFillStyle(0x173323, 0.96));

    this.refreshToggle(definition.key);
  }

  private createButton(
    x: number,
    y: number,
    width: number,
    height: number,
    label: string,
    subtitle: string,
    onClick: () => void,
  ): void {
    const button = this.add.rectangle(x, y, width, height, 0x1f6f78, 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);

    button.on('pointerover', () => button.setFillStyle(0x2f8f99));
    button.on('pointerout', () => button.setFillStyle(0x1f6f78));
    button.on('pointerdown', onClick);
  }

  private togglePreference(key: keyof AudioPreferences): void {
    this.preferences = saveAudioPreferences({
      ...this.preferences,
      [key]: !this.preferences[key],
    });
    this.refreshToggle(key);
  }

  private refreshToggle(key: keyof AudioPreferences): void {
    const visuals = this.toggleVisuals.get(key);

    if (!visuals) {
      return;
    }

    const enabled = this.preferences[key];
    visuals.background.setFillStyle(enabled ? 0x356b39 : 0x7a2f2f);
    visuals.statusText.setText(enabled ? 'Attivo' : 'Disattivato');
  }

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