'use client';

import React, { useEffect, useState } from 'react';
import {
  Radio,
  RadioGroup,
  FormControlLabel,
  Typography,
  Grid,
  Box,
  FormHelperText,
  CircularProgress,
  Alert,
} from '@mui/material';
import {
  faFileArrowUp,
} from '@fortawesome/free-solid-svg-icons';
import { formFields } from '../utils/form-fields-contract';
import FontAwesome from '@/shared/components/fontawesome';
import FormField from '@/shared/components/form/form-field';
import { FormFieldType, ModeType, TableColumn, TableType } from '@/shared/types/common';
import { AddButton } from '@/shared/components/table/styles';
import EditExportButtons from '@/shared/components/form/edit-export-buttons';
import ActionButtons from '@/shared/components/form/buttons-action';
import { CONTRACT_STATUS, ContractList, ContractRequest, mapContractToRequest } from '@/shared/types/contract';
import { FormikTouched, useFormik } from 'formik';
import { contractSchema } from '../utils/contract-validation';
import FormContainer from '@/layouts/form/form-container';
import ConditionalComponent from '../../../components/table/ConditionalComponent';
import { useContractStore } from '@/shared/api/stores/admin-service/contractStore';
import { useInfrastructureStore } from '@/shared/api/stores/admin-service/infrastructureStore';
import { AgencyNames, DepartmentNames, LotNumbers } from '@/shared/types/infrastructure';
import { useSnackbar } from 'notistack';
import ContratCircuitsTable from '../components/contrat-circuits-table';
interface ContractFormProps {
  contrat: ContractList;
  mode: ModeType;
  onEdit: (updatedContract: ContractRequest) => void;
  onClose: (isSaved: boolean) => void;
  tableHead: TableColumn[];
  updateTabContent?: (tabId: string, newContent: ContractRequest) => void
  tabId?: string
}

