/* eslint-disable @typescript-eslint/member-ordering */
import {
  Component,
  inject,
  signal
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucidePower } from '@ng-icons/lucide';

import type { DesktopSettingsSnapshot } from '../../../../core/platform/electron/electron-api.models';
import { loadGeneralSettingsFromStorage, saveGeneralSettingsToStorage } from '../../../../infrastructure/persistence';
import { ElectronBridgeService } from '../../../../core/platform/electron/electron-bridge.service';
import { PlatformService } from '../../../../core/platform';
import { ExperimentalMediaSettingsService } from '../../../../domains/experimental-media/application/services/experimental-media-settings.service';
import { APP_TRANSLATE_IMPORTS } from '../../../../core/i18n';
import { SelectOnFocusDirective, SubmitOnEnterDirective } from '../../../../shared/directives';

@Component({
  selector: 'app-general-settings',
  standalone: true,
  imports: [
    CommonModule,
    NgIcon,
    SelectOnFocusDirective,
    SubmitOnEnterDirective,
    ...APP_TRANSLATE_IMPORTS
  ],
  viewProviders: [
    provideIcons({
      lucidePower
    })
  ],
  templateUrl: './general-settings.component.html'
})
export class GeneralSettingsComponent {
  private platform = inject(PlatformService);
  private electronBridge = inject(ElectronBridgeService);
  readonly experimentalMedia = inject(ExperimentalMediaSettingsService);

  readonly isElectron = this.platform.isElectron;
  reopenLastViewedChat = signal(true);
  autoStart = signal(false);
  closeToTray = signal(true);
  savingAutoStart = signal(false);
  savingCloseToTray = signal(false);
  ignoredGameProcesses = signal<string[]>([]);
  ignoredProcessDraft = signal('');
  savingIgnoredGameProcesses = signal(false);

  constructor() {
    this.loadGeneralSettings();

    if (this.isElectron) {
      void this.loadDesktopSettings();
      void this.loadIgnoredGameProcesses();
    }
  }

  onReopenLastViewedChatChange(event: Event): void {
    const input = event.target as HTMLInputElement;
    const settings = saveGeneralSettingsToStorage({
      reopenLastViewedChat: !!input.checked
    });

    this.reopenLastViewedChat.set(settings.reopenLastViewedChat);
  }

  async onAutoStartChange(event: Event): Promise<void> {
    const input = event.target as HTMLInputElement;
    const enabled = !!input.checked;
    const api = this.electronBridge.getApi();

    if (!this.isElectron || !api) {
      input.checked = this.autoStart();
      return;
    }

    this.savingAutoStart.set(true);

    try {
      const snapshot = await api.setDesktopSettings({ autoStart: enabled });

      this.applyDesktopSettings(snapshot);
    } catch {
      input.checked = this.autoStart();
    } finally {
      this.savingAutoStart.set(false);
    }
  }

  async onCloseToTrayChange(event: Event): Promise<void> {
    const input = event.target as HTMLInputElement;
    const enabled = !!input.checked;
    const api = this.electronBridge.getApi();

    if (!this.isElectron || !api) {
      input.checked = this.closeToTray();
      return;
    }

    this.savingCloseToTray.set(true);

    try {
      const snapshot = await api.setDesktopSettings({ closeToTray: enabled });

      this.applyDesktopSettings(snapshot);
    } catch {
      input.checked = this.closeToTray();
    } finally {
      this.savingCloseToTray.set(false);
    }
  }

  onExperimentalVlcPlaybackChange(event: Event): void {
    const input = event.target as HTMLInputElement;

    this.experimentalMedia.setVlcJsPlaybackEnabled(!!input.checked);
    input.checked = this.experimentalMedia.vlcJsPlaybackEnabled();
  }

  private async loadDesktopSettings(): Promise<void> {
    const api = this.electronBridge.getApi();

    if (!api) {
      return;
    }

    try {
      const snapshot = await api.getDesktopSettings();

      this.applyDesktopSettings(snapshot);
    } catch {}
  }

  private loadGeneralSettings(): void {
    const settings = loadGeneralSettingsFromStorage();

    this.reopenLastViewedChat.set(settings.reopenLastViewedChat);
  }

  private applyDesktopSettings(snapshot: DesktopSettingsSnapshot): void {
    this.autoStart.set(snapshot.autoStart);
    this.closeToTray.set(snapshot.closeToTray);
  }

  onIgnoredProcessDraftChange(event: Event): void {
    const input = event.target as HTMLInputElement;

    this.ignoredProcessDraft.set(input.value);
  }

  async addIgnoredProcess(): Promise<void> {
    const draft = this.ignoredProcessDraft().trim();

    if (!draft) {
      return;
    }

    const next = Array.from(new Set([...this.ignoredGameProcesses(), draft]));

    await this.saveIgnoredGameProcesses(next);
    this.ignoredProcessDraft.set('');
  }

  async removeIgnoredProcess(name: string): Promise<void> {
    const next = this.ignoredGameProcesses().filter((entry) => entry !== name);

    await this.saveIgnoredGameProcesses(next);
  }

  private async loadIgnoredGameProcesses(): Promise<void> {
    const api = this.electronBridge.getApi();

    if (!api?.getIgnoredGameProcesses) {
      return;
    }

    try {
      const list = await api.getIgnoredGameProcesses();

      this.ignoredGameProcesses.set(list);
    } catch {}
  }

  private async saveIgnoredGameProcesses(list: string[]): Promise<void> {
    const api = this.electronBridge.getApi();

    if (!api?.setIgnoredGameProcesses) {
      return;
    }

    this.savingIgnoredGameProcesses.set(true);

    try {
      const normalized = await api.setIgnoredGameProcesses(list);

      this.ignoredGameProcesses.set(normalized);
    } finally {
      this.savingIgnoredGameProcesses.set(false);
    }
  }
}
