"use client"

import { useEffect, useState, useCallback, useRef, useMemo } from "react"
import { Grid, Box, Typography, IconButton, FormHelperText } from "@mui/material"
import { faPlus } from "@fortawesome/free-solid-svg-icons"
import FontAwesome from "@/shared/components/fontawesome"
import { mapAgencyToAgencyRequest, type AgencyList, type AgencyRequest, type DepartmentChildren } 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 { mainAgencyFormFields } from "../utils/form-fields-agency"
import { FormikTouched, useFormik } from "formik"
import EditExportButtons from "@/shared/components/form/edit-export-buttons"
import ConditionalComponent from "@/shared/components/table/ConditionalComponent"
import TabbedForm from "@/shared/components/tabs/tabbed-form"
import { useInfrastructureStore } from "@/shared/api/stores/admin-service/infrastructureStore"
import { useSnackbar } from "notistack"
import { getFormatedAddress } from "../../utils/address-utils"
import ActionButtons from "@/shared/components/form/buttons-action"
import { agencySchema } from "../utils/agency-validation"
import dayjs from "dayjs"
interface AgencyFormProps {
  agency: AgencyList
  mode: ModeType
  onEdit: (agency: AgencyList) => void
  onClose: (forceClose: boolean) => void
  tableHead?: TableColumn[]
  updateTabContent: (tabId: string, content: any) => void
  tabId: string
  markTabAsSaved?: (tabId: string, content: any) => void
  tabContent?: AgencyList
}