export default function ContractForm({
  contrat,
  mode,
  onClose,
  onEdit,
  tableHead,
  updateTabContent,
  tabId,
}: ContractFormProps) {
  const isReadOnly = mode === 'view';
  const { enqueueSnackbar } = useSnackbar();

  const { getContractById, loading, error, createContract, updateContract } = useContractStore();

  const {
    agencyNames,
    departmentNamesByAgencyId,
    lotNumbersByDepartmentId,
    fetchAgencyNames,
    fetchDepartmentNamesByAgencyId,
    fetchLotNumbersByDepartmentId,
  } = useInfrastructureStore();

  const [selectedAgencyId, setSelectedAgencyId] = useState<number>();
  const [selectedDepartmentId, setSelectedDepartmentId] = useState<number>();

  const [initialValues, setInitialValues] = useState<ContractRequest>({} as ContractRequest);
  const [agencyOptions, setAgencyOptions] = useState<{ value: string; label: string }[]>([]);
  const [departmentOptions, setDepartmentOptions] = useState<{ value: string; label: string }[]>([]);
  const [lotOptions, setLotOptions] = useState<{ value: string; label: string }[]>([]);

  const getAgencyNames = async () => {
    await fetchAgencyNames();
  }

  const getInitialValues = async () => {
    const contract = await getContractById(contrat.id);
    if (contract) {
      if (contract.agencyId) {
        await fetchDepartmentNamesByAgencyId(contract.agencyId);
      }
      if (contract.departmentId) {
        await fetchLotNumbersByDepartmentId(contract.departmentId);
      }
      setInitialValues(mapContractToRequest(contract));
    }
  }

  useEffect(() => {
    getAgencyNames();
    if (contrat.id) {
      getInitialValues();
    }
  }, []);

  useEffect(() => {
    if (selectedAgencyId) {
      fetchDepartmentNamesByAgencyId(selectedAgencyId);
    } else if (!selectedAgencyId) {
      setDepartmentOptions([]);
      setLotOptions([]);
    }
  }, [selectedAgencyId]);

  useEffect(() => {
    if (selectedDepartmentId) {
      fetchLotNumbersByDepartmentId(selectedDepartmentId);
    } else if (!selectedDepartmentId) {
      setLotOptions([]);
    }
  }, [selectedDepartmentId]);

  useEffect(() => {
    if (agencyNames.length > 0) {
      setAgencyOptions(agencyNames.map((agency: AgencyNames) => ({
        value: String(agency.id),
        label: agency.name
      })));
    }
  }, [agencyNames, initialValues]);

  useEffect(() => {
    if (departmentNamesByAgencyId.length > 0) {
      setDepartmentOptions(departmentNamesByAgencyId.map((department: DepartmentNames) => ({
        value: String(department.id),
        label: department.name
      })));
    }
  }, [departmentNamesByAgencyId, initialValues]);

  useEffect(() => {
    if (lotNumbersByDepartmentId.length > 0) {
      setLotOptions(lotNumbersByDepartmentId.map((lot: LotNumbers) => ({
        value: String(lot.id),
        label: lot.number
      })));
    }
  }, [lotNumbersByDepartmentId, initialValues]);

  const handleFormSubmit = (values: ContractRequest) => {
    if (mode === 'edit') {
      try {
        updateContract(contrat.id, values);
        onClose(true);
        enqueueSnackbar('Contrat modifié avec succès', { variant: 'success' });
      } catch (error: any) {
        enqueueSnackbar(error.message, { variant: 'error' });
        return;
      }
    } else if (mode === 'add' || mode === 'copy') {
      try {
        createContract(values);
        onClose(true);
        enqueueSnackbar('Contrat créé avec succès', { variant: 'success' });
      } catch (error: any) {
        enqueueSnackbar(error.message, { variant: 'error' });
        return;
      }
    }
  };

  const formik = useFormik<ContractRequest>({
    initialValues: initialValues,
    validationSchema: contractSchema,
    enableReinitialize: true,
    onSubmit: handleFormSubmit
  });
  useEffect(() => {
    if (updateTabContent && tabId && (mode !== "view")) {
      updateTabContent(tabId, formik.values)
    }
  }, [formik.values, updateTabContent, tabId, mode])

  const renderField = (field: FormFieldType<ContractRequest>) => {
    const handleChange = (name: string, value: any) => {
      formik.setFieldValue(name, value);
  
      if (name === 'agencyId' && setSelectedAgencyId) {
        setSelectedAgencyId(value);
      }
  
      if (name === 'departmentId' && setSelectedDepartmentId) {
        setSelectedDepartmentId(value);
      }
    };

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

  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%' }}>
      <Alert severity="error">Erreur lors de la récupération des données. Veuillez réessayer plus tard.</Alert>
    </Box>);
  }

  return (
    <FormContainer titre="Fiche Contrat">
      {isReadOnly ? (
        <EditExportButtons
          onEdit={() => onEdit(formik.values)}
          tooltipTitle={TableType.Contrat}
          dataRow={contrat}
          tableHead={tableHead}
        />
      ) : (
        <></>
      )}
      <form onSubmit={formik.handleSubmit}>
        <Grid container spacing={5} >
          {formFields(agencyOptions, departmentOptions, lotOptions).map((field) => (
            <Grid item xs={12} sm={4} key={field.name}>
              {renderField(field)}
            </Grid>
          ))}

          {/* Document section */}
          <Grid item xs={12}>
            <Box display="flex" alignItems="center" gap={4}>
              <Typography sx={{ color: isReadOnly ? "text.disabled" : "primary.main" }}>
                Le bon de commande
              </Typography>
              <AddButton
                variant="contained"
                sx={{ minHeight: '43px' }}
                endIcon={<FontAwesome icon={faFileArrowUp} width={18} />}
                disabled={isReadOnly}
              >
                Importez un document
              </AddButton>
              <Typography sx={{ color: isReadOnly ? "text.disabled" : "primary.main" }}>
                Statut
              </Typography>
              <div>
                <RadioGroup
                  row
                  name="status"
                  value={formik.values.status || ''}
                  onChange={formik.handleChange}
                  onBlur={formik.handleBlur}
                >
                  {CONTRACT_STATUS.map((option) => (
                    <FormControlLabel
                      key={option.value}
                      value={option.value}
                      control={<Radio />}
                      label={option.label}
                      disabled={isReadOnly}
                      sx={{
                        '& .MuiFormControlLabel-label': {
                          color: formik.values.status === option.value ? 'primary.main' : 'inherit',
                        },
                      }}
                    />
                  ))}
                </RadioGroup>
                <ConditionalComponent isValid={!!(formik.touched.status && formik.errors.status)}>
                  <FormHelperText error>{formik.errors.status}</FormHelperText>
                </ConditionalComponent>
              </div>
            </Box>
          </Grid>

          {!isReadOnly ? (
            <Grid item xs={12}>
              <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 ContractRequest] = true;
                          return acc;
                        }, {} as FormikTouched<ContractRequest>)
                      );
                    }
                  });
                }}
                onCancel={() => {
                  onClose(false);
                }}
                mode={mode}
              />
            </Grid>) : <></>}
        </Grid>
      </form>
      {isReadOnly ? <ContratCircuitsTable></ContratCircuitsTable> : <></>}
    </FormContainer>
  );
}
