"use client"

import React, { useEffect, useRef, useCallback } from "react"
import { Grid, IconButton, InputAdornment, Autocomplete } from "@mui/material"
import { centerFlexColumn, StyledTextField } from "@/shared/theme/css"
import FormField from "@/shared/components/form/form-field"
import { TableColumn, TableType, type FormFieldType, type ModeType } from "@/shared/types/common"
import type { IDriverAbsence } from "@/shared/types/driver-absence"
import FormContainer from "@/layouts/form/form-container"
import ActionButtons from "@/shared/components/form/buttons-action"
import EditExportButtons from "@/shared/components/form/edit-export-buttons"
import { formFieldsDriverAbsence } from "../utils/form-fields-absence"
import { useResponsive } from "@/hooks"
import { faPaperclip } from "@fortawesome/free-solid-svg-icons"
import FontAwesome from "@/shared/components/fontawesome"
import CustomTooltip from "@/shared/components/tooltips/tooltip-custom"
import { useFormik } from "formik"
import { driverAbsenceValidationSchema } from "../utils/driver-absence-validation"
import ConditionalComponent from "@/shared/components/table/ConditionalComponent"
import { useDriverStore } from "@/shared/api/stores/driverStore"
import { IDriverType } from "@/shared/types/driver"

import { useDriverAbsenceStore } from "@/shared/api/stores/driverAbsenceStore"
import { BinaryQuestion } from "@/shared/types/trajet"
import { useDocumentStore } from "@/shared/api/stores/document-service/documentStore"

const searchDrivers = (name: string) => {
  useDriverStore.getState().fetchDrivers({ firstName: name, lastName: name });
};

interface AbsenceFormProps {
  absence: IDriverAbsence;
  mode: ModeType;
  onSave: (updatedAbsence: IDriverAbsence) => void | Promise<void>;
  onEdit: (updatedAbsence: IDriverAbsence) => void;
  onClose: (forceClose: boolean) => void;
  isTraiteAbsence?: boolean;
  tableHead: TableColumn[];
  updateTabContent?: (tabId: string, content: IDriverAbsence) => void;
  tabId?: string;
}

