'use client';

import React, { useEffect, useMemo, useCallback, useState } from 'react';
import {
  Grid,
  Autocomplete,
  Box,
} from '@mui/material';
import { _CONTRACT_STATUS } from '../../../_mock/_Contrat';
import {
  centerFlexColumn,
  StyledTextField,
} from '@/shared/theme/css';
import FormField from '@/shared/components/form/form-field';
import { FormFieldType, ModeType, TableColumn, TableType } from '@/shared/types/common';
import { IAbsence } from '@/shared/types/absence';
import FormContainer from '@/layouts/form/form-container';
import { useFormFieldsAbsence } from '../utils/form-fields-absence';
import { _OPTION_DEMANDE } from '@/shared/sections/absence/utils/form-fields-absence';
import ActionButtons from '@/shared/components/form/buttons-action';
import EditExportButtons from '@/shared/components/form/edit-export-buttons';
import { useFormik } from 'formik';
import { absenceValidationSchema } from '../utils/absence-validation-schema';
import ConditionalComponent from '@/shared/components/table/ConditionalComponent';
import { useAbsenceStore } from '@/shared/api/stores/absenceStore';
import { usePassengerStore } from '@/shared/api/stores/passengerStore';
import { useCollaboratorStore } from '@/shared/api/stores/CollaboratorStore';
import { mapFrontToBackState } from '@/shared/types/absence';
import { useResponsive } from '@/hooks';
import { useTheme } from '@mui/material/styles';
import { faClose } from '@fortawesome/free-solid-svg-icons';
import FontAwesome from '@/shared/components/fontawesome';
import { Paper } from '@mui/material';
import { enqueueSnackbar } from 'notistack';
import { PassengerNameDTO } from '@/shared/types/passenger';

interface AbsenceFormProps {
  absence: IAbsence;
  mode: ModeType;
  onSave: (updatedAbsence: IAbsence) => void;
  onEdit: (updatedAbsenger: IAbsence) => void;
  onClose: (isSaved: boolean) => void;
  isTraiteAbsence?:boolean;
  tableHead: TableColumn[];
  updateTabContent?: (tabId: string, newContent: IAbsence) => void
  tabId?: string
}

