'use client';

import { useState, useEffect, useMemo, useCallback } from 'react';
import { debounce } from '@mui/material';
import { enqueueSnackbar } from 'notistack';
import { useDriverStore } from '@/shared/api/stores/driverStore';
import { useContractStore } from '@/shared/api/stores/admin-service/contractStore';
import type { ShortContract } from '@/shared/types/contract';
import { Option } from '../utils/form-fields-circuit';

interface UseCircuitFormOptionsReturn {
    driverOptions: Option[];
    contractOptions: Option[];
    lotOptions: Option[];
    searchContracts: (query?: string) => void;
    isLoading: boolean;
    updateLotOptions: (contractId: number, existingLotIds?: string[]) => { colorCode: string; lotNumber: any } | null;
}

export function useCircuitFormOptions(): UseCircuitFormOptionsReturn {
    const { searchContractByTitle, loading: loadingContract } = useContractStore();
    const { getActiveDrivers, loading: loadingDriver } = useDriverStore();

    const [driverOptions, setDriverOptions] = useState<Option[]>([]);
    const [contractOptions, setContractOptions] = useState<Option[]>([]);
    const [lotOptions, setLotOptions] = useState<Option[]>([]);
    const [searchedContracts, setSearchedContracts] = useState<ShortContract[]>([]);
    const [isInitialized, setIsInitialized] = useState(false);
    const isLoading = loadingContract || loadingDriver;


    const memoizedContractOptions = useMemo(
        () =>
            searchedContracts.map((contract) => ({
                value: contract.id.toString(),
                label: contract.title,
            })),
        [searchedContracts]
    );
    const loadAllContracts = useCallback(async () => {
        try {
            const contracts = await searchContractByTitle(null)
            setSearchedContracts(contracts)
        } catch (error) {
            enqueueSnackbar("Erreur lors du chargement des contrats", {
                variant: "error",
            });
        }
    }, [searchContractByTitle]);

    useEffect(() => {
        let isMounted = true;

        const initializeData = async () => {
            try {
                const results = await Promise.all([
                    getActiveDrivers(),
                    loadAllContracts(),
                ]);

                if (!isMounted) return;

                if (results[0]) {
                    setDriverOptions(
                        results[0].map((driver) => ({
                            value: driver.id.toString(),
                            label: driver.name,
                        }))
                    );
                }

                setIsInitialized(true);
            } catch (error: any) {
                enqueueSnackbar(error.message || 'Erreur de chargement', {
                    variant: 'error',
                });
            }
        };

        if (!isInitialized) {
            initializeData();
        }

        return () => {
            isMounted = false;
        };
    }, [isInitialized, getActiveDrivers, loadAllContracts]);

    useEffect(() => {
        setContractOptions(memoizedContractOptions);
    }, [memoizedContractOptions]);

    const getContracts = useCallback(
        async (query?: string) => {
            try {
                const contracts = await searchContractByTitle(query || null);
                setSearchedContracts(contracts);
            } catch (error) {
                enqueueSnackbar('Erreur lors de la recherche des contrats', {
                    variant: 'error',
                });
            }
        },
        [searchContractByTitle]
    );

    const searchContracts = useMemo(() => debounce(getContracts, 300), [getContracts]);

    const updateLotOptions = useCallback(
        (contractId: number): { colorCode: string; lotNumber: any } | null => {
            if (!contractId || searchedContracts.length === 0) {
                setLotOptions([]);
                return null;
            }

            const selectedContract = searchedContracts.find(
                (contract) => contract.id.toString() === contractId.toString()
            );
            if (selectedContract) {
                const newLotOptions = selectedContract.lotsNumber && selectedContract.lotsId
                    ? selectedContract.lotsNumber.map((lotNumber, index) => ({
                            value: selectedContract.lotsId[index]?.toString() || '',
                            label: lotNumber,
                        }))
                    : [];

                setLotOptions(newLotOptions);

                return {
                    colorCode: selectedContract.contractColor,
                    lotNumber: selectedContract.lotsId,
                };
            }

            return null;
        },
        [searchedContracts]
    );

    return {
        driverOptions,
        contractOptions,
        lotOptions,
        searchContracts,
        isLoading,
        updateLotOptions,
    };
}
