import { CommonModule } from '@angular/common';
import {
  ChangeDetectionStrategy,
  Component,
  computed,
  effect,
  signal,
  ViewChild,
  untracked,
} from '@angular/core';
import { Reunion as ReunionType } from 'src/app/core/interfaces/reunion';
import { DataTable, SortState, TableColumn } from '@shared/components/data-table/data-table';
import { Paginator } from '@shared/components/paginator/paginator';
import { SearchBar } from '@shared/components/search-bar/search-bar';
import { Modal } from '@shared/components/modal/modal';
import { ReunionForm } from '@shared/forms/reunion-form/reunion-form';
import { ReunionService } from 'src/app/core/services/reunion';
import { ZardButtonComponent } from '@shared/components/button/button.component';
import { ZardCardComponent } from '@shared/components/card/card.component';
import { SortDir } from '@shared/paging/paging';
import { LucideAngularModule } from 'lucide-angular';

@Component({
  standalone: true,
  selector: 'app-reunion-list',
  imports: [
    CommonModule,
    DataTable,
    Paginator,
    SearchBar,
    Modal,
    ReunionForm,
    ZardButtonComponent,
    ZardCardComponent,
    LucideAngularModule,
  ],
  templateUrl: './reunion.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ReunionList {
  // Core reactive state
  rows = signal<ReunionType[]>([]);
  loading = signal(false);
  total = signal(0);
  upcomingReunions = signal(0);
  pastReunions = signal(0);
  uniqueHippodromes = signal(0);

  // pagination, sorting, search
  page = signal(1);
  size = signal(10);
  search = signal('');
  sort = signal<SortState>({ key: 'date', dir: 'asc' });
  pageSize = [10, 20, 50];

  // modal management
  modalOpen = signal(false);
  modalTitle = signal('Nouvelle réunion');
  editingItem = signal<Partial<ReunionType> | null>(null);

  @ViewChild(ReunionForm) formComp?: ReunionForm;

  cols: TableColumn<ReunionType>[] = [
    { key: 'code', label: 'Code', sortable: true },
    { key: 'nom', label: 'Nom', sortable: true },
    {
      key: 'date',
      label: 'Date',
      sortable: true,
      cell: (r) =>
        new Date(r.date).toLocaleDateString('fr-FR', {
          day: '2-digit',
          month: 'short',
          year: 'numeric',
        }),
    },
    { key: 'numero', label: 'Numéro', sortable: true },
    {
      key: 'hippodrome.nom',
      label: 'Hippodrome',
      cell: (r) =>
        r.hippodrome ? `${r.hippodrome.nom} (${r.hippodrome.ville}, ${r.hippodrome.pays})` : '—',
    },
    {
      key: 'statut',
      label: 'Statut',
      cell: (r) => {
        const colorMap: Record<string, string> = {
          PLANIFIEE: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300',
          EN_COURS: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-300',
          TERMINEE: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300',
          ANNULEE: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-300',
        };
        const labelMap: Record<string, string> = {
          PLANIFIEE: 'Planifiée',
          EN_COURS: 'En cours',
          TERMINEE: 'Terminée',
          ANNULEE: 'Annulée',
        };
        return `<span class="px-2 py-1 rounded-full text-xs font-semibold ${colorMap[r.statut]}">${
          labelMap[r.statut]
        }</span>`;
      },
    },
    {
      key: 'totalCourses',
      label: 'Courses',
      cell: (r) => (r.totalCourses ? r.totalCourses.toString() : '—'),
    },
    {
      key: 'createdAt',
      label: 'Créée le',
      cell: (r) =>
        new Date(r.createdAt).toLocaleDateString('fr-FR', {
          day: '2-digit',
          month: 'short',
          year: 'numeric',
        }),
    },
    {
      key: 'updatedAt',
      label: 'Modifiée le',
      cell: (r) =>
        new Date(r.updatedAt).toLocaleDateString('fr-FR', {
          day: '2-digit',
          month: 'short',
          year: 'numeric',
        }),
    },
  ];

  constructor(private api: ReunionService) {
    // Effect will run only when one of these dependencies change
    effect(() => {
      const params = {
        page: this.page(),
        size: this.size(),
        search: this.search(),
        sortKey: this.sort().key,
        sortDir: this.sort().dir,
      };
      untracked(() => this.fetch(params)); // avoids recursive dependency
    });
  }

  private fetch(params: {
    page: number;
    size: number;
    search: string;
    sortKey: string;
    sortDir: SortDir;
  }) {
    this.loading.set(true);
    this.api.list(params).subscribe({
      next: (res) => {
        this.rows.set(res.content);
        this.total.set(res.pageable.total);
        const meta = res.pageable;

        this.upcomingReunions.set(0);
        this.pastReunions.set(0);
        this.uniqueHippodromes.set(0);
        this.loading.set(false);
      },
      error: () => {
        this.rows.set([]);
        this.total.set(0);
        this.upcomingReunions.set(0);
        this.pastReunions.set(0);
        this.uniqueHippodromes.set(0);
        this.loading.set(false);
      },
    });
  }

  // === UI interactions ===
  onSearch(q: string) {
    this.search.set(q);
    this.page.set(1); // reset pagination on new search
  }

  openCreate() {
    this.modalTitle.set('Nouvelle réunion');
    this.editingItem.set(null);
    queueMicrotask(() => this.modalOpen.set(true));
  }

  openEdit(row: ReunionType) {
    this.modalTitle.set('Modifier la réunion');
    this.editingItem.set(row);
    queueMicrotask(() => this.modalOpen.set(true));
  }

  closeModal() {
    this.modalOpen.set(false);
  }

  submitChildForm() {
    this.formComp?.onSubmit();
  }

  onFormSave(payload: Partial<ReunionType>) {
    const current = this.editingItem();
    const req$ = current?.id
      ? this.api.update(current.id, payload)
      : this.api.create(payload as Omit<ReunionType, 'id'>);
    req$.subscribe(() => {
      this.closeModal();
      // Reset editing item to null to clear the form
      this.editingItem.set(null);
      // refetch current page
      this.fetch({
        page: this.page(),
        size: this.size(),
        search: this.search(),
        sortKey: this.sort().key,
        sortDir: this.sort().dir,
      });
    });
  }

  remove(row: ReunionType) {
    if (!confirm(`Supprimer la réunion « ${row.nom} » ?`)) return;
    this.api.delete(row.id).subscribe(() =>
      this.fetch({
        page: this.page(),
        size: this.size(),
        search: this.search(),
        sortKey: this.sort().key,
        sortDir: this.sort().dir,
      })
    );
  }
}
