/* 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';

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

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

  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 ? 'Opened the current data folder.' : 'Could not open the data folder.');
    });
  }

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

      if (result.cancelled) {
        this.statusMessage.set('Export cancelled.');
        return;
      }

      this.statusMessage.set(result.filePath ? `Exported data to ${result.filePath}.` : 'Exported data.');
    });
  }

  async importData(): Promise<void> {
    if (!window.confirm('Importing data replaces the current local data. Existing data will be moved to a backup folder first. Continue?')) {
      return;
    }

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

      if (result.cancelled) {
        this.statusMessage.set('Import cancelled.');
        return;
      }

      this.restartRequired.set(result.restartRequired);
      this.statusMessage.set(result.backupPath
        ? `Imported data. Previous data was backed up to ${result.backupPath}.`
        : 'Imported data.');
    });
  }

  async eraseData(): Promise<void> {
    if (!window.confirm('Erase all local MetoYou data on this device? This cannot be undone.')) {
      return;
    }

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

      this.restartRequired.set(result.restartRequired);
      this.statusMessage.set('Local data erased. Restart the app to finish resetting the session.');
      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 : 'Data operation failed.');
    } finally {
      this.busyAction.set(null);
    }
  }
}