export default function AgencyForm({
  agency,
  mode,
  onEdit,
  onClose,
  tableHead = [],
  updateTabContent,
  tabId,
  markTabAsSaved,
  tabContent
}: AgencyFormProps) {
  const isReadOnly = mode === "view"

  const { enqueueSnackbar } = useSnackbar();

  const [agencyFormData, setAgencyFormData] = useState<AgencyRequest>({} as AgencyRequest);
  const [departments, setDepartments] = useState<DepartmentChildren[]>([]);
  const [selectedDepartment, setSelectedDepartment] = useState<DepartmentChildren | null>(null);
  const [sectorOptions, setSectorOptions] = useState<{ value: string, label: string }[]>([]);
  const [nameAvailability, setNameAvailability] = useState<{ message: string, isAvailable: boolean } | null>(null);
  const previousFormDataRef = useRef<AgencyRequest | null>(null);

  const {
    error,
    clearError,
    getAgencyById,
    createAgency,
    updateAgency,
    sectorNames,
    fetchSectorNames,
    existsAgencyByNameLoading,
    existsAgencyByName
  } = useInfrastructureStore();

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

  const getInitialValues = async () => {
    if (agency.id && mode !== 'add') {
      const agencyData = await getAgencyById(agency.id);
      if (agencyData) {
        const mappedData = mapAgencyToAgencyRequest(agencyData);
        setAgencyFormData(mappedData);
        setDepartments(agencyData?.departments || []);
      }
    }
  }

  // Load data from API when needed
  useEffect(() => {
    if (!tabContent && mode !== 'add' && agency.id) {
      getInitialValues();
    }
  }, [agency.id, mode, tabContent]);

  // Use tab content if available, otherwise use form data
  useEffect(() => {
    if (tabContent && typeof tabContent === 'object') {
      // tabContent is the formik.values (AgencyRequest) from updateTabContent
      // Check if it has sectorId property to determine if it's Request or List
      const hasSectorId = 'sectorId' in tabContent;
      const hasMapAddresse = 'mapAddresse' in tabContent;
      
      if (hasSectorId && hasMapAddresse) {
        // It's already an AgencyRequest from formik.values
        setAgencyFormData(tabContent as AgencyRequest);
        // Load departments for the table display
        if (tabContent.id) {
          getAgencyById(tabContent.id).then((agencyData) => {
            if (agencyData) {
              setDepartments(agencyData?.departments || []);
            }
          });
        }
      } else {
        // Convert AgencyList to AgencyRequest format (needs API call for sectorId)
        const mappedData: AgencyRequest = {
          id: tabContent.id,
          name: tabContent.name,
          description: tabContent.description,
          mapAddresse: undefined,
          sectorId: ''
        };
        setAgencyFormData(mappedData);
        // Load departments and get sectorId from API
        if (tabContent.id) {
          getAgencyById(tabContent.id).then((agencyData) => {
            if (agencyData) {
              setDepartments(agencyData?.departments || []);
              // Update sectorId from API
              const fullData = mapAgencyToAgencyRequest(agencyData);
              setAgencyFormData(fullData);
            }
          });
        }
      }
      previousFormDataRef.current = null; // Reset the ref
    } else if (mode === 'add' || (agency.id && Object.keys(agencyFormData).length === 0)) {
      getInitialValues();
      previousFormDataRef.current = null; // Reset the ref
    }
  }, [agency.id, mode, tabContent]);





  useEffect(() => {
    if (sectorNames) {
      setSectorOptions(sectorNames.map((sector) => ({ value: sector.id.toString(), label: sector.name })));
    }
  }, [sectorNames]);

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

  const handleFormSubmit = async (values: AgencyRequest) => {
    if (nameAvailability != null && !nameAvailability.isAvailable) {
      enqueueSnackbar('Veuillez entrer un nom valide !', { variant: 'error' });
      return;
    }
    const request = {
      ...values,
      address: values.mapAddresse ? getFormatedAddress(values.mapAddresse) : undefined
    };
    if (mode === 'add' || mode === 'copy') {
      try {
        await createAgency(request);
        enqueueSnackbar('Agence créée avec succès', { variant: 'success' });
        // Pour le mode création, on retourne à la liste car on ne peut pas rester sans ID
        onClose(true);
      } catch (error: any) {
        enqueueSnackbar(error.message, { variant: 'error' });
        clearError();
        return;
      }
    } else if (mode === 'edit') {
      if (!agency?.id) {
        enqueueSnackbar('Erreur: ID de l\'agence manquant', { variant: 'error' });
        return;
      }
      try {
        await updateAgency(agency.id, request);
        enqueueSnackbar('Agence modifiée avec succès', { variant: 'success' });
        // Rester dans le formulaire en mode "view" au lieu de retourner à la liste
        if (markTabAsSaved) {
          // Recharger les données complètes pour avoir le bon format
          const fullAgencyData = await getAgencyById(agency.id);
          if (fullAgencyData) {
            markTabAsSaved(tabId, fullAgencyData);
          } else {
            onClose(true);
          }
        } else {
          onClose(true);
        }
      } catch (error: any) {
        enqueueSnackbar(error.message, { variant: 'error' });
        clearError();
        return;
      }
    }
  };

  // Use tab content directly if available, otherwise use form data
  const initialValues = useMemo(() => {
    if (tabContent && typeof tabContent === 'object') {
      // Check if it's already an AgencyRequest
      if ('sectorId' in tabContent && 'mapAddresse' in tabContent) {
        return tabContent as AgencyRequest;
      }
      // Otherwise it's AgencyList, use agencyFormData which will have sectorId from API
    }
    return agencyFormData;
  }, [tabContent, agencyFormData]);

  const formik = useFormik<AgencyRequest>({
    initialValues: initialValues,
    validationSchema: agencySchema,
    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 nameTimeoutRef = useRef<NodeJS.Timeout>();

  const checkName = useCallback((name: string) => {
    if (nameTimeoutRef.current) {
      clearTimeout(nameTimeoutRef.current);
    }

    if (!name) {
      setNameAvailability(null);
      return;
    }

    const trimmedName = name.trim();
    if (trimmedName === '') {
      setNameAvailability(null);
      return;
    }

    nameTimeoutRef.current = setTimeout(() => {
      const verifyName = async () => {
        try {
          const exists = mode === 'edit'
            ? await existsAgencyByName(trimmedName, Number(agency.id))
            : await existsAgencyByName(trimmedName);

          setNameAvailability({
            message: exists ? 'Le nom existe déjà' : 'Le nom est disponible',
            isAvailable: !exists
          });
        } catch (error) {
          setNameAvailability(null);
        }
      };

      verifyName();
    }, 500);
  }, [mode, agency.id, existsAgencyByName]);

  useEffect(() => {
    return () => {
      if (nameTimeoutRef.current) {
        clearTimeout(nameTimeoutRef.current);
      }
    };
  }, []);

  useEffect(() => {
    if (error) {
      enqueueSnackbar(error, { variant: 'error' })
      clearError()
    }
  }, [error, enqueueSnackbar, clearError])

  const renderField = (field: FormFieldType<AgencyRequest>) => (
    <>
      <FormField
        field={field}
        value={formik.values[field.name as keyof AgencyRequest]}
        onChange={(name, value) => {
          formik.setFieldValue(name, value);
          if (field.name === 'name') {
            checkName(value);
          }
        }}
        error={
          formik.touched[field.name as keyof AgencyRequest]
            ? (formik.errors[field.name as keyof AgencyRequest] as string | undefined)
            : undefined
        }
        onBlur={formik.handleBlur}
        isReadOnly={field.name === 'sectorId' ? (mode === 'view' || mode === 'edit') : isReadOnly}
      />
      <ConditionalComponent isValid={field.name === 'name'}>
        <FormHelperText
          sx={{
            color: existsAgencyByNameLoading ? 'text.secondary' : (nameAvailability?.isAvailable ? 'success.main' : 'error.main'),
            marginTop: '4px',
            display: 'flex',
            alignItems: 'center'
          }}
        >
          <ConditionalComponent isValid={existsAgencyByNameLoading}>
            <Box sx={{ display: 'flex', alignItems: 'center' }}>
              <Box
                sx={{
                  width: '16px',
                  height: '16px',
                  border: '2px solid #f3f3f3',
                  borderTop: '2px solid #746CD4',
                  borderRadius: '50%',
                  animation: 'spin 1s linear infinite',
                  marginRight: '8px',
                  '@keyframes spin': {
                    '0%': { transform: 'rotate(0deg)' },
                    '100%': { transform: 'rotate(360deg)' }
                  }
                }}
              />
              <Typography sx={{ color: '#746CD4' }}>
                Vérification en cours...
              </Typography>
            </Box>
          </ConditionalComponent>
          <ConditionalComponent isValid={!existsAgencyByNameLoading}>
            {nameAvailability?.message}
          </ConditionalComponent>
        </FormHelperText>
      </ConditionalComponent>
    </>
  )

  const tabs = [
    {
      label: "Departement",
      content: (
        <Box
          sx={{
            borderRadius: "8px",
            width: "100%",
            marginTop: "20px",
            justifyContent: "center",
            alignItems: "center",
          }}
        >
          <Box
            sx={{
              display: "flex",
              justifyContent: "flex-end",
              width: "80%",
              margin: "0 auto 10px auto",
            }}
          >
            <ConditionalComponent isValid={!isReadOnly}>
              <IconButton
                color="inherit"
                sx={{
                  backgroundColor: "#746CD4",
                  color: "white",
                  "&:hover": { backgroundColor: "#F0F0FA", color: "#746CD4" },
                }}
                aria-label="add"
                onClick={() => {}}
              >
                <FontAwesome icon={faPlus} width={16} />
              </IconButton>
            </ConditionalComponent>
          </Box>

          <Box
            sx={{
              borderRadius: "8px",
              width: "100%",
              display: "flex",
              flexDirection: "column",
              alignItems: "center",
            }}
          >
            <Box
              sx={{
                display: "flex",
                backgroundColor: "#f0f0fa",
                padding: "16px",
                borderRadius: "8px",
                width: "80%",
              }}
            >
              <Typography
                variant="subtitle2"
                sx={{
                  width: "20%",
                  fontWeight: "500",
                  color: "#6b7280",
                }}
              >
                Nom de Departement
              </Typography>
              <Typography
                variant="subtitle2"
                sx={{
                  width: "20%",
                  fontWeight: "500",
                  color: "#6b7280",
                }}
              >
                Adresse
              </Typography>
              <Typography
                variant="subtitle2"
                sx={{
                  width: "20%",
                  fontWeight: "500",
                  color: "#6b7280",
                }}
              >
                Date de création
              </Typography>
              <Typography
                variant="subtitle2"
                sx={{
                  width: "40%",
                  fontWeight: "500",
                  color: "#6b7280",
                }}
              >
                Description
              </Typography>
            </Box>
            <Box
              sx={{
                display: "flex",
                flexDirection: "column",
                alignItems: "center",
                width: "100%",
                padding: "3px",
              }}
            >
              {departments?.map((department) => (
                <Box
                  key={department.id}
                  sx={{
                    cursor: "pointer",
                    color: "black",
                    display: "flex",
                    justifyContent: "space-between",
                    alignItems: "center",
                    padding: "12px",
                    borderRadius: "8px",
                    backgroundColor: "#f0f0fa",
                    border: selectedDepartment?.id === department.id ? "1px solid #746CD4" : "none",
                    marginBottom: "8px",
                    width: "80%",
                  }}
                  onClick={() => setSelectedDepartment(department)}
                >
                  <Box
                    sx={{
                      display: "flex",
                      justifyContent: "space-between",
                      alignItems: "center",
                      width: "100%",
                    }}
                  >
                    <Typography variant="body1" sx={{ width: "20%" }}>
                      {department.name}
                    </Typography>
                    <Typography variant="body1" sx={{ width: "20%" }}>
                      {department.address?.street + " " + department.address?.zipCode + " " + department.address?.city + " " + department.address?.country}
                    </Typography>
                    <Typography variant="body1" sx={{ width: "20%" }}>
                      {dayjs(department.createdAt || '').format('DD-MM-YYYY HH:mm')}
                    </Typography>
                    <Typography variant="body2" sx={{ width: "40%", marginLeft: "5px" }}>
                      {department.description}
                    </Typography>
                  </Box>
                </Box>
              ))}
            </Box>
          </Box>
        </Box>
      ),
    },
  ]

  return (
    <FormContainer >
      <ConditionalComponent isValid={isReadOnly}>
        <EditExportButtons
          onEdit={() => onEdit(agency)}
          tooltipTitle="Agence"
          dataRow={formik.values}
          tableHead={tableHead}
        />
      </ConditionalComponent>

      <form
        onSubmit={formik.handleSubmit}
        style={{
          width: "100%",
          display: "flex",
          flexDirection: "column",
          alignItems: "center",
          marginBottom: isReadOnly ? "0" : "11rem",
        }}
      >
        <Grid
          container
          spacing={2}
          direction="row"
        >
          {mainAgencyFormFields(sectorOptions).map((field) => (
            <Grid item xs={12} sm={4} key={field.name} sx={{ width: "100%" }}>
              {renderField(field)}
            </Grid>
          ))}
        </Grid>

        <ConditionalComponent isValid={mode === "view"}>
          <TabbedForm
            tabs={tabs}
            isTransparent
            sx={{
              fontWeight: "bold",
              color: "#F1F0FB",
              marginTop: "20px",
              width: "100%",
            }}
          />
        </ConditionalComponent>

        <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 AgencyRequest] = true;
                        return acc;
                      }, {} as FormikTouched<AgencyRequest>)
                    );
                  }
                });
              }}
              onCancel={() => onClose(false)}
              mode={mode} />
          </Grid>
        </ConditionalComponent>
      </form>
    </FormContainer>
  )
}