'use client';

import React, { useEffect, useMemo, useCallback } 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 { 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';

interface AbsenceFormProps {
  absence: IAbsence;
  mode: ModeType;
  onSave: (updatedAbsence: IAbsence) => void;
  onEdit: (updatedAbsence: 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 } = useAbsenceStore();
  const { passengers, searchPassengers, loading: passengersLoading } = usePassengerStore();
  const isBetweenSmAndLg = useResponsive('between', 'sm', 'lg');
  const theme = useTheme();
  const isSmallScreen = isBetweenSmAndLg;
  
  useEffect(() => {
    searchPassengers({ size: 1000 });
  }, [searchPassengers]);

  const isReadOnly = mode === 'view';
  const isCreating = mode === 'add';
  
  const handlePassengerSelect = (selectedValue: string | number) => {
    if (!selectedValue) {
      formik.setFieldValue('usager', null);
      formik.setFieldValue('etablissement', '');
      formik.setFieldValue('departement', '');
      formik.setFieldTouched('usager', true, false);
      formik.validateField('usager');
      return;
    }
    
    const selectedPassenger = usePassengerStore.getState().passengers.find(p => p.id.toString() === selectedValue.toString());    
    if (selectedPassenger) {
      const usagerObject = {
        id: selectedPassenger.id,
        firstName: selectedPassenger.firstName,
        lastName: selectedPassenger.lastName,
        establishmentName: selectedPassenger.establishmentTransportSchedules?.[0]?.establishmentName,
        departmentName: selectedPassenger.departmentName
      };      
      formik.setFieldValue('usager', usagerObject);
      formik.setFieldValue('etablissement', selectedPassenger.establishmentTransportSchedules?.[0]?.establishmentName);
      formik.setFieldValue('departement', selectedPassenger.departmentName);
    }
  };

  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 = passengers
        .filter(passenger => {
          const searchTerm = (formik.values.searchTerm || '').toLowerCase();
          if (!searchTerm) return true;
          
          const fullName = `${passenger.firstName} ${passenger.lastName}`.toLowerCase();          
          return fullName.includes(searchTerm) ;
        })
        .map(passenger => ({
          value: passenger.id.toString(),
          label: `${passenger.firstName} ${passenger.lastName}`,
          passenger
        }));

      const selectedOption = formik.values.usager?.id ? 
        options.find(opt => opt.value === formik.values.usager.id.toString()) : null;

      return (
        <Autocomplete
          options={options}
          value={selectedOption}
          disabled={isReadOnly}
          loading={passengersLoading}
          filterOptions={(options) => options}  
          onInputChange={(event, newInputValue, reason) => {
            formik.setFieldValue('searchTerm', 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}
            />
          )}
        />
      );
    }

    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>
  );
}