export default function AbsenceDriverForm({
  absence,
  mode,
  onSave,
  onClose,
  onEdit,
  isTraiteAbsence,
  tableHead,
  updateTabContent,
  tabId
}: AbsenceFormProps) {
  const isBetweenSmAndLg = useResponsive("between", "sm", "lg");
  const fileInputRef = useRef<HTMLInputElement>(null);
  const isReadOnly = mode === "view";
  const drivers = useDriverStore((state) => state.drivers) || [];

  const formik = useFormik<IDriverAbsence>({
    initialValues: absence,
    validationSchema: driverAbsenceValidationSchema,
    onSubmit: (values) => {
      if (mode === "add") {
        handleCreate(values);
      } else {
        handleUpdate(values);
      }
    },
  });

  const getDriverById = useCallback((id: string | null | undefined): IDriverType | null => {
    if (!id) return null;
    return drivers.find((driver) => parseInt(driver.id) === parseInt(id)) || null;
  }, [drivers]);

  const [authorizedBy, setAuthorizedBy] = React.useState<IDriverType | null>(() => getDriverById(absence.autorisePar));
  const [validatedBy, setValidatedBy] = React.useState<IDriverType | null>(() => getDriverById(absence.validePar));

  useEffect(() => {
    formik.setFieldValue('autorisePar', absence.autorisePar ? absence.autorisePar : null);
    formik.setFieldValue('validePar', absence.validePar ? absence.validePar : null);
  }, []);

  const handleUserSelect = (fieldName: string, driver: IDriverType | null) => {
    if (fieldName === 'autorisePar') {
      setAuthorizedBy(driver);
    } else if (fieldName === 'validePar') {
      setValidatedBy(driver);
    } else if (fieldName === 'chauffeur') {
      formik.setFieldValue(fieldName, driver ? String(driver.id) : null);
    }
  };

  const handleIconClick = () => {
    if (fileInputRef.current) {
      fileInputRef.current.click();
    }
  };

  const handleFileUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (file) {
      formik.setFieldValue('justificatif', file);
    }
  };

  const renderField = (field: FormFieldType<IDriverAbsence>) => {
    if (field.name === "justificatif") {
      const error = formik.touched[field.name] && formik.errors[field.name];
      return (
        <StyledTextField
          isSmallScreen={isBetweenSmAndLg}
          fullWidth
          name={field.name}
          InputLabelProps={{ shrink: true }}
          value={formik.values[field.name] ? formik.values[field.name].name : ""}
          onBlur={formik.handleBlur}
          error={!!error}
          helperText={error ? String(formik.errors[field.name]) : undefined}
          label={field.label}
          placeholder={field.placeholder}
          sx={{
            ...(isReadOnly && {
              '& .MuiInputBase-root': {
                backgroundColor: '#f5f5f5',
                cursor: 'not-allowed',
              },
              '& .MuiInputBase-input': {
                cursor: 'not-allowed',
                color: 'text.disabled',
              }
            })
          }}
          InputProps={{
            readOnly: isReadOnly,
            endAdornment: (
              <InputAdornment position="end">
                <CustomTooltip title="Importer la justification" arrow>
                  <IconButton onClick={handleIconClick} disabled={isReadOnly}>
                    <FontAwesome
                      icon={faPaperclip}
                      sx={{
                        color: isReadOnly ? 'text.disabled' : "primary.main",
                        width: isBetweenSmAndLg ? 16 : 18,
                      }}
                    />
                  </IconButton>
                </CustomTooltip>
              </InputAdornment>
            )
          }}
        />
      );
    }

    return (
      <FormField
        field={field}
        value={formik.values[field.name]}
        onChange={(name, value) => formik.setFieldValue(name, value)}
        error={
          formik.touched[field.name]
            ? (formik.errors[field.name] as string | undefined)
            : undefined
        }
        onBlur={formik.handleBlur}
        isReadOnly={field.name === "department" || field.name === "chauffeurAffecte" ? true : isReadOnly}
      />
    );
  };

  const handleCreate = async (values: IDriverAbsence) => {
    const document = await useDocumentStore.getState().upload(values.justificatif, values.chauffeur);

    const createdAbsence = await useDriverAbsenceStore.getState().createAbsence({
      ...values,
      supportingDocumentId: document,
      driverId: parseInt(values.chauffeur),
      absenceType: values.typeAbsence,
      startDate: new Date(values.dateDebut),
      endDate: new Date(values.dateFin),
      nbHours: parseInt(values.nombreHeures),
      receptionMode: values.modeReception,
      driverTraject: values.chauffeurAffecte === BinaryQuestion.Oui,
      isAssigned: values.chauffeurAffecte === BinaryQuestion.Oui,
      validatedBy: values.validePar ? parseInt(values.validePar) : null,
      authorizedBy: values.autorisePar ? parseInt(values.autorisePar) : null,
      status: values.statut
    });
    onSave(values);
    onClose(true);
  };

  const handleUpdate = async (values: IDriverAbsence) => {
    let document = absence.supportingDocumentId ?? 0;
    if (values.justificatif !== absence.justificatif) {
      document = await useDocumentStore.getState().upload(values.justificatif, values.chauffeur);
    }

    const updatedAbsence = await useDriverAbsenceStore.getState().updateAbsence(absence.id, {
      ...values,
      supportingDocumentId: document,
      driverId: absence.driver?.id ? parseInt(absence.driver.id) : parseInt(values.chauffeur),
      driverName: absence.driverName ? values.driverName  : `${absence.driver?.firstName} ${absence.driver?.lastName}`,
      absenceType: values.typeAbsence,
      startDate: new Date(values.dateDebut),
      endDate: new Date(values.dateFin),
      nbHours: parseInt(values.nombreHeures),
      receptionMode: values.modeReception,
      driverTraject: values.chauffeurAffecte === BinaryQuestion.Oui,
      isAssigned: values.chauffeurAffecte === BinaryQuestion.Oui,
      validatedBy: values.validePar ? parseInt(values.validePar) : null,
      authorizedBy: values.autorisePar ? parseInt(values.autorisePar) : null,
      status: values.statut,
    });
    if (updateTabContent && tabId) {
      updateTabContent(tabId, values);
    } else {
      onEdit(values);
    }
    onClose(true);
  };

  return (
    <FormContainer titre="Fiche d'absence chauffeur">
      <ConditionalComponent isValid={isReadOnly}>
        <EditExportButtons
          onEdit={isTraiteAbsence ? undefined : () => onEdit(absence)}
          onExport={() => void 0}
          tooltipTitle={TableType.absence}
          dataRow={absence}
          tableHead={tableHead}
        />
      </ConditionalComponent>

      <form onSubmit={formik.handleSubmit}>
        <Grid container spacing={4}>
          {formFieldsDriverAbsence.filter((field) =>
            !(!isTraiteAbsence && field.name === "validePar" && mode !== "edit")
          ).map((field) => (
            <Grid item xs={12} sm={4} sx={centerFlexColumn} key={field.name}>
              {field.name === "chauffeur" ? (
                <Autocomplete
                  options={drivers}
                  getOptionLabel={(option: IDriverType) => `${option.firstName} ${option.lastName}`}
                  onInputChange={(event, newInputValue) => {
                    searchDrivers(newInputValue);
                  }}
                  onChange={(event, value) => handleUserSelect(field.name, value)}
                  isOptionEqualToValue={(option, value) => option.id === value.id}
                  disableClearable={mode === "view"}
                  disabled={mode === "view" || mode === "edit"}
                  value={absence.driver ?? null}
                  renderInput={(params) => (
                    <StyledTextField
                      {...params}
                      label={field.label}
                      disabled={mode === "view" || mode === "edit"}
                      onBlur={formik.handleBlur}
                      error={mode === "view" || mode === "edit" ? false : formik.touched[field.name] && Boolean(formik.errors[field.name])}
                      helperText={formik.touched[field.name] && String(formik.errors[field.name])}
                    />
                  )}
                />
              ) : field.name === "autorisePar" ? (
                <Autocomplete
                  options={drivers}
                  getOptionLabel={(option: IDriverType) => `${option.firstName} ${option.lastName}`}
                  onInputChange={(event, newInputValue) => {
                    searchDrivers(newInputValue);
                  }}
                  onChange={(event, value) => handleUserSelect(field.name, value)}
                  isOptionEqualToValue={(option, value) => option.id === value.id}
                  value={authorizedBy}
                  renderInput={(params) => (
                    <StyledTextField
                      {...params}
                      label={field.label}
                      onBlur={formik.handleBlur}
                      error={formik.touched[field.name] && Boolean(formik.errors[field.name])}
                      helperText={formik.touched[field.name] && String(formik.errors[field.name])}
                    />
                  )}
                />
              ) : field.name === "validePar" ? (
                <Autocomplete
                  options={drivers}
                  getOptionLabel={(option: IDriverType) => `${option.firstName} ${option.lastName}`}
                  onInputChange={(event, newInputValue) => {
                    searchDrivers(newInputValue);
                  }}
                  onChange={(event, value) => handleUserSelect(field.name, value)}
                  isOptionEqualToValue={(option, value) => option.id === value.id}
                  value={validatedBy}
                  renderInput={(params) => (
                    <StyledTextField
                      {...params}
                      label={field.label}
                      onBlur={formik.handleBlur}
                      error={formik.touched[field.name] && Boolean(formik.errors[field.name])}
                      helperText={formik.touched[field.name] && String(formik.errors[field.name])}
                    />
                  )}
                />
              ) : (
                renderField(field)
              )}
            </Grid>
          ))}
          <input type="file" ref={fileInputRef} style={{ display: "none" }} onChange={handleFileUpload} />
          <Grid item xs={12}>
            <ConditionalComponent isValid={mode !== "view"}>
              <ActionButtons
                onSave={() => {
                  formik.validateForm().then(() => {
                    formik.submitForm();
                  });
                }}
                onCancel={() => onClose(false)}
                mode={mode}
              />
            </ConditionalComponent>
          </Grid>
        </Grid>
      </form>
    </FormContainer>
  );
}