'use client';

import { Grid, Box, CircularProgress, Typography } from '@mui/material';
import { useFormik, FormikProvider } from 'formik';
import FormField from '@/shared/components/form/form-field';
import type { FormFieldType, ModeType, TableColumn } from '@/shared/types/common';
import TabbedForm from '@/shared/components/tabs/tabbed-form';
import FormContainer from '@/layouts/form/form-container';
import { mainEtabformFields } from '../utils/form-fields-establishment';
import { EmptyPlaceholder } from '@/shared/components/column-selector/column-container';
import EtablissementVacanceForm from '../components/establishment-vacance';
import ConditionalComponent from '@/shared/components/table/ConditionalComponent';
import { useEffect, useState } from 'react';
import { establishmentSchema } from '../utils/validation-schema-establishment';
import { EstablishmentRequest, EstablishmentTableItem, mapEstablishmentToEstablishmentRequest } from '@/shared/types/establishment';
import { useEstablishmentStore } from '@/shared/api/stores/admin-service/establishmentStore';
import { useInfrastructureStore } from '@/shared/api/stores/admin-service/infrastructureStore';
import EstablishmentDetailsForm from '../components/establishment-details';
import EstablishmentHoursForm from '../components/establishment-hours-form';
import { useZoneStore } from '@/shared/api/stores/admin-service/zoneStore';
import { useSnackbar } from 'notistack';
import { getFormatedAddress } from '@/shared/sections/admin-config/infrastructure/utils/address-utils';

interface EstablishmentFormProps {
  etablissement: EstablishmentTableItem;
  mode: ModeType;
  onSave: (updated: EstablishmentRequest) => void;
  onEdit: (updated: EstablishmentRequest) => void;
  onClose: (forceClose: boolean) => void;
  tableHead: TableColumn[];
  updateTabContent?: (tabId: string, newContent: EstablishmentRequest) => void
  tabId?: string
}

export default function EstablishmentForm({
  etablissement,
  mode,
  onSave,
  onClose,
  onEdit,
  tableHead,
  updateTabContent,
  tabId,
}: EstablishmentFormProps) {
  const { enqueueSnackbar } = useSnackbar();

  const { getEstablishmentById, establishmentById, loading, error, createEstablishment, updateEstablishment } = useEstablishmentStore();
  const { fetchDepartmentNames, departmentNames } = useInfrastructureStore();
  const { fetchZoneNames, zoneNames } = useZoneStore();

  const [establishmentData, setEstablishmentData] = useState<EstablishmentRequest>({} as EstablishmentRequest);
  const [zoneOptions, setZoneOptions] = useState<{ label: string, value: string }[]>([]);
  const [departmentOptions, setDepartmentOptions] = useState<{ label: string, value: string }[]>([]);

  const getInitialValues = async () => {
    await fetchDepartmentNames();
    await fetchZoneNames();
    if (etablissement.id) {
      await getEstablishmentById(etablissement.id);
    }
  }

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

  useEffect(() => {
    if (departmentNames) {
      setDepartmentOptions(departmentNames.map((department) => ({ label: department.name, value: department.id.toString() })));
    }
    if (establishmentById) {
      setEstablishmentData(mapEstablishmentToEstablishmentRequest(establishmentById));
    }
    if (zoneNames) {
      setZoneOptions(zoneNames.map((zone) => ({ label: zone.name, value: zone.id.toString() })));
    }
  }, [departmentNames, establishmentById, zoneNames]);

  const handleFormSubmit = (values: EstablishmentRequest) => {
    const request = {
      ...values,
      address: getFormatedAddress(values.mapAddress)
    };
    if (mode === 'edit') {
      try {
        updateEstablishment(etablissement.id, request);
        onClose(true);
        enqueueSnackbar('Etablissement modifié avec succès', { variant: 'success' });
      } catch (error: any) {
        enqueueSnackbar(error.message, { variant: 'error' });
        return;
      }
    } else if (mode === 'add' || mode === 'copy') {
      try {
        createEstablishment(request);
        onClose(true);
        enqueueSnackbar('Etablissement créé avec succès', { variant: 'success' });
      } catch (error: any) {
        enqueueSnackbar(error.message, { variant: 'error' });
        return;
      }
    }
  };

  const formik = useFormik<EstablishmentRequest>({
    initialValues: establishmentData,
    validationSchema: establishmentSchema,
    enableReinitialize: true,
    onSubmit: handleFormSubmit,
  });

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

  const isReadOnly = mode === 'view';
  const isAddMode = mode === 'add';

  const renderField = (field: FormFieldType<EstablishmentRequest>) => {
    const error = formik.touched[field.name] && formik.errors[field.name];
    return (
      <FormField
        field={field}
        value={
          field.name === 'zoneId' ? String(formik.values[field.name as keyof EstablishmentRequest]) :
            field.name === 'departmentId' ? String(formik.values[field.name as keyof EstablishmentRequest]) :
              formik.values[field.name]
        }
        onChange={(name, value) => formik.setFieldValue(name, value)}
        error={error ?
          field.name === "mapAddress" ? formik.errors.mapAddress?.["address"]
            :
            String(formik.errors[field.name])
          : undefined}
        isReadOnly={isReadOnly}
        onBlur={formik.handleBlur}
      />
    );
  };

  const tabs = [
    {
      label: 'Coordonnée',
      content: (
        <EstablishmentDetailsForm
          renderField={renderField}
          mode={mode}
          onEdit={() => onEdit(formik.values)}
          onClose={() => onClose(false)}
          etablissement={formik.values}
          tableHead={tableHead}
          zoneOptions={zoneOptions}
          departmentOptions={departmentOptions}
        />
      ),
    },
    {
      label: 'Horaires',
      content: (
        <EstablishmentHoursForm
          onEdit={() => onEdit(formik.values)}
          onClose={() => onClose(false)}
          mode={mode}
          formik={formik}
        />
      ),
    },
    {
      label: 'Vacance',
      content: (
        <ConditionalComponent
          isValid={isAddMode || mode === 'copy'}
          defaultComponent={<EtablissementVacanceForm />}
        >
          <EmptyPlaceholder text="Les vacances peuvent être saisies une fois que vous avez enregistré la fiche." />
        </ConditionalComponent>
      )
    },
  ];

  if (loading) {
    return <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>
      <CircularProgress />
    </Box>
  }

  if (error) {
    return <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>
      <Typography>Une erreur est survenue lors de la récupération des données. Veuillez réessayer plus tard.</Typography>
    </Box>
  }

  return (
    <FormikProvider value={formik}>
      <FormContainer titre="Fiche d'un établissement">
        <form onSubmit={formik.handleSubmit}>
          <Grid container spacing={5}>
            {mainEtabformFields().map((etablissement) => (
              <Grid
                item
                xs={12}
                sm={etablissement.name === 'uaiCode' ? 4 : 8}
                key={etablissement.name}
              >
                {renderField(etablissement)}
              </Grid>
            ))}
          </Grid>
          <TabbedForm tabs={tabs} sx={{ mt: 4 }} />
        </form>
      </FormContainer>
    </FormikProvider>
  );
}