"use client"
import { useEffect, useState, useCallback, useMemo } from "react"
import React from "react"
import { Box, Grid, Button, Typography, IconButton, Tooltip } from "@mui/material"
import { Departements } from "@/shared/types/etablissement"
import ActionButtons from "@/shared/components/form/buttons-action"
import AttendanceSheetCher from "../components/attendance-sheet-cher"
import AttendanceSheetNotCher from "../components/attendance-sheet-not-cher"
import ExportModal from "./export-modal"
import FontAwesome from "@/shared/components/fontawesome"
import { faFileExport, faPenToSquare } from "@fortawesome/free-solid-svg-icons"
import type { ModeType } from "@/shared/types/common"
import MultiSectionContainer from "@/shared/components/form/multiForm-container"
import ConditionalComponent from "@/shared/components/table/ConditionalComponent"
import {
  AttendanceSheet,
  AttendanceSheetWithRouteSheets,
  BatchUpdatePayload,
  IAttendanceNotCher,
  IAttendanceSheetCher,
  MonthsString,
  RouteSheetDTO
} from "@/shared/types/attendance-sheet"
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'
import { fr } from 'date-fns/locale'
import { useAttendanceSheetStore } from "@/shared/api/stores/attendanceSheetStore"
import { useSnackbar } from 'notistack'
import { ConcernedTrip } from "@/shared/types/absence"
import EditExportButtons from "@/shared/components/form/edit-export-buttons"

interface AttendanceUpdatePayload {
  id: number;
  passengerId: number;
  date: string;
  isAbsent: boolean;
}

interface PendingChange {
  passengerId: number;
  date: string;
  concernedTrips: ConcernedTrip[];
}

type TabData = IAttendanceNotCher | IAttendanceSheetCher

interface SheetTab {
  id: number;
  data: TabData;
  isReadOnly?: boolean;
}

interface AttendanceSheetParentProps {
  onReturn: () => void;
  mode?: ModeType;
  vacation?: AttendanceSheetWithRouteSheets;
  initialDepartement?: string;
  onClose: (isSaved: boolean) => void;
  attendance: Record<string, Record<string, boolean>> | Record<number, Record<string, Record<string, boolean>>>;
  updateTabAttendance: (tabId: string, attendance: Record<string, Record<string, boolean>> | Record<number, Record<string, Record<string, boolean>>>) => void;
  tabId: string;
  onEdit?: () => void;
  showEditButton?: boolean;
}

