import React, { useCallback, useEffect, useRef, useState } from 'react';
import { Box, FormHelperText, Grid, Typography } from '@mui/material';
import { FormikTouched, useFormik } from 'formik';
import FormField from '@/shared/components/form/form-field';
import type { FormFieldType, ModeType } from '@/shared/types/common';
import FormContainer from '@/layouts/form/form-container';
import ActionButtons from '@/shared/components/form/buttons-action';
import ConditionalComponent from '@/shared/components/table/ConditionalComponent';
import EditExportButtons from '@/shared/components/form/edit-export-buttons';
import { interventionFormFields } from '../utils/form-fields-service-provider';
import { Intervention, InterventionType } from '@/shared/types/fleet-management/service-provider';
import { interventionSchema } from '../utils/service-provider-schema';
import { useSnackbar } from 'notistack';
import { useInterventionStore } from '@/shared/api/stores/fleet-service/intervention-store';

interface InterventionNewViewProps {
    intervention: Intervention;
    mode: ModeType;
    onSave: (updated: Intervention) => void;
    onEdit: (updated: Intervention) => void;
    onClose: (isSaved: boolean) => void;
    updateTabContent?: (tabId: string, newContent: Intervention) => void;
    tabId?: string;
}

export default function InterventionNewView({ intervention, mode, onSave, onClose, onEdit, updateTabContent, tabId }: InterventionNewViewProps) {

    const { enqueueSnackbar } = useSnackbar();

    const isReadOnly = mode === 'view';

    const [nameAvailability, setNameAvailability] = useState<{ message: string; isAvailable: boolean } | null>(null);

    const {
        existsByNameLoading,
        createIntervention,
        updateIntervention,
        existsByName,
    } = useInterventionStore();

    const handleFormSubmit = async (values: Intervention) => {
        if (nameAvailability != null && !nameAvailability.isAvailable) {
            enqueueSnackbar('Veuillez entrer un nom valide !', { variant: 'error' });
            return;
        }
        if (mode === 'edit') {
            try {
                await updateIntervention(intervention.id, values);
                onClose(true);
                enqueueSnackbar('Intevention modifié avec succès', { variant: 'success' });
            } catch (error: any) {
                enqueueSnackbar(error.message, { variant: 'error' });
                return;
            }
        } else if (mode === 'add' || mode === 'copy') {
            try {
                await createIntervention(values);
                onClose(true);
                enqueueSnackbar('Intevention créé avec succès', { variant: 'success' });
            } catch (error: any) {
                enqueueSnackbar(error.message, { variant: 'error' });
                return;
            }
        }
    };

    const formik = useFormik<Intervention>({
        initialValues: intervention,
        validationSchema: interventionSchema,
        onSubmit: handleFormSubmit,
        enableReinitialize: true
    });

    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 verifyCode = async () => {
                try {
                    const exists = mode === 'edit'
                        ? await existsByName(trimmedName, Number(intervention.id))
                        : await existsByName(trimmedName);

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

            verifyCode();
        }, 500);
    }, [mode, intervention.id, existsByName]);

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

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

    const renderField = (field: FormFieldType<Intervention>) => {
        if (field.name === 'customInterventionType' && formik.values.customInterventionType !== InterventionType.OTHER) {
            return null;
        }

        const handleChange = (name: string, value: any) => {
            formik.setFieldValue(name, value);
            if (name === 'name') {
                checkName(value);
            }
        };

        return (
            <>
                <FormField
                    field={field}
                    value={formik.values[field.name as keyof Intervention]}
                    onChange={handleChange}
                    error={
                        Boolean(formik.touched[field.name as keyof Intervention]) &&
                            formik.errors[field.name as keyof Intervention]
                            ? String(formik.errors[field.name as keyof Intervention])
                            : undefined
                    }
                    onBlur={formik.handleBlur}
                    isReadOnly={isReadOnly}
                />
                <ConditionalComponent isValid={field.name === 'name'}>
                    <FormHelperText
                        sx={{
                            color: existsByNameLoading ? 'text.secondary' : (nameAvailability?.isAvailable ? 'success.main' : 'error.main'),
                            marginTop: '4px',
                            display: 'flex',
                            alignItems: 'center'
                        }}
                    >
                        <ConditionalComponent isValid={existsByNameLoading}>
                            <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={!existsByNameLoading}>
                            {nameAvailability?.message}
                        </ConditionalComponent>
                    </FormHelperText>
                </ConditionalComponent>
            </>
        );
    };

    return (
        <FormContainer titre="Intervention" hasBorder isSousElemnt>
            <ConditionalComponent isValid={isReadOnly}>
                <EditExportButtons
                    onEdit={() => onEdit(intervention)}
                    tooltipTitle="l'intervention"
                />
            </ConditionalComponent>
            <form onSubmit={formik.handleSubmit}>
                <Grid container spacing={5}>
                    {interventionFormFields.map((field) => (
                        <Grid item xs={12} sm={6} key={field.name}>
                            {renderField(field)}
                        </Grid>
                    ))}
                    <ConditionalComponent isValid={!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 Intervention] = true;
                                                    return acc;
                                                }, {} as FormikTouched<Intervention>)
                                            );
                                        }
                                    });
                                }}
                                onCancel={() => {
                                    onClose(false);
                                }}
                                mode={mode}
                            />
                        </Grid>
                    </ConditionalComponent>
                </Grid>
            </form>
        </FormContainer>
    );
}