import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component, signal, ViewChild } from '@angular/core';
import { DataTable, TableColumn } from '@shared/components/data-table/data-table';
import { ZardButtonComponent } from '@shared/components/button/button.component';
import { ZardPaginationModule } from '@shared/components/pagination/pagination.module';
import { ListParams, PagedResult } from '@shared/paging/paging';
import { ResultatApiResponse, ResultatStatut } from 'src/app/core/interfaces/resultat';
import { ResultatService } from 'src/app/core/services/resultat';
import { Depouillement, ResultatCourse } from 'src/app/core/services/depouillement';
import { Course } from 'src/app/core/interfaces/course';
import { toast } from 'ngx-sonner';

@Component({
  standalone: true,
  selector: 'app-rapport',
  templateUrl: './rapport.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [CommonModule, DataTable, ZardButtonComponent, ZardPaginationModule],
})
export class Rapport {
  rows = signal<ResultatApiResponse[]>([]);
  loading = signal(false);
  sending = signal<Map<string, boolean>>(new Map());
  // Pagination state
  page = signal<number>(1);
  perPage = signal<number>(10);
  totalPages = signal<number>(1);
  totalElements = signal<number>(0);
  @ViewChild(DataTable) table?: DataTable<ResultatApiResponse>;

  cols: TableColumn<ResultatApiResponse>[] = [
        { key: 'courseNumero', label: 'N°' },
    { key: 'hippodromeNom', label: 'Hippodrome' },
    { key: 'courseNom', label: 'Course' },
    { key: 'ordreArrivee', label: "Ordre d'arrivée", cell: (r) => String(r.ordreArrivee ?? '').replace(/,/g, ' - ') },
    { key: 'statut', label: 'Statut', cell: (r)=>(r.statut.toString().toLowerCase().replace("_", " ")) },
    { key: 'datePublication', label: 'Date pub.', cell: (r) => r.datePublication ?? r.createdAt ?? '—' },
    { key: 'dateValidation', label: 'Date validation' },
  ];

  constructor(private api: ResultatService, private depouillement: Depouillement) {
    // initial load
    this.fetch();
  }
  private fetchPage(params?: Partial<ListParams>) {
    this.loading.set(true);
    const p: ListParams = { page: this.page(), size: this.perPage(), ...(params || {}) };
    this.api.listRawPaged(p).subscribe({
      next: (res: PagedResult<ResultatApiResponse>) => {
        const filtered = (res?.content || []).filter((r) => !!(r.ordreArrivee && String(r.ordreArrivee).trim()));
        this.rows.set(filtered);
        // normalize paging meta
        this.totalPages.set(res.totalPages ?? 1);
        this.totalElements.set(res.totalElements ?? (filtered.length || 0));
        // ensure local page is in sync with backend response
        if (res.pageable?.pageNumber) this.page.set(res.pageable.pageNumber);
        this.loading.set(false);
      },
      error: (err) => {
        console.error('Error fetching paged reports:', err);
        this.rows.set([]);
        this.loading.set(false);
      },
    });
  }

  fetch() {
    this.fetchPage();
  }

  onPageChange(nextPage: number) {
    this.page.set(nextPage);
    this.fetchPage();
  }

  onPerPageChange(size: number) {
    this.perPage.set(size);
    this.page.set(1);
    this.fetchPage();
  }

  // wrapper for template change event to avoid $event typing issues
  onPerPageChangeEvent(e: Event) {
    const v = (e.target as HTMLSelectElement)?.value;
    const size = Number(v) || 10;
    this.onPerPageChange(size);
  }

  openReport(row: ResultatApiResponse) {
    try {
      // Open a per-result report URL in a new tab. Adjust path if your server uses another route.
      const url = `/resultat/${row.id}`;
      window.open(url, '_blank');
    } catch (err) {
      console.error('Failed to open report for', row, err);
    }
  }

  isSending(id: string | number) {
    return !!this.sending().get(String(id));
  }

  private setSending(id: string | number, v: boolean) {
    const map = new Map(this.sending());
    map.set(String(id), v);
    this.sending.set(map);
  }

  sendToDepouillement(row: ResultatApiResponse) {
    if (!row || !row.id) return;
    const id = String(row.id);
    if (this.isSending(id)) return; // already sending

    this.setSending(id, true);

    // Build a minimal ResultatCourse payload using available fields.
    const course = {
      id: String((row as any).courseId ?? '')
    };

    const payload: Omit<ResultatCourse, "id"> = {
      course,
      statut: (row.statut as any) ?? (0 as any),
      ordreArrivee: String(row.ordreArrivee ?? ''),
      datePublication: row.datePublication ?? row.createdAt,
    };

      this.depouillement.sendResultat(payload).subscribe({
        next: (res) => {
          // After successful depouillement, update the resultat statut to PROVISOIRE
          const updateId = String((res && (res as any).id) ?? row.id);
          this.api.update(updateId, { statut: ResultatStatut.PROVISOIRE }).subscribe({
            next: (updated) => {
              // Update the local rows to reflect the new statut
              this.rows.set(
                this.rows().map((r) => (String(r.id) === String(updateId) ? { ...r, statut: ResultatStatut.PROVISOIRE } : r))
              );
              toast.success('Résultat envoyé au dépouillement et statut mis à jour.');
              this.setSending(id, false);
            },
            error: (err) => {
              console.error('Error updating resultat statut after depouillement:', err);
              toast.error('Échec de la mise à jour du statut du résultat.');
              this.setSending(id, false);
            },
          });
        },
        error: (err) => {
          console.error('Error sending to depouillement:', err);
          this.setSending(id, false);
        },
      });
  }
}
