'use client';

import { useEffect, useState } from 'react';
import { Typography, Grid, Box } from '@mui/material';
import { useFormik, FormikProvider } from 'formik';
import { centerFlexColumn } from '@/shared/theme/css';
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 TabbedForm from '@/shared/components/tabs/tabbed-form';
import UsagerTabForm from '../components/usager-form/usager-form';
import DepotDocumentForm from '../components/usager-form/depot-document';
import AutresInterlocuteursForm from '../components/usager-form/autres-interlocuteurs';
import SuiviDossierForm from '../components/usager-form/suivi-dossier';
import RepresentantTabs from '../components/usager-form/representant/representant-tabs';
import AvenantsHorairesList from '../components/usager-form/avenants-horaires/avenants-horaires-list';
import { usagerSchema } from '../utils/usager-validation';
import type { IPassengerList, Representative } from '@/shared/types/passenger';
import { calculateAge, mainPassengerFormFields } from '../utils/form-fields-usager';
import { usePassengerStore } from '@/shared/api/stores/passengerStore';
import { useUsagerSave } from '../hooks/use-usager-save';
import { useAmendmentPassengerStore } from '@/shared/api/stores/circuit-service/amendmentPassengerStore';
import { enqueueSnackbar } from 'notistack';
import { WeekSchedule } from '@/shared/components/form/etablissement-jours-field';
import { convertWeekSchedules } from '../../trajet/utils/schedulesTransformationUtils';

interface TrajetFormProps {
  usager: IPassengerList;
  mode: ModeType;
  originalRepresentatives: Representative[];
  onEdit: (updatedUsager: IPassengerList, replaceCurrentTab?: boolean) => void;
  onClose: (isSaved: boolean) => void;
  tableHead: TableColumn[];
  updateTabContent: (tabId: string, content: IPassengerList) => void;
  tabId: string;
  hasUnsavedChanges?: boolean;
  markTabAsSaved: (tabId: string, content: IPassengerList) => void;
  setTabReplaceCurrentTab: (tabId: string, replaceCurrentTab: boolean) => void;
}
export interface RenderFieldOptions {
  onAddInfrastructure?: () => void;
  onAddEstablishment?: () => void;
}

