import { useMemo, useCallback, useEffect, useState } from 'react';
import { useCandidatesStore, CandidateType } from '@/shared/api/stores/hr-service/candidatesStore';
import { enqueueSnackbar } from 'notistack';
import {
  AppointmentStatus,
  CandidateDTO,
  CandidateStatus,
  SourceCandidat,
  candidatesApi,
} from '@/shared/api/endpoints/hr/candidates';
import {
  CandidatureTab,
  ICandidature,
  CandidatureStatut,
  StatutRendezVous,
} from '@/shared/types/candidature';
import { mapFiltersToBackend } from '@/shared/types/candidate-filters';
import {
  DEFAULT_CANDIDATURE_TABLE_HEAD,
  DEFAULT_CANDIDATURE_RETENUS_CHAUFFEUR_TABLE_HEAD,
  DEFAULT_CANDIDATURE_RDV_SEMAINE_CHAUFFEUR_TABLE_HEAD,
  DEFAULT_CANDIDATURE_ABSENT_RDV_CHAUFFEUR_TABLE_HEAD,
  DEFAULT_CANDIDATURE_TABLEAU_CHAUFFEUR_TABLE_HEAD,
  DEFAULT_CANDIDATURE_TOUS_TABLE_HEAD,
  DEFAULT_CANDIDATURE_REFUSES_BLACKLISTES_TABLE_HEAD,
} from '@/shared/_mock/_candidature';

const statusMapping: Record<string, CandidateStatus> = {
  'À traiter': 'TO_PROCESS',
  'En cours': 'IN_PROGRESS',
  Retenu: 'RETAINED',
  Validé: 'VALIDATED',
  Refusé: 'REFUSED',
  Blacklisté: 'BLACKLISTED',
  Absent: 'ABSENT',

  aTraiter: 'TO_PROCESS',
  enCours: 'IN_PROGRESS',
  retenu: 'RETAINED',
  valide: 'VALIDATED',
  refuse: 'REFUSED',
  blackliste: 'BLACKLISTED',
  absent: 'ABSENT',
};

const reverseStatusMapping: Record<CandidateStatus, CandidatureStatut> = {
  TO_PROCESS: CandidatureStatut.ATraiter,
  IN_PROGRESS: CandidatureStatut.EnCours,
  RETAINED: CandidatureStatut.Retenu,
  VALIDATED: CandidatureStatut.Valide,
  REFUSED: CandidatureStatut.Refuse,
  BLACKLISTED: CandidatureStatut.Blackliste,
  ABSENT: CandidatureStatut.Absent,
};

const reverseAppointmentStatusMapping: Record<AppointmentStatus, StatutRendezVous> = {
  NO_APPOINTMENT: StatutRendezVous.PasDeRdv,
  SCHEDULED: StatutRendezVous.Programme,
  ATTENDED: StatutRendezVous.Honore,
  MISSED: StatutRendezVous.Absent,
  CANCELLED: StatutRendezVous.Annule,
  RESCHEDULED: StatutRendezVous.Replanifiee,
};

const reverseSourceMapping: Record<SourceCandidat, string> = {
  INDEED: 'Indeed',
  LINKEDIN: 'LinkedIn',
  POLE_EMPLOI: 'Pôle emploi',
  RECOMMENDATION: 'Recommandation',
  SITE_WEB: 'Site web',
  APEC: 'APEC',
  SPONTANEE: 'Candidature spontanée',
  WELCOME_TO_THE_JUNGLE: 'Welcome to the Jungle',
  AUTRE: 'Autre',
};

