"use client"

import React, { useEffect, useState } from "react"
import { Box, Grid } from "@mui/material"
import { LotList, mapLotToLotRequest, type DepartmentRequest, type LotRequest } from "@/shared/types/infrastructure"
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 { mainLotFormFields } from "../utils/lot-form-fields"
import { FormikTouched, useFormik } from "formik"
import EditExportButtons from "@/shared/components/form/edit-export-buttons"
import ConditionalComponent from "@/shared/components/table/ConditionalComponent"
import { useSnackbar } from "notistack"
import { useInfrastructureStore } from "@/shared/api/stores/admin-service/infrastructureStore"
import ActionButtons from "@/shared/components/form/buttons-action"
import { lotSchema } from "../utils/lot-validation"

interface LotFormProps {
  lot: LotList
  mode: ModeType
  onEdit: (lot: LotList) => void
  onClose: (forceClose: boolean) => void
  tableHead?: TableColumn[]
  updateTabContent?: (tabId: string, content: any) => void
  tabId?: string
}

export default function LotForm({
  lot,
  mode,
  onEdit,
  onClose,
  tableHead = [],
  updateTabContent,
  tabId
}: LotFormProps) {
  const isReadOnly = mode === "view"

  const { enqueueSnackbar } = useSnackbar();

  const lotId = lot.id;

  const [lotData, setLotData] = useState<LotRequest>({} as LotRequest);
  const [departmentOptions, setDepartmentOptions] = useState<{ value: string, label: string }[]>([]);

  const { departmentNames, fetchDepartmentNames, lotById, getLotById, createLot, updateLot } = useInfrastructureStore();

  const disableDepartments = mode === "edit";

  useEffect(() => {
    fetchDepartmentNames();
  }, []);

  useEffect(() => {
    if (lotId) {
      getLotById(lotId);
    }
  }, [lotId]);

  useEffect(() => {
    if (lotById) {
      setLotData(mapLotToLotRequest(lotById));
    }
  }, [lotById]);

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

  const handleFormSubmit = (values: LotRequest) => {
    if (mode === 'add' || mode === 'copy') {
      try {
        createLot(values);
        enqueueSnackbar('Lot créé avec succès', { variant: 'success' });
        onClose(true);
      } catch (error: any) {
        enqueueSnackbar(error.message, { variant: 'error' });
        return;
      }
    } else if (mode === 'edit') {
      try {
        updateLot(lotId, values);
        enqueueSnackbar('Lot modifié avec succès', { variant: 'success' });
        onClose(true);
      } catch (error: any) {
        enqueueSnackbar(error.message, { variant: 'error' });
        return;
      }
    }
  };

  const formik = useFormik<LotRequest>({
    initialValues: lotData,
    validationSchema: lotSchema,
    onSubmit: handleFormSubmit,
    enableReinitialize: true,
  })

  useEffect(() => {
    if (updateTabContent && tabId && mode !== "view") {
      const timer = setTimeout(() => {
        updateTabContent(tabId, formik.values)
      }, 300)

      return () => {
        clearTimeout(timer)
      }
    }
  }, [formik.values, updateTabContent, tabId, mode])
  
  const renderField = (field: FormFieldType<LotRequest>) => {
    const fieldValue = formik.values[field.name as keyof LotRequest]
    const value = field.type === "multiple"
      ? (Array.isArray(fieldValue) ? fieldValue.filter(v => v !== null) : [])
      : fieldValue

    return (
      <FormField
        field={field}
        value={value}
        onChange={(name, value) => {
          formik.setFieldValue(name, value)
        }}
        error={
          formik.touched[field.name as keyof LotRequest]
            ? (formik.errors[field.name as keyof LotRequest] as string | undefined)
            : undefined
        }
        onBlur={formik.handleBlur}
        isReadOnly={field.name === 'departmentsIds' ? disableDepartments : isReadOnly}
      />
    )
  }

  return (
    <FormContainer sx={{ width: "100%" }}>
      <ConditionalComponent isValid={isReadOnly}>
        <EditExportButtons
          onEdit={() => onEdit(lot)}
          tooltipTitle="Lot"
          dataRow={formik.values}
          tableHead={tableHead}
        />
      </ConditionalComponent>

      <form onSubmit={formik.handleSubmit}>
        <Box
          sx={{
            width: "100%",
            display: "flex",
            flexDirection: "column",
            alignItems: "center",
            justifyContent: "center",
          }}
        >
          <Grid
            container
            spacing={2}
            direction="column"
            alignItems="center"
            justifyContent="center"
            sx={{ minHeight: "100%", maxWidth: "600px", margin: "auto" }}
          >
            {mainLotFormFields(departmentOptions).map((field) => (
              <Grid item xs={12} key={field.name} sx={{ width: "100%" }}>
                {renderField(field)}
              </Grid>
            ))}

            <ConditionalComponent isValid={!isReadOnly}>
              <Grid container spacing={2} justifyContent="flex-end" sx={{ mt: 3 }}>
                <ActionButtons
                  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 DepartmentRequest] = true;
                            return acc;
                          }, {} as FormikTouched<DepartmentRequest>)
                        );
                      }
                    });
                  }}
                  onCancel={() => onClose(false)}
                  mode={mode} />
              </Grid>
            </ConditionalComponent>
          </Grid>
        </Box>
      </form>
    </FormContainer>
  )
}