export default function AbsenceForm({
  absence,
  mode,
  onSave,
  onClose,
  onEdit,
  isTraiteAbsence,
  tableHead,
  updateTabContent,
  tabId,
}: AbsenceFormProps) {
  const { updateAbsence, createAbsence, getAbsenceById } = useAbsenceStore();
  const { passengers, searchPassengerNames, loading: passengersLoading } = usePassengerStore();
  const { getCollaboratorsByDepartment, loading: collaboratorsLoading } = useCollaboratorStore();
  const isBetweenSmAndLg = useResponsive('between', 'sm', 'lg');
  const theme = useTheme();
  const isSmallScreen = isBetweenSmAndLg;
  
  const [collaborators, setCollaborators] = useState<Array<{ id: number; firstName: string; lastName: string }>>([]);
  const [passengerNames, setPassengerNames] = useState<Array<PassengerNameDTO>>([]);
  const [isDataLoaded, setIsDataLoaded] = useState(false);

  useEffect(() => {
    const loadAbsenceData = async () => {
      try {
        const initialPassengers = await searchPassengerNames('');
        setPassengerNames(initialPassengers);
      } catch (error) {
        console.error('❌ Error loading passengers:', error);
      }

      if ((mode === 'edit' || mode === 'view') && absence.id) {
        try {
          const backendData = await getAbsenceById(absence.id) as any;
          if (backendData?.passenger) {
            const passengerFromBackend: PassengerNameDTO = {
              id: backendData.passenger.id,
              firstName: backendData.passenger.firstName,
              lastName: backendData.passenger.lastName,
              departmentId: backendData.passenger.departmentId || undefined
            };

            setPassengerNames(prev => {
              const exists = prev.some(p => p.id === passengerFromBackend.id);
              if (!exists) {
                return [passengerFromBackend, ...prev];
              }
              return prev;
            });

            if (backendData.passenger.departmentId) {
              try {
                const departmentCollaborators = await getCollaboratorsByDepartment(backendData.passenger.departmentId);
                setCollaborators(departmentCollaborators);
              } catch (error) {
                console.error('❌ Error loading collaborators:', error);
              }
            }

            const transformedData = {
              id: backendData.id.toString(),
              usager: {
                id: backendData.passenger.id,
                value: backendData.passenger.id.toString(),
                label: `${backendData.passenger.firstName} ${backendData.passenger.lastName}`,
                firstName: backendData.passenger.firstName,
                lastName: backendData.passenger.lastName,
                establishmentName: backendData.passenger.establishmentName || '',
                departmentName: backendData.passenger.departmentName || ''
              },
              etat: mapBackendStateToFrontend(backendData.state),
              etablissement: backendData.passenger.establishmentName || '',
              dateDebut: new Date(backendData.startDate),
              dateFin: new Date(backendData.endDate),
              sensAR: backendData.concernedTrip.map((trip: string) => 
                trip === 'Outbound' ? 'aller' : 'retour'
              ),
              observation: backendData.observations || '',
              modeReception: backendData.receivingMethod || '',
              previentLe: backendData.forecastDate || '',
              departement: backendData.passenger.departmentName || '',
              comment: backendData.comment || '',
              par: backendData.reportedBy || ''
            };

            formik.resetForm({ values: transformedData as IAbsence });
            
          
          }
        } catch (error) {
          console.error('❌ ERROR:', error);
        }
      }
    };
    
    loadAbsenceData();
  }, [mode, absence.id]);

  const mapBackendStateToFrontend = (backendState: string): string => {
    switch (backendState) {
      case 'Processed':
        return 'Traité';
      case 'In_progress':
        return 'En cours';
      case 'Unprocessed':
        return 'Non traité';
      case 'Cancelled':
        return 'Annulé';
      default:
        return 'Non traité';
    }
  };

  const isReadOnly = mode === 'view';
  const isCreating = mode === 'add';
  
  const handlePassengerSelect = async (selectedValue: string | number) => {
    if (!selectedValue) {
      formik.setFieldValue('usager', null);
      formik.setFieldValue('etablissement', '');
      formik.setFieldValue('departement', '');
      formik.setFieldValue('par', ''); 
      setCollaborators([]); 
      formik.setFieldTouched('usager', true, false);
      formik.validateField('usager');
      return;
    }
    

    const selectedPassenger = passengerNames.find(p => p.id.toString() === selectedValue.toString());    
    if (selectedPassenger) {
      const usagerObject = {
        id: selectedPassenger.id,
        firstName: selectedPassenger.firstName,
        lastName: selectedPassenger.lastName,
        establishmentName: '', 
        departmentName: ''
      };      
      formik.setFieldValue('usager', usagerObject);
      formik.setFieldValue('etablissement', '');
      formik.setFieldValue('departement', '');
      
      if (selectedPassenger.departmentId) {
        try {
          const departmentCollaborators = await getCollaboratorsByDepartment(selectedPassenger.departmentId);
          setCollaborators(departmentCollaborators);
        } catch (error) {
          console.error('Error fetching collaborators by department:', error);
          setCollaborators([]);
        }
      } else {
        setCollaborators([]);
      }
    }
  };

  const handlePassengerSearch = async (searchTerm: string) => {
    try {

      const names = await searchPassengerNames(searchTerm || undefined);
      setPassengerNames(names);
    } catch (error) {
      console.error('Error searching passenger names:', error);
      setPassengerNames([]);
    }
  };

  const formik = useFormik<IAbsence>({
    initialValues: {
      ...absence,
      usager: absence.usager || {
        id: '',
        establishmentName: '',
        departmentName: '',
        firstName: '',
        lastName: ''
      },
      etat: Array.isArray(absence.etat) ? absence.etat[0] : absence.etat,
      sensAR: Array.isArray(absence.sensAR) ? absence.sensAR : [absence.sensAR],
    },
    enableReinitialize: true,
    validationSchema: absenceValidationSchema,
    validateOnChange: true,
    validateOnBlur: true,
    onSubmit: async (values) => {
      const errors = await formik.validateForm();
      if (Object.keys(errors).length > 0) {
        Object.keys(values).forEach(key => {
          formik.setFieldTouched(key as keyof IAbsence, true, false);
        });
        return;
      }

      try {
        const formattedData = {
          passengerId: typeof values.usager === 'object' ? values.usager.id : values.usager,
          state: Array.isArray(values.etat) 
            ? values.etat.map(state => mapFrontToBackState(state))
            : mapFrontToBackState(values.etat),
          startDate: values.dateDebut,
          endDate: values.dateFin,
          forecastDate: values.previentLe,
          concernedTrip: values.sensAR.map(v => v === 'aller' ? 'Outbound' : 'Return'),
          observations: values.observation || '',
          receivingMethod: values.modeReception,
          comment: values.comment || '',
          reportedBy: values.par,
        };

        if (mode === 'add') {
          await createAbsence(formattedData);
          enqueueSnackbar('Absence créée avec succès', { variant: 'success' });
        } else {
          await updateAbsence(parseInt(values.id), formattedData);
        }
        
        onSave(values);
        onClose(true);
      } catch (error: any) {
        if (error?.code === "001" || error?.response?.data?.code === "001") {
          enqueueSnackbar("Une absence existe déjà pour ce passager à cette date.", { variant: 'error' });
        } else {
          enqueueSnackbar(
            error?.message || error?.response?.data?.message || "Erreur lors de la création de l'absence",
            { variant: 'error' }
          );
        }
      }
    },
  }); 

  useEffect(() => {
    if (updateTabContent && tabId && (mode !== "view")) {
      updateTabContent(tabId, formik.values)
    }
  }, [formik.values, updateTabContent, tabId, mode])

  const renderField = (field: FormFieldType<IAbsence>) => {
    const fieldName = field.name as keyof IAbsence;
    const error = formik.touched[fieldName] && formik.errors[fieldName] ? String(formik.errors[fieldName]) : undefined;
    
    if (field.name === 'usager') {
 

      const options = passengerNames.map(passenger => ({
        value: passenger.id.toString(),
        label: `${passenger.firstName} ${passenger.lastName}`,
        passenger: {
          id: passenger.id,
          firstName: passenger.firstName,
          lastName: passenger.lastName,
          establishmentName: '', 
          departmentName: '',
          departmentId: passenger.departmentId 
        }
      }));

      let selectedOption: typeof options[0] | null = null;
      if (formik.values.usager?.id) {
        const usagerIdValue = formik.values.usager.id;
        const usagerId = String(usagerIdValue);
        selectedOption = options.find(opt => opt.value === usagerId) || null;
        
        if (!selectedOption && formik.values.usager.firstName && formik.values.usager.lastName) {
          const departmentIdValue = typeof (formik.values.usager as any).departmentId === 'number' 
            ? (formik.values.usager as any).departmentId 
            : undefined;
          
          const departmentNameValue = formik.values.usager.departmentName;
          const departmentNameString = Array.isArray(departmentNameValue) 
            ? departmentNameValue[0] || '' 
            : departmentNameValue || '';
          
          selectedOption = {
            value: usagerId,
            label: `${formik.values.usager.firstName} ${formik.values.usager.lastName}`,
            passenger: {
              id: typeof usagerIdValue === 'number' ? usagerIdValue : parseInt(usagerIdValue as string),
              firstName: formik.values.usager.firstName,
              lastName: formik.values.usager.lastName,
              establishmentName: formik.values.usager.establishmentName || '',
              departmentName: departmentNameString,
              departmentId: departmentIdValue,
            }
          };
        }
      }
      
     

      return (
        <Autocomplete
          options={options}
          value={selectedOption}
          disabled={isReadOnly}
          loading={passengersLoading}
          filterOptions={(options) => options}  
          onInputChange={(event, newInputValue, reason) => {
            formik.setFieldValue('searchTerm', newInputValue);
            if (reason === 'input') {
              handlePassengerSearch(newInputValue);
            }
          }}
          onChange={(event, newValue) => {
            if (newValue) {
              handlePassengerSelect(newValue.value);
            } else {
              handlePassengerSelect('');
            }
          }}
          renderOption={(props, option, { selected }) => {
            const { style, ...otherProps } = props;
            return (
              <Box
                component="li"
                {...otherProps}
                sx={{
                  backgroundColor: selected ? theme.palette.primary.main : 'transparent',
                  color: selected ? 'white' : 'inherit',
                  '&:hover': {
                    backgroundColor: selected ? theme.palette.primary.main : theme.palette.action.hover,
                  },
                  padding: '8px 16px',
                  cursor: 'pointer',
                }}
              >
                {option.label}
              </Box>
            );
          }}
          renderInput={(params) => (
            <StyledTextField
              {...params}
              isSmallScreen={isSmallScreen}
              error={!!error}
              helperText={error || ""}
              onBlur={() => {
                formik.setFieldTouched(fieldName, true, false);
                formik.validateField(fieldName);
              }}
              fullWidth
              label={
                <>
                  Usager
                  <span style={{ color: '#FF0000' }}> *</span>
                </>
              }
              placeholder="Rechercher un usager..."
              InputLabelProps={{
                shrink: true,
              }}
              sx={{
                '& .MuiInputBase-root': {
                  padding: 0,
                  ...(isReadOnly && {
                    backgroundColor: '#f5f5f5',
                    cursor: 'not-allowed',
                  }),
                },
                ...(isReadOnly
                  ? {
                    '& .MuiInputBase-input': {
                      cursor: 'not-allowed',
                      color: 'text.disabled',
                    },
                  }
                  : {
                    '& .MuiAutocomplete-popupIndicator': {
                      color: theme.palette.primary.main,
                    },
                  }),
              }}
            />
          )}
          getOptionLabel={(option) => {
            if (typeof option === 'string') return option;
            return option.label || '';
          }}
          ListboxProps={{
            style: { maxHeight: '300px' },
          }}
          noOptionsText={passengersLoading ? "Chargement..." : "Aucun usager trouvé"}
          clearIcon={<FontAwesome icon={faClose} width={18} sx={{ color: 'primary.main' }} />}
          forcePopupIcon={true}
          PaperComponent={(props) => (
            <Paper
              {...props}
              elevation={3}
            />
          )}
        />
      );
    }

    if (field.name === 'par') {
    
      const collaboratorOptions = collaborators.map(collaborator => ({
        value: `${collaborator.firstName} ${collaborator.lastName}`,
        label: `${collaborator.firstName} ${collaborator.lastName}`,
        collaborator
      }));

      let selectedCollaboratorOption = null;
      if (formik.values.par) {
        selectedCollaboratorOption = collaboratorOptions.find(opt => opt.value === formik.values.par) || null;
        
        if (!selectedCollaboratorOption) {
          selectedCollaboratorOption = {
            value: formik.values.par,
            label: formik.values.par,
            collaborator: null as any
          };
        }
      }

    

      return (
        <Autocomplete
          options={collaboratorOptions}
          value={selectedCollaboratorOption}
          disabled={isReadOnly || !formik.values.usager}
          loading={collaboratorsLoading}
          filterOptions={(options) => options}
          freeSolo={false}
          onChange={(event, newValue) => {
            if (newValue) {
              const value = typeof newValue === 'string' ? newValue : newValue.value;
              formik.setFieldValue('par', value);
            } else {
              formik.setFieldValue('par', '');
            }
            formik.setFieldTouched('par', true, false);
            formik.validateField('par');
          }}
          renderOption={(props, option, { selected }) => {
            const { style, ...otherProps } = props;
            return (
              <Box
                component="li"
                {...otherProps}
                sx={{
                  backgroundColor: selected ? theme.palette.primary.main : 'transparent',
                  color: selected ? 'white' : 'inherit',
                  '&:hover': {
                    backgroundColor: selected ? theme.palette.primary.main : theme.palette.action.hover,
                  },
                  padding: '8px 16px',
                  cursor: 'pointer',
                }}
              >
                {typeof option === 'string' ? option : option.label}
              </Box>
            );
          }}
          renderInput={(params) => (
            <StyledTextField
              {...params}
              isSmallScreen={isSmallScreen}
              error={!!error}
              helperText={error || ""}
              onBlur={() => {
                formik.setFieldTouched(fieldName, true, false);
                formik.validateField(fieldName);
              }}
              fullWidth
              label={
                <>
                  Par
                  <span style={{ color: '#FF0000' }}> *</span>
                </>
              }
              placeholder={!formik.values.usager ? "Sélectionnez d'abord un usager" : "Sélectionnez un collaborateur..."}
              InputLabelProps={{
                shrink: true,
              }}
              sx={{
                '& .MuiInputBase-root': {
                  padding: 0,
                  ...(isReadOnly && {
                    backgroundColor: '#f5f5f5',
                    cursor: 'not-allowed',
                  }),
                },
                ...(isReadOnly
                  ? {
                    '& .MuiInputBase-input': {
                      cursor: 'not-allowed',
                      color: 'text.disabled',
                    },
                  }
                  : {
                    '& .MuiAutocomplete-popupIndicator': {
                      color: theme.palette.primary.main,
                    },
                  }),
              }}
            />
          )}
          getOptionLabel={(option) => {
            if (typeof option === 'string') return option;
            return option.label || '';
          }}
          ListboxProps={{
            style: { maxHeight: '300px' },
          }}
          noOptionsText={
            !formik.values.usager 
              ? "Sélectionnez d'abord un usager" 
              : collaboratorsLoading 
                ? "Chargement..." 
                : "Aucun collaborateur trouvé"
          }
          clearIcon={<FontAwesome icon={faClose} width={18} sx={{ color: 'primary.main' }} />}
          forcePopupIcon={true}
          PaperComponent={(props) => (
            <Paper
              {...props}
              elevation={3}
            />
          )}
        />
      );
    }

    const displayValue = formik.values[field.name];

    return (
      <FormField
        field={field}
        value={displayValue}
        onChange={(name, value) => {
          formik.setFieldValue(name, value);
          formik.setFieldTouched(name, true, false);
        }}
        error={error}
        isReadOnly={isReadOnly}
        onBlur={() => {
          formik.setFieldTouched(fieldName, true, false);
          formik.validateField(fieldName);
        }}
      />
    );
  };

  return (
    <FormContainer titre="Fiche Absence" >
      <ConditionalComponent isValid={isReadOnly}>
        <EditExportButtons
          onEdit={isTraiteAbsence ? undefined : () => onEdit(absence)}
          tooltipTitle={TableType.AbsenceUsager}
          dataRow={absence}
          tableHead={tableHead}
        />
      </ConditionalComponent>
      <form onSubmit={formik.handleSubmit} noValidate>
        <Grid container spacing={4}>
          {useFormFieldsAbsence(_OPTION_DEMANDE).map((field) => (
            <Grid item xs={12} sx={field.name === 'sensAR' ? centerFlexColumn : undefined} sm={4} key={field.name}>
              {renderField(field)}
            </Grid>
          ))}

          <Grid item xs={12}>
            <ConditionalComponent isValid={!isReadOnly}>
              <ActionButtons 
                onSave={() => {
                  formik.validateForm().then((errors) => {
                    if (Object.keys(errors).length > 0) {
                      Object.keys(formik.values).forEach(key => {
                        formik.setFieldTouched(key as keyof IAbsence, true, false);
                      });
                    } else {
                      formik.submitForm();
                    }
                  });
                }}
                onCancel={() => onClose(false)} 
                mode={mode} 
              />
            </ConditionalComponent>
          </Grid>
        </Grid>
      </form>
    </FormContainer>
  );
}