export default function UsagerForm({
  usager,
  mode,
  onClose,
  onEdit,
  tableHead,
  updateTabContent,
  tabId,
  hasUnsavedChanges,
  markTabAsSaved,
  setTabReplaceCurrentTab,
  originalRepresentatives,
}: TrajetFormProps) {
  const isReadOnly = mode === 'view';
  const isEditMode = mode === 'edit';
  const isAddMode = mode === 'add';

  const [sharedSchedules, setSharedSchedules] = useState<WeekSchedule[]>([]);

  const [trajectorySchedules, setTrajectorySchedules] = useState<{
    pair: { [key: string]: { all: boolean; ret: boolean } };
    impair: { [key: string]: { all: boolean; ret: boolean } };
  }>({
    pair: {},
    impair: {},
  });

  const { loading } = usePassengerStore();

  const { isPassengerAttachedToACertainAmendment } = useAmendmentPassengerStore();

  const [isUsagerAttachedToAmendment, setIsUsagerAttachedToAmendment] = useState<boolean>(false);

  const { handleFormSubmit, isSaving } = useUsagerSave({
    mode,
    originalRepresentatives,
    tabId,
    markTabAsSaved,
    setTabReplaceCurrentTab,
  });

  const formik = useFormik<IPassengerList>({
    initialValues: usager,
    enableReinitialize: true,
    validationSchema: usagerSchema,
    onSubmit: (values) => {
      handleFormSubmit(values, (newValues) => {
        formik.resetForm({ values: newValues });
      });
    },
  });

  const handleEdit = () => {
    onEdit(formik.values);
  };

  const handleSave = () => {
    formik.validateForm().then(() => {
      formik.submitForm();
    });
  };

  const handleCancel = () => {
    onClose(false);
  };

  useEffect(() => {
    if (formik.dirty && !hasUnsavedChanges) {
      formik.resetForm();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [hasUnsavedChanges]);

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

      return () => {
        clearTimeout(timer);
      };
    }
  }, [formik.values, updateTabContent, tabId, isReadOnly]);

  useEffect(() => {
    setTrajectorySchedules(convertWeekSchedules(sharedSchedules));
  }, [sharedSchedules]);

  const renderField = (field: FormFieldType<IPassengerList>, options?: RenderFieldOptions) => {
    const error = formik.touched[field.name] && formik.errors[field.name];

    return (
      <FormField
        field={field}
        value={
          field.name === 'idDepartment'
            ? String(formik.values[field.name])
            : formik.values[field.name]
        }
        onChange={(name, value) => {
          formik.setFieldValue(name, value);
          if (name === 'birthDate') {
            formik.setFieldValue('age', calculateAge(value) || 0);
          }
        }}
        error={error ? String(formik.errors[field.name]) : undefined}
        isReadOnly={
          field.name === 'startTransport' && (isUsagerAttachedToAmendment as boolean) && isEditMode
            ? true
            : loading || isSaving || isReadOnly
        }
        onBlur={formik.handleBlur}
        onAddInfrastructure={options?.onAddInfrastructure}
        onAddEstablishment={options?.onAddEstablishment}
      />
    );
  };

  useEffect(() => {
    if (isEditMode) {
      const checkUsagerAttachedToAnAmendment = async (id: string): Promise<boolean> => {
        const resp = await isPassengerAttachedToACertainAmendment(id);
        if (resp === 'attached') return true;
        if (resp === 'unattached') return false;

        enqueueSnackbar(resp, { variant: 'error' });
        return false;
      };

      const fetchData = async () => {
        try {
          const witness = await checkUsagerAttachedToAnAmendment(usager.id);
          setIsUsagerAttachedToAmendment(witness);
        } catch (error: any) {
          enqueueSnackbar(error.message, { variant: 'error' });
        }
      };

      fetchData();
    }
  }, [usager.id]);

  const tabs = [
    {
      label: 'Usagers',
      content: (
        <UsagerTabForm
          setSharedSchedules={setSharedSchedules}
          renderField={renderField}
          mode={mode}
          usager={usager}
          onEdit={handleEdit}
          onClose={handleCancel}
          handleSave={handleSave}
          tableHead={tableHead}
          loading={loading || isSaving}
          isUsagerAttachedToAmendment={isUsagerAttachedToAmendment}
        />
      ),
    },
    {
      label: 'Représentant, Adresses et Circuits',
      content: (
        <RepresentantTabs
          trajectorySchedules={trajectorySchedules}
          withContact
          onSave={handleSave}
          loading={loading || isSaving}
          onClose={handleCancel}
          onEdit={handleEdit}
          mode={mode}
          isUsagerAttachedToAmendment={isUsagerAttachedToAmendment}
        />
      ),
    },
    {
      label: 'Depot de documents',
      content: <DepotDocumentForm idUser={formik.values.id} />,
      disabled: isAddMode,
    },
    {
      label: 'Avenants horaires',
      content: <AvenantsHorairesList key={formik.values.id} usager={usager} />,
      disabled: isAddMode,
    },
    {
      label: 'Autres interlocuteurs',
      content: (
        <AutresInterlocuteursForm
          mode={mode}
          onEdit={handleEdit}
          onSave={handleSave}
          onCancel={handleCancel}
          loading={loading || isSaving}
        />
      ),
    },
    {
      label: 'Suivi de dossier',
      content: <SuiviDossierForm usager={usager} />,
    },
  ];

  return (
    <FormContainer titre="Fiche Usager">
      <FormikProvider value={formik}>
        <form onSubmit={formik.handleSubmit}>
          <Grid container spacing={4} sx={{ width: '100%' }}>
            {mainPassengerFormFields.map((field) => (
              <Grid
                item
                sx={centerFlexColumn}
                xs={12}
                sm={field.name === 'civility' ? 3.2 : 3.5}
                key={field.name}
              >
                {renderField(field)}
              </Grid>
            ))}
            <Grid sx={centerFlexColumn} item xs={12} sm={1.8}>
              <Box display="flex" alignItems="center" gap={1}>
                <Typography sx={{ color: (theme) => theme.palette.primary.main }}>Age</Typography>
                <Typography>{formik.values.age ? `${formik.values.age} ans` : '-'}</Typography>
              </Box>
            </Grid>
          </Grid>
          <TabbedForm tabs={tabs} sx={{ mt: 4 }} showNavigationButtons />
        </form>
      </FormikProvider>
    </FormContainer>
  );
}
