"use client"
import { useEffect, useState } from "react"
import { FormikTouched, useFormik } from "formik"
import FormField from "@/shared/components/form/form-field"
import type { FormFieldType, ModeType, TableColumn } from "@/shared/types/common"
import FormContainer from "@/layouts/form/form-container"
import { type IIncident, TypeDeclaration } from "@/shared/types/flottes/incident"
import TabbedForm from "@/shared/components/tabs/tabbed-form"
import DocumentForm from "@/shared/components/documents/documents-form"
import { _interventionReport } from "@/shared/_mock/_documents"
import { vehicleIncidentSchema } from "../utils/vehicle-incident-schema"
import { InterventionType } from "@/shared/types/flottes/vehicule"
import { useRouter } from "next/navigation"
import { convertIncidentToIntervention, convertIncidentToRevision } from "../utils/vehicle-incident-converter"
import { mapVehicleIncidentToRequest, VehicleIncident, VehicleIncidentRequest } from "@/shared/types/fleet-management/vehicle-incident"
import { useSnackbar } from "notistack"
import { useInfrastructureStore } from "@/shared/api/stores/admin-service/infrastructureStore"
import { useVehicleStore } from "@/shared/api/stores/fleet-service/vehicle-store"
import { useDriverStore } from "@/shared/api/stores/driverStore"
import { useServiceProviderStore } from "@/shared/api/stores/fleet-service/service-provider-store"
import { useInterventionStore } from "@/shared/api/stores/fleet-service/intervention-store"
import VehicleIncidentDetails from "../components/vehicle-incident-details"
import { useVehicleIncidentStore } from "@/shared/api/stores/fleet-service/vehicle-incident-store"

interface IncidentFormProps {
  vehicleIncident: VehicleIncident
  mode: ModeType
  onSave: (updatedIncident: VehicleIncidentRequest) => void
  onEdit: (updatedIncident: VehicleIncidentRequest) => void
  onClose: (isSaved: boolean) => void
  tableHead: TableColumn[]
  setHasUnsavedChanges?: (value: boolean) => void
  updateTabContent?: (tabId: string, newContent: VehicleIncidentRequest) => void
  tabId?: string
}

