import { Component, inject, signal, viewChild } from '@angular/core';
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
import { firstValueFrom } from 'rxjs';
import { CreateRecipeInput, RecipeListItem } from '../../core/models/recipe.models';
import { RecipeManagementService } from '../../core/services/recipe-management.service';
import { RecipeService } from '../../core/services/recipe.service';
import { RecipeFormComponent } from './recipe-form.component';
import { ExcelImportPanelComponent } from './excel-import-panel.component';
import { extractApiError } from '../../core/utils/api-error.util';

type Tab = 'manual' | 'edit' | 'import';

@Component({
  selector: 'app-manage-meals',
  standalone: true,
  imports: [TranslatePipe, RecipeFormComponent, ExcelImportPanelComponent],
  template: `
    <div class="space-y-6">
      <header class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
        <div>
          <h1 class="text-2xl font-extrabold tracking-tight sm:text-3xl">{{ 'manage.title' | translate }}</h1>
          <p class="mt-1 text-slate-500 dark:text-slate-400">{{ 'manage.subtitle' | translate }}</p>
        </div>
        <button
          type="button"
          class="btn-secondary shrink-0"
          [disabled]="recalculatePending()"
          (click)="handleRecalculate()"
        >
          @if (recalculatePending()) {
            <span class="inline-block h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent"></span>
            {{ 'manage.recalculating' | translate }}
          } @else {
            ↻ {{ 'manage.recalculateMacros' | translate }}
          }
        </button>
      </header>

      @if (recalculateError()) {
        <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">
          {{ recalculateError() }}
        </div>
      }

      <div class="flex gap-2 border-b border-slate-200 dark:border-slate-800">
        <button
          type="button"
          (click)="setTab('manual')"
          class="flex items-center gap-2 border-b-2 px-4 py-2.5 text-sm font-semibold transition"
          [class]="
            tab() === 'manual'
              ? 'border-brand-600 text-brand-600'
              : 'border-transparent text-slate-500 hover:text-slate-700 dark:text-slate-400'
          "
        >
          ✎ {{ 'manage.tabManual' | translate }}
        </button>
        <button
          type="button"
          (click)="setTab('edit')"
          class="flex items-center gap-2 border-b-2 px-4 py-2.5 text-sm font-semibold transition"
          [class]="
            tab() === 'edit'
              ? 'border-brand-600 text-brand-600'
              : 'border-transparent text-slate-500 hover:text-slate-700 dark:text-slate-400'
          "
        >
          ✏ {{ 'manage.tabEdit' | translate }}
        </button>
        <button
          type="button"
          (click)="setTab('import')"
          class="flex items-center gap-2 border-b-2 px-4 py-2.5 text-sm font-semibold transition"
          [class]="
            tab() === 'import'
              ? 'border-brand-600 text-brand-600'
              : 'border-transparent text-slate-500 hover:text-slate-700 dark:text-slate-400'
          "
        >
          ↑ {{ 'manage.tabImport' | translate }}
        </button>
      </div>

      @if (successMessage() && (tab() === 'manual' || tab() === 'edit')) {
        <div
          class="flex items-center gap-2 rounded-xl bg-brand-50 p-3 text-sm font-medium text-brand-800 dark:bg-brand-950/40 dark:text-brand-200"
        >
          ✓ {{ successMessage() }}
        </div>
      }

      @if (tab() === 'manual') {
        <app-recipe-form
          #recipeForm
          [pending]="pending()"
          [error]="formError()"
          (submitRecipe)="handleCreate($event)"
        />
      } @else if (tab() === 'edit') {
        <div class="grid gap-6 lg:grid-cols-[280px_1fr]">
          <div class="card max-h-[70vh] overflow-y-auto p-4">
            <label class="block text-sm">
              <span class="font-medium">{{ 'common.search' | translate }}</span>
              <input class="input mt-1 w-full" [value]="searchQuery()" (input)="onSearch($event)" />
            </label>
            <ul class="mt-3 space-y-1">
              @if (loadingList()) {
                <li class="text-sm text-slate-400">{{ 'common.loading' | translate }}</li>
              } @else {
                @for (r of filteredRecipes(); track r.id) {
                  <li>
                    <button
                      type="button"
                      class="w-full rounded-lg px-3 py-2 text-left text-sm transition"
                      [class.bg-brand-600]="editingId() === r.id"
                      [class.text-white]="editingId() === r.id"
                      (click)="startEdit(r.id)"
                    >
                      {{ r.name }}
                    </button>
                  </li>
                }
              }
            </ul>
          </div>
          <div>
            @if (editingId()) {
              <app-recipe-form
                #editForm
                [pending]="pending()"
                [error]="formError()"
                [editMode]="true"
                [recipeId]="editingId()"
                (submitRecipe)="handleUpdate($event)"
              />
            } @else {
              <p class="text-sm text-slate-400">{{ 'manage.selectRecipeToEdit' | translate }}</p>
            }
          </div>
        </div>
      } @else {
        <app-excel-import-panel />
      }
    </div>
  `,
})
export class ManageMealsComponent {
  private readonly management = inject(RecipeManagementService);
  private readonly recipes = inject(RecipeService);
  private readonly translate = inject(TranslateService);
  private readonly recipeForm = viewChild('recipeForm', { read: RecipeFormComponent });
  private readonly editForm = viewChild('editForm', { read: RecipeFormComponent });

