/* eslint-disable @typescript-eslint/member-ordering */
import {
  Component,
  DestroyRef,
  computed,
  inject,
  signal
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { CommonModule } from '@angular/common';
import { NgIcon, provideIcons } from '@ng-icons/core';
import {
  lucideBug,
  lucideCircleAlert,
  lucideClock3,
  lucideMemoryStick,
  lucideTrash2,
  lucideTriangleAlert
} from '@ng-icons/lucide';
import { interval } from 'rxjs';
import { startWith, switchMap } from 'rxjs/operators';

import { DebuggingService } from '../../../../core/services/debugging.service';
import { ElectronBridgeService } from '../../../../core/platform/electron/electron-bridge.service';
import { formatAppRamLabel } from '../../../../core/platform/electron/electron-app-metrics.rules';
import { PlatformService } from '../../../../core/platform';
import { APP_TRANSLATE_IMPORTS, AppI18nService } from '../../../../core/i18n';

const APP_METRICS_POLL_INTERVAL_MS = 2_000;

@Component({
  selector: 'app-debugging-settings',
  standalone: true,
  imports: [
    CommonModule,
    NgIcon,
    ...APP_TRANSLATE_IMPORTS
  ],
  viewProviders: [
    provideIcons({
      lucideBug,
      lucideCircleAlert,
      lucideClock3,
      lucideMemoryStick,
      lucideTrash2,
      lucideTriangleAlert
    })
  ],
  templateUrl: './debugging-settings.component.html'
})
export class DebuggingSettingsComponent {
  private readonly destroyRef = inject(DestroyRef);
  private readonly platform = inject(PlatformService);
  private readonly electronBridge = inject(ElectronBridgeService);
  readonly debugging = inject(DebuggingService);
  private readonly appI18n = inject(AppI18nService);

  readonly isElectron = this.platform.isElectron;
  readonly ramLabel = signal<string | null>(null);
  readonly enabled = this.debugging.enabled;
  readonly isConsoleOpen = this.debugging.isConsoleOpen;
  readonly entryCount = computed(() => {
    return this.debugging.entries().reduce((sum, entry) => sum + entry.count, 0);
  });
  readonly errorCount = computed(() => {
    return this.debugging.entries().reduce((sum, entry) => {
      return sum + (entry.level === 'error' ? entry.count : 0);
    }, 0);
  });
  readonly warningCount = computed(() => {
    return this.debugging.entries().reduce((sum, entry) => {
      return sum + (entry.level === 'warn' ? entry.count : 0);
    }, 0);
  });
  readonly lastUpdatedLabel = computed(() => {
    const lastEntry = this.debugging.entries().at(-1);

    return lastEntry ? lastEntry.timeLabel : this.appI18n.instant('settings.debugging.noLogsYet');
  });

  constructor() {
    if (this.isElectron)
      this.startRamPolling();
  }

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

    this.debugging.setEnabled(input.checked);
  }

  openConsole(): void {
    this.debugging.openConsole();
  }

  clearLogs(): void {
    this.debugging.clear();
  }

  private startRamPolling(): void {
    const api = this.electronBridge.getApi();

    if (!api?.getAppMetrics)
      return;

    interval(APP_METRICS_POLL_INTERVAL_MS)
      .pipe(
        startWith(0),
        switchMap(() => api.getAppMetrics()),
        takeUntilDestroyed(this.destroyRef)
      )
      .subscribe({
        next: (snapshot) => {
          this.ramLabel.set(formatAppRamLabel(snapshot));
        },
        error: () => {
          this.ramLabel.set(null);
        }
      });
  }
}