const convertBackendToFrontend = (candidate: CandidateDTO): ICandidature => ({
  id: candidate.id,
  nom: candidate.lastName,
  prenom: candidate.firstName,
  email: candidate.email,
  telephone: candidate.phone,
  age: candidate.age,
  address: candidate.address
    ? {
        address:
          typeof candidate.address === 'object'
            ? [
                (candidate.address as any)?.street,
                (candidate.address as any)?.city,
                (candidate.address as any)?.zipCode,
                (candidate.address as any)?.country,
              ]
                .filter(Boolean)
                .join(', ')
            : (candidate.address as any),
        lat: (candidate.address as any)?.latitude || 0,
        lng: (candidate.address as any)?.longitude || 0,
        city: (candidate.address as any)?.city || candidate.city,
        postalCode: (candidate.address as any)?.zipCode || candidate.postalCode,
        country: (candidate.address as any)?.country || '',
        formattedAddress:
          typeof candidate.address === 'object'
            ? [
                (candidate.address as any)?.street,
                (candidate.address as any)?.zipCode,
                (candidate.address as any)?.city,
                (candidate.address as any)?.country,
              ]
                .filter(Boolean)
                .join(', ')
            : (candidate.address as any),
      }
    : { address: '', lat: 0, lng: 0, city: '', postalCode: '', country: '', formattedAddress: '' },
  codePostal: candidate.postalCode,
  ville: candidate.city,
  departement: candidate.department,
  type: candidate.type === 'DRIVER' ? 'Candidature chauffeur' : 'Candidature sédentaire',
  statut: reverseStatusMapping[candidate.status as CandidateStatus] || CandidatureStatut.ATraiter,
  statusRDV:
    reverseAppointmentStatusMapping[candidate.appointmentStatus as AppointmentStatus] ||
    StatutRendezVous.PasDeRdv,
  dureePermis: candidate.drivingLicenseDuration || '',
  proximiteCircuit: candidate.circuitProximity || '',
  disponibilite: candidate.availability || '',
  suiviAppel: candidate.callFollowUp || '',
  dateAppelRappel: candidate.callBackDate || '',
  dateHeureRdvAgence: candidate.agencyAppointmentDateTime || '',
  raisonRefus: candidate.refusalReason || '',
  document: candidate.document || '',
  contrat_document: candidate.contractDocument || '',
  dateCandidature: candidate.applicationDate,
  sourceCandidat: candidate.sourceCandidate
    ? reverseSourceMapping[candidate.sourceCandidate] || 'Autre'
    : 'Autre',
  wasAbsentBefore: false,
});

