/* 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 {
  lucideDatabase,
  lucideDownload,
  lucideFolderOpen,
  lucideRefreshCw,
  lucideTrash2,
  lucideUpload
} from '@ng-icons/lucide';

import { ElectronBridgeService } from '../../../../core/platform/electron/electron-bridge.service';
import { APP_TRANSLATE_IMPORTS, AppI18nService } from '../../../../core/i18n';

type DataAction = 'open' | 'export' | 'import' | 'erase' | 'restart';

@Component({
  selector: 'app-data-settings',
  standalone: true,
  imports: [
    CommonModule,
    NgIcon,
    ...APP_TRANSLATE_IMPORTS
  ],
  viewProviders: [
    provideIcons({
      lucideDatabase,
      lucideDownload,
      lucideFolderOpen,
      lucideRefreshCw,
      lucideTrash2,
      lucideUpload
    })
  ],
  templateUrl: './data-settings.component.html'
})
export class DataSettingsComponent {
  private readonly electron = inject(ElectronBridgeService);
  private readonly appI18n = inject(AppI18nService);

  readonly isElectron = this.electron.isAvailable;
  readonly dataPath = signal<string | null>(null);
  readonly busyAction = signal<DataAction | null>(null);
  readonly statusMessage = signal<string | null>(null);
  readonly errorMessage = signal<string | null>(null);
  readonly restartRequired = signal(false);

  constructor() {
    void this.loadDataPath();
  }

  async openDataFolder(): Promise<void> {
    await this.runAction('open', async () => {
      const opened = await this.electron.requireApi().openCurrentDataFolder();

      this.statusMessage.set(opened
        ? this.appI18n.instant('settings.data.messages.openedFolder')
        : this.appI18n.instant('settings.data.messages.couldNotOpenFolder'));
    });
  }

  async exportData(): Promise<void> {
    await this.runAction('export', async () => {
      const result = await this.electron.requireApi().exportUserData();

      if (result.cancelled) {
        this.statusMessage.set(this.appI18n.instant('settings.data.messages.exportCancelled'));
        return;
      }

      this.statusMessage.set(result.filePath
        ? this.appI18n.instant('settings.data.messages.exportedTo', { path: result.filePath })
        : this.appI18n.instant('settings.data.messages.exported'));
    });
  }

  async importData(): Promise<void> {
    if (!window.confirm(this.appI18n.instant('settings.data.import.confirm'))) {
      return;
    }

    await this.runAction('import', async () => {
      const result = await this.electron.requireApi().importUserData();

      if (result.cancelled) {
        this.statusMessage.set(this.appI18n.instant('settings.data.messages.importCancelled'));
        return;
      }

      this.restartRequired.set(result.restartRequired);
      this.statusMessage.set(result.backupPath
        ? this.appI18n.instant('settings.data.messages.importedWithBackup', { path: result.backupPath })
        : this.appI18n.instant('settings.data.messages.imported'));
    });
  }

  async eraseData(): Promise<void> {
    if (!window.confirm(this.appI18n.instant('settings.data.erase.confirm'))) {
      return;
    }

    await this.runAction('erase', async () => {
      const result = await this.electron.requireApi().eraseUserData();

      this.restartRequired.set(result.restartRequired);
      this.statusMessage.set(this.appI18n.instant('settings.data.messages.erased'));
      await this.loadDataPath();
    });
  }

  async restartApp(): Promise<void> {
    await this.runAction('restart', async () => {
      await this.electron.requireApi().relaunchApp();
    });
  }

  private async loadDataPath(): Promise<void> {
    if (!this.isElectron) {
      return;
    }

    try {
      this.dataPath.set(await this.electron.requireApi().getAppDataPath());
    } catch {
      this.dataPath.set(null);
    }
  }

  private async runAction(action: DataAction, operation: () => Promise<void>): Promise<void> {
    this.busyAction.set(action);
    this.errorMessage.set(null);
    this.statusMessage.set(null);

    try {
      await operation();
    } catch (error) {
      this.errorMessage.set(error instanceof Error ? error.message : this.appI18n.instant('settings.data.messages.operationFailed'));
    } finally {
      this.busyAction.set(null);
    }
  }
}