export default function VehicleIncidentForm({
  vehicleIncident,
  mode,
  onSave,
  onClose,
  onEdit,
  tableHead,
  setHasUnsavedChanges,
  updateTabContent,
  tabId,
}: IncidentFormProps) {
  const isReadOnly = mode === "view"

  const { enqueueSnackbar } = useSnackbar();

  const router = useRouter()

  const [formData, setFormData] = useState({} as VehicleIncidentRequest);

  const [departmentOptions, setDepartmentOptions] = useState<{ value: string; label: string }[]>([]);
  const [vehicleOptions, setVehicleOptions] = useState<{ value: string; label: string }[]>([]);
  const [driverOptions, setDriverOptions] = useState<{ value: string; label: string }[]>([]);
  const [serviceProviderOptions, setServiceProviderOptions] = useState<{ value: string; label: string }[]>([]);
  const [interventionOptions, setInterventionOptions] = useState<{ value: string; label: string }[]>([]);

  const {
    departmentNames,
    fetchDepartmentNames
  } = useInfrastructureStore();

  const {
    getVehicleShortAll
  } = useVehicleStore();

  const {
    getAllShorts
  } = useDriverStore();

  const {
    allServiceProviders,
    fetchAllServiceProviders
  } = useServiceProviderStore();

  const {
    fetchAllInterventions
  } = useInterventionStore();

  const {
    getVehicleIncidentById,
    createVehicleIncident,
    updateVehicleIncident
  } = useVehicleIncidentStore();

  const handleFormSubmit = async (values: VehicleIncidentRequest) => {
    if (mode === 'edit') {
      try {
        await updateVehicleIncident(vehicleIncident.id, values);
        onClose(true);
        enqueueSnackbar('Incident / Sinistre de véhicule modifié avec succès', { variant: 'success' });
      } catch (error: any) {
        enqueueSnackbar(error.message, { variant: 'error' });
        return;
      }
    } else if (mode === 'add' || mode === 'copy') {
      try {
        await createVehicleIncident(values);
        onClose(true);
        enqueueSnackbar('Incident / Sinistre de véhicule créé avec succès', { variant: 'success' });
      } catch (error: any) {
        enqueueSnackbar(error.message, { variant: 'error' });
        return;
      }
    }
  };

  const formik = useFormik<VehicleIncidentRequest>({
    initialValues: formData,
    validationSchema: vehicleIncidentSchema,
    enableReinitialize: true,
    onSubmit: handleFormSubmit
  })

  useEffect(() => {
    const fetchOptionsData = async () => {
      await fetchDepartmentNames();

      const allVehicleShortAll = await getVehicleShortAll();
      const allDriverShort = await getAllShorts();
      const allServiceProviders = await fetchAllServiceProviders();
      const allInterventions = await fetchAllInterventions();

      setVehicleOptions(
        allVehicleShortAll.map((v) => ({ value: String(v.id), label: v.registrationPlate }))
      );
      setDriverOptions(
        allDriverShort.map((d) => ({ value: String(d.id), label: `${d.firstName} ${d.lastName}` }))
      );
      setServiceProviderOptions(
        allServiceProviders.map((sp) => ({ value: String(sp.id), label: sp.name }))
      );
      setInterventionOptions(
        allInterventions.map((i) => ({ value: String(i.id), label: i.name }))
      );
    };

    const getInitialValues = async () => {
      if (vehicleIncident.id && mode !== 'add') {
        const vehicleIncidentData = await getVehicleIncidentById(vehicleIncident.id);
        if (vehicleIncidentData) {
          const mappedData = mapVehicleIncidentToRequest(vehicleIncidentData);
          setFormData(mappedData);
        }
      }
    }

    fetchOptionsData();
    getInitialValues();
  }, [vehicleIncident.id, mode]);

  useEffect(() => {
    setDepartmentOptions(
      departmentNames.map((d) => ({ value: d.id.toString(), label: d.name }))
    );
  }, [departmentNames])

  useEffect(() => {
    if (mode === 'add') {
      setFormData({} as VehicleIncidentRequest);
      formik.resetForm();
    }
  }, []);

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

  const changeServiceProviderId = (serviceProviderId: string) => {
    if (serviceProviderId) {
      const serviceProvider = allServiceProviders.find(
        (sp) => String(sp.id) === String(serviceProviderId)
      );

      formik.setFieldValue("serviceProviderId", serviceProviderId);
      formik.setFieldValue("interventionId", String(serviceProvider?.intervention.id) || '');
      formik.setFieldValue("interventionType", String(serviceProvider?.intervention.interventionType) || '');
    }
  }

  const renderField = (field: FormFieldType<VehicleIncidentRequest>) => {
    const handleChange = (name: string, value: any) => {
      formik.setFieldValue(name, value);
      if (name === 'serviceProviderId') {
        changeServiceProviderId(value);
      }
    };

    return (
      <FormField
        field={field}
        value={
          field.name === 'departmentId' ? String(formik.values[field.name as keyof VehicleIncidentRequest] || '') :
            field.name === 'vehicleId' ? String(formik.values[field.name as keyof VehicleIncidentRequest] || '') :
              field.name === 'driverId' ? String(formik.values[field.name as keyof VehicleIncidentRequest] || '') :
                field.name === 'serviceProviderId' ? String(formik.values[field.name as keyof VehicleIncidentRequest] || '') :
                  field.name === 'interventionId' ? String(formik.values[field.name as keyof VehicleIncidentRequest] || '') :
                    formik.values[field.name as keyof VehicleIncidentRequest]}
        onChange={handleChange}
        error={
          formik.touched[field.name as keyof VehicleIncidentRequest]
            ? (formik.errors[field.name as keyof VehicleIncidentRequest] as string | undefined)
            : undefined
        }
        onBlur={formik.handleBlur}
        isReadOnly={isReadOnly}
      />
    )
  }

  const tabs = [
    {
      label: "Sinistre",
      content: (
        <VehicleIncidentDetails
          renderField={renderField}
          mode={mode}
          onSave={() => {
            formik.validateForm().then((errors) => {
              const hasErrors = Object.keys(errors).length > 0;
              if (!hasErrors) {
                formik.submitForm();
              } else {
                formik.setTouched(
                  Object.keys(errors).reduce((acc, key) => {
                    acc[key as keyof VehicleIncidentRequest] = true;
                    return acc;
                  }, {} as FormikTouched<VehicleIncidentRequest>)
                );
              }
            });
          }}
          onClose={() => onClose(false)}
          onEdit={() => onEdit(formik.values)}
          incident={formik.values}
          tableHead={tableHead}
          departmentOptions={departmentOptions}
          vehicleOptions={vehicleOptions}
          driverOptions={driverOptions}
          serviceProviderOptions={serviceProviderOptions}
          interventionOptions={interventionOptions}
        />
      ),
    },
    {
      label: "Documents",
      content: <DocumentForm documents={mode === "add" ? [] : _interventionReport} />,
    },
  ]

  const navigateToAnotherPage = (values: IIncident) => {
    if (values.declaration === TypeDeclaration.Adanev) {
      if (values.interventionType) {
        if (values.interventionType === InterventionType.Réparation) {
          const interventionData = convertIncidentToIntervention(values)
          sessionStorage.setItem("pendingInterventionData", JSON.stringify(interventionData))
          router.push("/dashboard/flottes/entretien/reparation?openView=true")
          return
        } else if (values.interventionType === InterventionType.Entretien) {
          const revisionData = convertIncidentToRevision(values)
          sessionStorage.setItem("pendingRevisionData", JSON.stringify(revisionData))
          router.push("/dashboard/flottes/revision?openView=true")
          return
        }
      }
    } else {
      if (setHasUnsavedChanges) setHasUnsavedChanges(false)
      onClose(true)
    }
  }

  return (
    <FormContainer titre="Fiche Sinistre">
      <form onSubmit={formik.handleSubmit}>
        <TabbedForm tabs={tabs} />
      </form>
    </FormContainer>
  )
}