export function useCandidatureTableBackend(
  activeTab: CandidatureTab,
  defaultType?: 'Candidature chauffeur' | 'Candidature sédentaire',
  onMainTabChange?: (tab: CandidatureTab) => void
) {
  const {
    candidates,
    loading,
    creating,
    updating,
    sendingEmail,
    sendingForm,
    totalElements,
    totalPages,
    currentPage,
    pageSize,
    fetchCandidatesByStatus,
    fetchRdvSemaineCandidates,
    fetchAbsentCandidates,
    fetchRefusedAndBlacklistedCandidates,
    fetchCandidates,
    fetchCandidatesByType,
    searchCandidatesAdvanced,
    createCandidate,
    updateCandidate,
    updateCandidateStatus,
    scheduleRdv,
    markAsAbsent,
    replanifyRdv,
    sendEmailToCandidate,
    sendFormToCandidate,
    setPage,
  } = useCandidatesStore();

  const [filters, setFilters] = useState<Record<string, { value: string; condition: string }>>({});
  const [filtersApplied, setFiltersApplied] = useState(false);

  const getTableHead = useMemo(() => {
    switch (activeTab) {
      case CandidatureTab.ATraiter:
        return DEFAULT_CANDIDATURE_TABLE_HEAD;
      case CandidatureTab.Retenus:
        return DEFAULT_CANDIDATURE_RETENUS_CHAUFFEUR_TABLE_HEAD;
      case CandidatureTab.RdvSemaine:
        return DEFAULT_CANDIDATURE_RDV_SEMAINE_CHAUFFEUR_TABLE_HEAD;
      case CandidatureTab.AbsentRdv:
        return DEFAULT_CANDIDATURE_ABSENT_RDV_CHAUFFEUR_TABLE_HEAD;
      case CandidatureTab.Tableau:
        return DEFAULT_CANDIDATURE_TABLEAU_CHAUFFEUR_TABLE_HEAD;
      case CandidatureTab.Tous:
        return DEFAULT_CANDIDATURE_TOUS_TABLE_HEAD;
      case CandidatureTab.RefusesBlacklistes:
        return DEFAULT_CANDIDATURE_REFUSES_BLACKLISTES_TABLE_HEAD;
      default:
        return DEFAULT_CANDIDATURE_TABLE_HEAD;
    }
  }, [activeTab, defaultType]);

  const fetchRetenusCandidates = useCallback(
    async (candidateType?: CandidateType) => {
      await fetchCandidatesByStatus('RETAINED', candidateType, currentPage, pageSize);
    },
    [currentPage, pageSize, fetchCandidatesByStatus]
  );

  const fetchDataWithFilters = useCallback(() => {
    const candidateType: CandidateType =
      defaultType === 'Candidature chauffeur' ? 'DRIVER' : 'SEDENTARY';

    if (filtersApplied && Object.keys(filters).length > 0) {
      const backendFilters = mapFiltersToBackend(filters);

      switch (activeTab) {
        case CandidatureTab.ATraiter:
          backendFilters.status = 'TO_PROCESS';
          break;
        case CandidatureTab.Retenus:
          break;
        case CandidatureTab.AbsentRdv:
          backendFilters.status = 'ABSENT';
          break;
        case CandidatureTab.Tableau:
          backendFilters.status = 'VALIDATED';
          break;
      }

      if (candidateType) {
        backendFilters.type = candidateType;
      }

      searchCandidatesAdvanced(backendFilters);
    } else {
      switch (activeTab) {
        case CandidatureTab.ATraiter:
          fetchCandidatesByStatus('TO_PROCESS', candidateType);
          break;
        case CandidatureTab.Retenus:
          fetchRetenusCandidates(candidateType);
          break;
        case CandidatureTab.RdvSemaine:
          fetchRdvSemaineCandidates(candidateType);
          break;
        case CandidatureTab.AbsentRdv:
          fetchAbsentCandidates(candidateType);
          break;
        case CandidatureTab.Tableau:
          fetchCandidatesByStatus('VALIDATED', candidateType);
          break;
        case CandidatureTab.RefusesBlacklistes:
          fetchRefusedAndBlacklistedCandidates(candidateType);
          break;
        case CandidatureTab.Tous:
          fetchCandidatesByType(candidateType);
          break;
        default:
          break;
      }
    }
  }, [
    activeTab,
    defaultType,
    filters,
    filtersApplied,
    fetchCandidatesByStatus,
    fetchRdvSemaineCandidates,
    fetchAbsentCandidates,
    fetchRefusedAndBlacklistedCandidates,
    fetchCandidates,
    searchCandidatesAdvanced,
    fetchRetenusCandidates,
  ]);

  useEffect(() => {
    fetchDataWithFilters();
  }, [fetchDataWithFilters]);

  const filteredData = useMemo(() => {
    let mappedCandidates = candidates.map((candidate, index) => {
      const frontendData = convertBackendToFrontend(candidate);
      return {
        ...frontendData,
        id: (index + 1).toString(),
        rowNumber: index + 1,
        originalId: candidate.id,
      };
    });

    if (activeTab === CandidatureTab.Retenus) {
      const today = new Date();
      today.setHours(0, 0, 0, 0);

      mappedCandidates = mappedCandidates.filter((candidate) => {
        if (!candidate.dateHeureRdvAgence) return true;

        const rdvDate = new Date(candidate.dateHeureRdvAgence);
        rdvDate.setHours(0, 0, 0, 0);
        return rdvDate >= today;
      });
    }

    if (activeTab === CandidatureTab.AbsentRdv) {
      const today = new Date();
      today.setHours(0, 0, 0, 0);

      const retainedCandidates = candidates.filter((candidate) => candidate.status === 'RETAINED');

      const retainedWithOldRdv = retainedCandidates.filter((candidate) => {
        if (!candidate.agencyAppointmentDateTime) return false;
        const rdvDate = new Date(candidate.agencyAppointmentDateTime);
        rdvDate.setHours(0, 0, 0, 0);
        return rdvDate < today;
      });

      const oldRdvCandidates = retainedWithOldRdv.map((candidate, index) => {
        const frontendData = convertBackendToFrontend(candidate);
        return {
          ...frontendData,
          id: `old-${index + 1}`,
          rowNumber: index + 1,
          originalId: candidate.id,
        };
      });

      mappedCandidates = [...mappedCandidates, ...oldRdvCandidates];
    }

    return mappedCandidates;
  }, [candidates, activeTab]);

  const getOriginalIdFromDisplayId = useCallback(
    (displayId: string): string | null => {
      const candidate = filteredData.find((c) => c.id === displayId);
      if (!candidate) {
        return null;
      }
      const originalId = candidate.originalId;
      return originalId || null;
    },
    [filteredData]
  );

  const refreshCurrentView = useCallback(() => {
    fetchDataWithFilters();
  }, [fetchDataWithFilters]);

  const getAddressValue = useCallback((address: any): string => {
    if (typeof address === 'object' && address?.address) {
      return address.address;
    }
    return address || '';
  }, []);

  const getCandidateType = useCallback((defaultType: string): 'DRIVER' | 'SEDENTARY' => {
    return defaultType === 'Candidature chauffeur' ? 'DRIVER' : 'SEDENTARY';
  }, []);

  const getSourceCandidat = useCallback((sourceCandidat: string): SourceCandidat => {
    const source = sourceCandidat?.toLowerCase();

    if (source === 'indeed') return 'INDEED';
    if (source === 'linkedin') return 'LINKEDIN';
    if (source === 'pôle emploi') return 'POLE_EMPLOI';

    return 'AUTRE';
  }, []);

  const getLicenseDurationForUpdate = useCallback(
    (dureePermis: string | number | undefined): string | undefined => {
      if (!dureePermis) return undefined;
      return typeof dureePermis === 'string' ? dureePermis : String(dureePermis);
    },
    []
  );

  const getLicenseDurationForCreate = useCallback(
    (dureePermis: string | number | undefined, candidateType: string): number | undefined => {
      if (candidateType === 'DRIVER') {
        if (!dureePermis || dureePermis === '') {
          throw new Error('La durée de permis est obligatoire pour les chauffeurs');
        }
        const parsed = typeof dureePermis === 'string' ? parseInt(dureePermis) : dureePermis;
        if (isNaN(parsed)) {
          throw new Error('La durée de permis doit être un nombre valide');
        }
        return parsed;
      }
      return undefined;
    },
    []
  );

  const getApplicationDate = useCallback((dateCandidature?: string): string => {
    return dateCandidature || new Date().toISOString().split('T')[0];
  }, []);

  const handleSave = useCallback(
    async (candidatureData: ICandidature) => {
      try {
        const candidateId = candidatureData.originalId || candidatureData.id;

        if (candidateId) {
          const backendData: Partial<CandidateDTO> = {};
          backendData.type = getCandidateType(defaultType || '');
          backendData.firstName = candidatureData.prenom || 'Unknown';
          backendData.lastName = candidatureData.nom || 'Unknown';
          backendData.email = candidatureData.email || 'unknown@example.com';
          backendData.phone = candidatureData.telephone || '0000000000';
          backendData.age = candidatureData.age || 25;
          backendData.postalCode = candidatureData.codePostal || '00000';
          backendData.city = candidatureData.ville || 'Unknown';
          backendData.department = candidatureData.departement || '00';
          if (candidatureData.address || candidatureData.ville || candidatureData.codePostal) {
            backendData.address = {
              street: getAddressValue(candidatureData.address) || '',
              city: candidatureData.address?.city || candidatureData.ville || undefined,
              zipCode: candidatureData.address?.postalCode || candidatureData.codePostal || undefined,
              country: candidatureData.address?.country || undefined,
              latitude: candidatureData.address?.lat || 0,
              longitude: candidatureData.address?.lng || 0,
            } as any;
          }
          if (candidatureData.statut) {
            backendData.status = statusMapping[candidatureData.statut] || 'TO_PROCESS';
          }
          if (candidatureData.sourceCandidat) {
            backendData.sourceCandidate = getSourceCandidat(candidatureData.sourceCandidat);
          }
          if (candidatureData.email_pro) {
            backendData.professionalEmail = candidatureData.email_pro;
          }
          if (candidatureData.dureePermis)
            backendData.drivingLicenseDuration = getLicenseDurationForUpdate(
              candidatureData.dureePermis
            );
          if (candidatureData.proximiteCircuit)
            backendData.circuitProximity = candidatureData.proximiteCircuit;
          if (candidatureData.disponibilite)
            backendData.availability = candidatureData.disponibilite;
          if (candidatureData.suiviAppel) backendData.callFollowUp = candidatureData.suiviAppel;
          if (candidatureData.dateAppelRappel)
            backendData.callBackDate = candidatureData.dateAppelRappel;
          if (candidatureData.dateHeureRdvAgence) {
            const raw = candidatureData.dateHeureRdvAgence;
            const onlyDatePattern = /^\d{4}-\d{2}-\d{2}$/;
            const dateTimeNoSecondsPattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/;
            const dateTimeWithSecondsPattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/;

            if (onlyDatePattern.test(raw)) {
              backendData.agencyAppointmentDateTime = `${raw}T09:00:00`;
            } else if (dateTimeNoSecondsPattern.test(raw)) {
              backendData.agencyAppointmentDateTime = `${raw}:00`;
            } else if (dateTimeWithSecondsPattern.test(raw)) {
              backendData.agencyAppointmentDateTime = raw;
            } else {
              const rdvDate = new Date(raw);
              if (!isNaN(rdvDate.getTime())) {
                const pad = (n: number) => (n < 10 ? `0${n}` : `${n}`);
                const y = rdvDate.getFullYear();
                const m = pad(rdvDate.getMonth() + 1);
                const d = pad(rdvDate.getDate());
                let hh = pad(rdvDate.getHours());
                let mm = pad(rdvDate.getMinutes());
                const ss = pad(rdvDate.getSeconds());

                if (hh === '00' && mm === '00') {
                  hh = '09';
                  mm = '00';
                }

                backendData.agencyAppointmentDateTime = `${y}-${m}-${d}T${hh}:${mm}:${ss}`;
              }
            }
          }
          if (candidatureData.raisonRefus) backendData.refusalReason = candidatureData.raisonRefus;
          if (candidatureData.document) {
            backendData.document =
              typeof candidatureData.document === 'string' ? candidatureData.document : '';
          }
          if (candidatureData.contrat_document) {
            backendData.contractDocument =
              typeof candidatureData.contrat_document === 'string'
                ? candidatureData.contrat_document
                : (candidatureData.contrat_document as any)?.name || '';
          }
          if (candidatureData.contrat) {
            const contractStatusMapping: Record<string, string> = {
              signé: 'SIGNED',
              'non signé': 'NOT_SIGNED',
              'en cours': 'IN_PROGRESS',
            };
            backendData.contractStatus =
              contractStatusMapping[candidatureData.contrat] || 'NOT_SIGNED';
          }
          if (candidatureData.dateCandidature) {
            const date = new Date(candidatureData.dateCandidature);
            if (!isNaN(date.getTime())) {
              backendData.applicationDate = date.toISOString().split('T')[0];
            }
          }

          await updateCandidate(candidateId, backendData);

          if (candidatureData.dateHeureRdvAgence && backendData.agencyAppointmentDateTime) {
            try {
              await candidatesApi.scheduleRdv(
                candidateId.toString(),
                backendData.agencyAppointmentDateTime
              );
              enqueueSnackbar('RDV planifié avec succès !', { variant: 'success' });
            } catch (rdvError) {
              console.error('Erreur lors de la planification du RDV:', rdvError);
              enqueueSnackbar('Erreur lors de la planification du RDV', { variant: 'warning' });
            }
          }

          await refreshCurrentView();
        } else {
          const candidateType = getCandidateType(defaultType || '');
          const backendData = {
            firstName: candidatureData.prenom,
            lastName: candidatureData.nom,
            email: candidatureData.email,
            phone: candidatureData.telephone,
            age: candidatureData.age,
            address: {
              street: getAddressValue(candidatureData.address) || '',
              city: candidatureData.address?.city || candidatureData.ville || undefined,
              zipCode: candidatureData.address?.postalCode || candidatureData.codePostal || undefined,
              country: candidatureData.address?.country || undefined,
              latitude: candidatureData.address?.lat || 0,
              longitude: candidatureData.address?.lng || 0,
            },
            postalCode: candidatureData.codePostal,
            city: candidatureData.ville,
            department: candidatureData.departement,
            type: candidateType,
            sourceCandidat: getSourceCandidat(candidatureData.sourceCandidat),
            licenseDuration: getLicenseDurationForCreate(
              candidatureData.dureePermis,
              candidateType
            ),
            circuitProximity: candidatureData.proximiteCircuit,
            availability: candidatureData.disponibilite,
            applicationDate: getApplicationDate(candidatureData.dateCandidature),
            callFollow: candidatureData.suiviAppel,
            callOrCallbackDate: candidatureData.dateAppelRappel,
          };

          try {
            await createCandidate(backendData as any);

            try {
              await refreshCurrentView();
            } catch (refreshError) {}
          } catch (creationError) {
            throw creationError;
          }
        }
      } catch (error) {
        throw error;
      }
    },
    [
      createCandidate,
      updateCandidate,
      defaultType,
      refreshCurrentView,
      getAddressValue,
      getCandidateType,
      getSourceCandidat,
      getLicenseDurationForUpdate,
      getLicenseDurationForCreate,
      getApplicationDate,
    ]
  );

  const handleStatusChange = useCallback(
    async (row: ICandidature, newStatus: string, field: keyof ICandidature, reason?: string) => {
      const candidateId = row.originalId || row.id;

      if (field === 'statut') {
        const backendStatus = statusMapping[newStatus];
        if (backendStatus) {
          if (backendStatus === 'ABSENT') {
            await markAsAbsent(candidateId);
            await refreshCurrentView();
          } else {
            await updateCandidateStatus(candidateId, backendStatus, reason);
            await refreshCurrentView();
          }

          if (backendStatus === 'RETAINED' && onMainTabChange) {
            enqueueSnackbar(
              'Candidat marqué comme retenu. Redirection vers la liste des retenus...',
              {
                variant: 'success',
                autoHideDuration: 2000,
              }
            );
            setTimeout(() => {
              onMainTabChange(CandidatureTab.Retenus);
            }, 1000);
          }
        }
      } else if (field === 'contrat') {
        const backendData: Partial<CandidateDTO> = {
          contractDocument: newStatus,
        };
        await updateCandidate(candidateId, backendData);
        await refreshCurrentView();
      }
    },
    [updateCandidateStatus, updateCandidate, refreshCurrentView]
  );

  const handleCreateRdvSemaine = useCallback(
    async (candidature: ICandidature) => {
      try {
        const candidateId = candidature.originalId || candidature.id;
        const today = new Date();
        const daysUntilNextMonday = (8 - today.getDay()) % 7 || 7;
        const rdvDate = new Date(today);
        rdvDate.setDate(today.getDate() + daysUntilNextMonday);
        rdvDate.setHours(9, 0, 0, 0);

        await scheduleRdv(candidateId, rdvDate.toISOString());

        await refreshCurrentView();

        return {
          ...candidature,
          dateHeureRdvAgence: rdvDate.toISOString(),
        };
      } catch (error) {
        throw error;
      }
    },
    [scheduleRdv, refreshCurrentView]
  );

  const handleSendEmail = useCallback(
    async (candidateId: string, subject: string, message: string) => {
      const originalId = getOriginalIdFromDisplayId(candidateId);

      if (!originalId) {
        throw new Error("UUID original non trouvé pour l'ID d'affichage");
      }

      try {
        await sendEmailToCandidate({
          candidateId: originalId,
          subject,
          message,
        });
        refreshCurrentView();
      } catch (error) {
        throw error;
      }
    },
    [sendEmailToCandidate, getOriginalIdFromDisplayId, refreshCurrentView]
  );

  const handleSendForm = useCallback(
    async (candidateId: string, formId: string, observation?: string) => {
      const originalId = getOriginalIdFromDisplayId(candidateId);

      if (!originalId) {
        throw new Error("UUID original non trouvé pour l'ID d'affichage");
      }

      try {
        await sendFormToCandidate({
          candidateId: originalId,
          formId,
          observation,
        });
        refreshCurrentView();
      } catch (error) {
        throw error;
      }
    },
    [sendFormToCandidate, getOriginalIdFromDisplayId, refreshCurrentView]
  );

  const handleScheduleRdv = useCallback(
    async (candidateId: string, rdvDateTime: string) => {
      const originalId = getOriginalIdFromDisplayId(candidateId);

      if (!originalId) {
        throw new Error("UUID original non trouvé pour l'ID d'affichage");
      }

      try {
        await scheduleRdv(originalId, rdvDateTime);
        refreshCurrentView();
      } catch (error) {
        throw error;
      }
    },
    [scheduleRdv, refreshCurrentView, getOriginalIdFromDisplayId]
  );

  const handleMarkAsAbsent = useCallback(
    async (candidateId: string) => {
      const originalId = getOriginalIdFromDisplayId(candidateId);
      if (!originalId) {
        throw new Error("UUID original non trouvé pour l'ID d'affichage");
      }

      await markAsAbsent(originalId);
      refreshCurrentView();
    },
    [markAsAbsent, refreshCurrentView, getOriginalIdFromDisplayId]
  );

  const handleReplanifyRdv = useCallback(
    async (candidateId: string, rdvDateTime: string) => {
      const originalId = getOriginalIdFromDisplayId(candidateId);
      if (!originalId) {
        throw new Error("UUID original non trouvé pour l'ID d'affichage");
      }

      await replanifyRdv(originalId, rdvDateTime);
      await refreshCurrentView();
    },
    [replanifyRdv, refreshCurrentView, getOriginalIdFromDisplayId]
  );

  const handleFilterChange = useCallback((key: string, value: string, condition: string) => {
    setFilters((prev) => {
      const newFilters = { ...prev };
      if (value.trim() === '') {
        delete newFilters[key];
      } else {
        newFilters[key] = { value, condition };
      }

      return newFilters;
    });
    setFiltersApplied(true);
  }, []);

  const handleResetFilters = useCallback(() => {
    setFilters({});
    setFiltersApplied(false);
  }, []);

  const mockTable = {
    dense: false,
    selected: [],
    onSelectRow: () => {},
    onSelectAllRows: () => {},
    onResetPage: () => setPage(0),
    page: currentPage,
    rowsPerPage: pageSize,
    totalRows: totalElements,
    orderBy: 'nom',
    order: 'asc' as const,
    onSort: () => {},
    onChangePage: () => {},
    onChangeRowsPerPage: () => {},
    onChangeDense: () => {},
  };

  return {
    table: mockTable,
    filteredData,
    tableHead: getTableHead,
    notFound: !loading && filteredData.length === 0,
    filters,
    handleFilterChange,
    handleResetFilters,
    handleResetColumns: () => {},
    handleColumnsChange: () => {},
    dataToExport: filteredData,
    handleSave,
    handleStatusChange,
    handleCreateRdvSemaine,
    handleSendEmail,
    handleSendForm,
    handleScheduleRdv,
    handleMarkAsAbsent,
    handleReplanifyRdv,
    loading,
    creating,
    updating,
    sendingEmail,
    sendingForm,
    totalElements,
    totalPages,
    currentPage,
    pageSize,
  };
}