function MultiSectionForm({
  onReturn,
  mode = "edit",
  vacation,
  initialDepartement = Departements.Cher,
  onClose,
  attendance,
  updateTabAttendance,
  tabId,
  onEdit,
  showEditButton = false,
}: AttendanceSheetParentProps) {
  const { enqueueSnackbar } = useSnackbar();
  const [tabs, setTabs] = useState<SheetTab[]>([]);
  const [exportModalOpen, setExportModalOpen] = useState(false);
  const [pendingChanges, setPendingChanges] = useState<PendingChange[]>([]);
  const [isSaving, setIsSaving] = useState(false);

  const { updateAttendanceStatusBatch,exportAttendanceSheetPdf} = useAttendanceSheetStore();

  const monthNumberToName = useCallback((month: number): string => {
    return Object.values(MonthsString)[month - 1] || "";
  }, []);

  useEffect(() => {
    if (vacation?.routeSheets && Array.isArray(vacation.routeSheets) && vacation.routeSheets.length > 0) {
      const initialTabs = vacation.routeSheets.map((sheet: RouteSheetDTO, idx: number) => ({
        id: idx,
        data: {
          departement: sheet.departmentName,
          month: monthNumberToName(sheet.month),
          year: String(sheet.year),
          circuit: sheet.circuitName,
          etablissement: sheet.establishment?.establishmentName || "",
          driver: sheet.driver ? `${sheet.driver.firstName} ${sheet.driver.lastName}` : "Non assigné",
          establishment: sheet.establishment || null,
          adresse: sheet.establishment?.address ?
            `${sheet.establishment.address.street}, ${sheet.establishment.address.zipCode} ${sheet.establishment.address.city}` : "",
          telephone: sheet.establishment?.fax || "",
          passengers: sheet.passengers,
          nomResponsable: sheet.establishment?.establishmentManager
            ? `${sheet.establishment.establishmentManager.firstName} ${sheet.establishment.establishmentManager.lastName}`
            : "",
          calendar: {
            ...sheet.calendar,
            days: sheet.calendar?.days?.map(day => {
              return {
                ...day,
                passengerStatuses: day.passengerStatuses || {}
              };
            }) || []
          },
        },
      }));

      setTabs(initialTabs);
    }
  }, [vacation?.routeSheets, monthNumberToName]);

 const handleAttendanceUpdate = useCallback(async (
    passengerId: number,
    date: string,
    isAbsent: boolean,
    tripType?: 'A' | 'R' 
  ): Promise<void> => {
    let concernedTrips: ConcernedTrip[] = [];
    if (isAbsent && tripType) {
      if (tripType === 'A') {
        concernedTrips = [ConcernedTrip.Outbound];
      } else if (tripType === 'R') {
        concernedTrips = [ConcernedTrip.Return];
      }
    }
    setPendingChanges(prev => {
      const existingIndex = prev.findIndex(
        change => change.passengerId === passengerId && change.date === date
      );

      const newChange = { passengerId, date, concernedTrips };

      if (existingIndex !== -1) {
        const newChanges = [...prev];
        newChanges[existingIndex] = newChange;
        return newChanges;
      }

      return [...prev, newChange];
    });
    return Promise.resolve();
  }, []);


  const handleSaveAll = useCallback(async () => {
    try {
      setIsSaving(true);

      if (pendingChanges.length === 0) {
        enqueueSnackbar('Aucun changement à enregistrer', { variant: 'info' });
        return;
      }

      const convertMonthToNumber = (monthStr: string): string => {
        const months: { [key: string]: string } = {
          'Janvier': '01', 'Fevrier': '02', 'Mars': '03', 'Avril': '04',
          'Mai': '05', 'Juin': '06', 'Juillet': '07', 'Aout': '08',
          'Septembre': '09', 'Octobre': '10', 'Novembre': '11', 'Decembre': '12'
        };
        return months[monthStr] || monthStr;
      };

      const changes = pendingChanges.map(change => {
        const [year, month, day] = change.date.split('-');
        const formattedDate = `${year}-${convertMonthToNumber(month)}-${day.padStart(2, '0')}`;

        return {
          passengerId: change.passengerId,
          date: formattedDate,
          concernedTrips: change.concernedTrips
        };
      });

      const payload = {
        attendanceSheetId: Number(vacation?.id) || 5,
        changes: changes
      };

      await updateAttendanceStatusBatch(payload);

      setPendingChanges([]);
      enqueueSnackbar('Les modifications ont été enregistrées avec succès', {
        variant: 'success'
      });
      onClose(true);
    } catch (error) {
      console.error('6. Erreur lors de la sauvegarde:', error);
      enqueueSnackbar('Erreur lors de la sauvegarde des modifications', {
        variant: 'error'
      });
    } finally {
      setIsSaving(false);
    }
  }, [pendingChanges, vacation?.id, updateAttendanceStatusBatch, enqueueSnackbar, onClose]);

  const handleFormChange = useCallback((tabId: number, newData: TabData) => {
    setTabs((prevTabs) => prevTabs.map((tab) => (
      tab.id === tabId ? { ...tab, data: newData } : tab
    )));
  }, []);

  const handleAttendanceChangeNotCher = useCallback(
    (newAttendance: Record<string, Record<string, boolean>>) => {
      updateTabAttendance(tabId, newAttendance);
    },
    [updateTabAttendance, tabId],
  );

  const handleAttendanceChangeCher = useCallback(
    (newAttendance: Record<number, Record<string, Record<string, boolean>>>) => {
      updateTabAttendance(tabId, newAttendance);
    },
    [updateTabAttendance, tabId],
  );

  const handleCancelChanges = useCallback(() => {
    if (pendingChanges.length > 0 && mode !== 'view') {
      if (window.confirm('Voulez-vous vraiment annuler toutes les modifications ?')) {
        setPendingChanges([]);
        onClose(false);
      }
    } else {
      onClose(false);
    }
  }, [pendingChanges.length, onClose, mode]);

  const exportSheets = useMemo(
    () => tabs.map((tab) => ({
      id: `Feuille-${tab.id}`,
      name: `Feuille ${tab.id + 1} - ${"etablissement" in tab.data ? tab.data.etablissement : ""} (${"mois" in tab.data && "annee" in tab.data ? `${tab.data.mois}/${tab.data.annee}` : ""
        })`,
    })),
    [tabs],
  );
const handleExportPdf = useCallback(async () => {
  try {
    if (!vacation?.id || !vacation.routeSheets?.[0]) {
      enqueueSnackbar('Données manquantes pour l\'export', { variant: 'error' });
      return;
    }

    const sheet = vacation.routeSheets[0];
    await exportAttendanceSheetPdf(
      Number(vacation.id),
      sheet.month,
      sheet.year
    );
    
    enqueueSnackbar('Export PDF généré avec succès', { variant: 'success' });
  } catch (error) {
    console.error('Erreur lors de l\'export PDF:', error);
    enqueueSnackbar('Erreur lors de l\'export PDF', { variant: 'error' });
  }
}, [vacation, exportAttendanceSheetPdf]);
 const exportButton = useMemo(
  () => (
    <Button
      variant="outlined"
      onClick={handleExportPdf}
      endIcon={<FontAwesome icon={faFileExport} width={18} />}
      sx={{
        textTransform: "none",
        color: "text.secondary",
        borderColor: "divider",
        "&:hover": {
          borderColor: "primary.main",
          color: "primary.main",
        },
      }}
    >
      Exporter PDF
    </Button>
  ),
  [handleExportPdf],
);

  if (!tabs.length) {
    return (
      <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '200px' }}>
        <Typography>Aucune donnée disponible</Typography>
      </Box>
    );
  }

  return (
    <LocalizationProvider dateAdapter={AdapterDateFns} adapterLocale={fr}>
      <Box sx={{ p: 2, bgcolor: "white" }}>
        <ConditionalComponent
          isValid={showEditButton && mode === 'view'}
          defaultComponent={null}
        >
          <Box sx={{ mb: 2 }}>
            <EditExportButtons
              onEdit={onEdit}
              tooltipTitle="Feuille de présence"

              tableHead={[]}
            />
          </Box>
        </ConditionalComponent>

        <Grid container spacing={4}>
          <ConditionalComponent
            isValid={initialDepartement === 'cher'}
            defaultComponent={
              <AttendanceSheetNotCher
                tabs={tabs as { id: number; data: IAttendanceNotCher; isReadOnly?: boolean }[]}
                tab={tabs[0] as { id: number; data: IAttendanceNotCher; isReadOnly?: boolean }}
                mode={mode}
                handleFormChange={handleFormChange}
                attendance={attendance as Record<string, Record<string, boolean>>}
                onAttendanceChange={handleAttendanceChangeNotCher}
                onAttendanceUpdate={handleAttendanceUpdate}
              />
            }
          >
            <>
              {tabs.map((tab) => (
                <MultiSectionContainer key={tab.id} id={tab.id} title="Feuille">
                  <AttendanceSheetCher
                    tabs={tabs as { id: number; data: IAttendanceSheetCher; isReadOnly?: boolean }[]}
                    tab={tab as { id: number; data: IAttendanceSheetCher; isReadOnly?: boolean }}
                    mode={mode}
                    handleFormChange={handleFormChange}
                    attendance={attendance as Record<number, Record<string, Record<string, boolean>>>}
                    onAttendanceChange={handleAttendanceChangeCher}
                    onAttendanceUpdate={handleAttendanceUpdate}
                  />
                </MultiSectionContainer>
              ))}
            </>
          </ConditionalComponent>
        </Grid>

        <ConditionalComponent
          isValid={pendingChanges.length > 0 && mode !== 'view'}
          defaultComponent={null}
        >
          <Typography
            color="warning.main"
            sx={{
              mt: 2,
              mb: 2,
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center'
            }}
          >
            {pendingChanges.length} modification(s) en attente de sauvegarde
          </Typography>
        </ConditionalComponent>

        <Grid item xs={12} sx={{ mt: 3 }}>
          <ActionButtons
            onSave={mode === 'view' ? () => onClose(false) : handleSaveAll}
            onCancel={handleCancelChanges}
            mode={mode}
            onValidate={mode === 'view' ? undefined : handleSaveAll}
            thirdButtonText={mode === 'view' ? undefined : "Enregistrer Tout"}
            secoundButtonText={mode === 'view' ? "Fermer" : mode === 'edit' ? "Annuler les modifications" : "Retourner"}
            loading={isSaving}
            additionalButton={mode === 'view' ? exportButton : undefined}
          />
        </Grid>

        <ExportModal
          open={exportModalOpen}
          onClose={() => setExportModalOpen(false)}
          onExport={() => void 0}
          sheets={exportSheets}
        />
      </Box>
    </LocalizationProvider>
  );
}

export default React.memo(MultiSectionForm);