import { Component, ElementRef, inject, signal, viewChild } from '@angular/core';
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
import { firstValueFrom } from 'rxjs';
import { RecipeManagementService } from '../../core/services/recipe-management.service';
import { RecipeImportResult } from '../../core/models/recipe.models';
import { extractApiError } from '../../core/utils/api-error.util';

@Component({
  selector: 'app-excel-import-panel',
  standalone: true,
  imports: [TranslatePipe],
  template: `
    <div class="space-y-6">
      <section class="card p-6">
        <div class="flex items-start gap-4">
          <div class="grid h-12 w-12 shrink-0 place-items-center rounded-xl bg-brand-100 text-brand-700 dark:bg-brand-900/40 dark:text-brand-300">
            📊
          </div>
          <div class="flex-1">
            <h2 class="text-lg font-bold">{{ 'manage.importTitle' | translate }}</h2>
            <p class="mt-1 text-sm text-slate-500 dark:text-slate-400">{{ 'manage.importDescription' | translate }}</p>
            <button type="button" (click)="downloadTemplate()" [disabled]="downloading()" class="btn-secondary mt-4">
              @if (downloading()) {
                <span class="inline-block h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent"></span>
              } @else {
                ↓
              }
              {{ 'manage.downloadTemplate' | translate }}
            </button>
          </div>
        </div>
      </section>

      <section class="card space-y-4 p-6">
        <label class="block text-sm font-medium">{{ 'manage.uploadLabel' | translate }}</label>
        <input
          #fileInput
          type="file"
          accept=".xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
          class="block w-full text-sm text-slate-500 file:mr-4 file:rounded-lg file:border-0 file:bg-brand-50 file:px-4 file:py-2 file:text-sm file:font-semibold file:text-brand-700 hover:file:bg-brand-100 dark:file:bg-brand-900/40 dark:file:text-brand-300"
          (change)="onFileSelected($event)"
        />

        @if (importError()) {
          <div role="alert" class="rounded-xl bg-red-50 p-3 text-sm text-red-700 dark:bg-red-950/40 dark:text-red-300">
            {{ importError() }}
          </div>
        }

        @if (importResult()) {
          <div class="rounded-xl border border-brand-200 bg-brand-50 p-4 dark:border-brand-800 dark:bg-brand-950/30">
            <div class="flex items-center gap-2 font-semibold text-brand-800 dark:text-brand-200">
              ✓ {{ 'manage.importComplete' | translate }}
            </div>
            <p class="mt-2 text-sm text-slate-600 dark:text-slate-300">
              {{ 'manage.createdCount' | translate: { count: importResult()!.createdCount } }} ·
              {{ 'manage.skippedCount' | translate: { count: importResult()!.skippedCount } }}
            </p>
            @if (importResult()!.errors.length > 0) {
              <ul class="mt-3 max-h-40 space-y-1 overflow-y-auto text-sm text-amber-700 dark:text-amber-300">
                @for (msg of importResult()!.errors; track msg) {
                  <li>• {{ msg }}</li>
                }
              </ul>
            }
          </div>
        }

        <button
          type="button"
          [disabled]="!selectedFile() || importPending()"
          (click)="handleImport()"
          class="btn-primary"
        >
          @if (importPending()) {
            <span class="inline-block h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent"></span>
          } @else {
            ↑
          }
          {{ importPending() ? ('manage.importing' | translate) : ('manage.importRecipes' | translate) }}
        </button>
      </section>

      <section class="rounded-xl border border-dashed border-slate-300 p-4 text-sm text-slate-500 dark:border-slate-700 dark:text-slate-400">
        <p class="font-medium text-slate-700 dark:text-slate-200">{{ 'manage.excelFormatTitle' | translate }}</p>
        <ul class="mt-2 list-inside list-disc space-y-1">
          <li>{{ 'manage.excelRecipesSheet' | translate }}</li>
          <li>{{ 'manage.excelIngredientsSheet' | translate }}</li>
          <li>{{ 'manage.excelStepsSheet' | translate }}</li>
        </ul>
        <p class="mt-2">{{ 'manage.duplicateSkipped' | translate }}</p>
      </section>
    </div>
  `,
})
export class ExcelImportPanelComponent {
  private readonly management = inject(RecipeManagementService);
  private readonly translate = inject(TranslateService);
  private readonly fileInput = viewChild<ElementRef<HTMLInputElement>>('fileInput');

  readonly selectedFile = signal<File | null>(null);
  readonly downloading = signal(false);
  readonly importPending = signal(false);
  readonly importError = signal<string | null>(null);
  readonly importResult = signal<RecipeImportResult | null>(null);

  onFileSelected(event: Event): void {
    const input = event.target as HTMLInputElement;
    this.selectedFile.set(input.files?.[0] ?? null);
  }

  async downloadTemplate(): Promise<void> {
    this.downloading.set(true);
    try {
      const blob = await firstValueFrom(this.management.downloadImportTemplate());
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = 'DailyMeals-recipe-import-template.xlsx';
      link.click();
      URL.revokeObjectURL(url);
    } finally {
      this.downloading.set(false);
    }
  }

  async handleImport(): Promise<void> {
    const file = this.selectedFile();
    if (!file) return;

    this.importError.set(null);
    this.importResult.set(null);
    this.importPending.set(true);
    try {
      const result = await firstValueFrom(this.management.importFromExcel(file));
      this.importResult.set(result);
      this.selectedFile.set(null);
      const input = this.fileInput()?.nativeElement;
      if (input) input.value = '';
    } catch (err) {
      this.importError.set(extractApiError(err, this.translate.instant('errors.importFailed')));
    } finally {
      this.importPending.set(false);
    }
  }
}