  readonly tab = signal<Tab>('manual');
  readonly pending = signal(false);
  readonly formError = signal<string | null>(null);
  readonly successMessage = signal<string | null>(null);
  readonly recipeList = signal<RecipeListItem[]>([]);
  readonly searchQuery = signal('');
  readonly loadingList = signal(false);
  readonly editingId = signal<number | null>(null);
  readonly recalculatePending = signal(false);
  readonly recalculateError = signal<string | null>(null);

  readonly filteredRecipes = () => {
    const q = this.searchQuery().trim().toLowerCase();
    const list = this.recipeList();
    if (!q) return list;
    return list.filter((r) => r.name.toLowerCase().includes(q));
  };

  setTab(id: Tab): void {
    this.tab.set(id);
    this.formError.set(null);
    this.successMessage.set(null);
    if (id === 'edit') this.loadRecipeList();
  }

  onSearch(event: Event): void {
    this.searchQuery.set((event.target as HTMLInputElement).value);
  }

  loadRecipeList(): void {
    this.loadingList.set(true);
    this.recipes.getRecipes().subscribe({
      next: (items) => {
        this.recipeList.set(items);
        this.loadingList.set(false);
      },
      error: () => {
        this.recipeList.set([]);
        this.loadingList.set(false);
      },
    });
  }

  async startEdit(id: number): Promise<void> {
    this.editingId.set(id);
    this.formError.set(null);
    this.successMessage.set(null);
    try {
      const recipe = await firstValueFrom(this.recipes.getRecipeById(id));
      setTimeout(() => this.editForm()?.loadRecipe(recipe));
    } catch (err) {
      this.formError.set(extractApiError(err, this.translate.instant('errors.loadRecipeFailed')));
    }
  }

  async handleCreate(input: CreateRecipeInput): Promise<void> {
    this.formError.set(null);
    this.successMessage.set(null);
    this.pending.set(true);
    try {
      const recipe = await firstValueFrom(this.management.createRecipe(input));
      this.successMessage.set(this.translate.instant('manage.savedSuccess', { name: recipe.name }));
      this.recipeForm()?.reset();
    } catch (err) {
      this.formError.set(extractApiError(err, this.translate.instant('errors.saveRecipeFailed')));
    } finally {
      this.pending.set(false);
    }
  }

  async handleUpdate(input: CreateRecipeInput): Promise<void> {
    const id = this.editingId();
    if (!id) return;
    this.formError.set(null);
    this.successMessage.set(null);
    this.pending.set(true);
    try {
      const recipe = await firstValueFrom(this.management.updateRecipe(id, input));
      this.successMessage.set(this.translate.instant('manage.updatedSuccess', { name: recipe.name }));
      this.loadRecipeList();
    } catch (err) {
      this.formError.set(extractApiError(err, this.translate.instant('errors.saveRecipeFailed')));
    } finally {
      this.pending.set(false);
    }
  }

  async handleRecalculate(): Promise<void> {
    this.recalculateError.set(null);
    this.successMessage.set(null);
    this.recalculatePending.set(true);
    try {
      const result = await firstValueFrom(this.management.recalculateAllMacros());
      this.successMessage.set(
        this.translate.instant('manage.recalculateSuccess', {
          updated: result.recipesUpdated,
          processed: result.recipesProcessed,
          unlinked: result.unlinkedIngredientRows,
        }),
      );
      if (this.tab() === 'edit') {
        this.loadRecipeList();
        const id = this.editingId();
        if (id) await this.startEdit(id);
      }
    } catch (err) {
      this.recalculateError.set(
        extractApiError(err, this.translate.instant('errors.recalculateMacrosFailed')),
      );
    } finally {
      this.recalculatePending.set(false);
    }
  }
}
