'use client';

import { useState } from 'react';
import { enqueueSnackbar } from 'notistack';
import type { IPassengerList, Representative } from '@/shared/types/passenger';
import type { AddPassengerToCircuit, CircuitAssignmentRequest } from '@/shared/types/circuit';
import { usePassengerStore } from '@/shared/api/stores/passengerStore';
import { usePassengersCircuitStore } from '@/shared/api/stores/circuit-service/passengerscircuitStore';
import type { ModeType } from '@/shared/types/common';

interface UseUsagerSaveProps {
    mode: ModeType;
    originalRepresentatives: Representative[];
    tabId: string;
    markTabAsSaved: (tabId: string, content: IPassengerList) => void;
    setTabReplaceCurrentTab: (tabId: string, replaceCurrentTab: boolean) => void;
}

interface SaveResult {
    success: boolean;
    data?: IPassengerList;
    error?: string;
}

export const useUsagerSave = ({
    mode,
    originalRepresentatives,
    tabId,
    markTabAsSaved,
    setTabReplaceCurrentTab,
}: UseUsagerSaveProps) => {
    const [isSaving, setIsSaving] = useState(false);
    const { addPassenger, updatePassenger } = usePassengerStore();
    const {
        addPassengersToCircuit,
        assignCircuitToRepresentatives,
        cancelCircuitAssignmentForRepresentatives,
    } = usePassengersCircuitStore();

    const isEditMode = mode === 'edit';
    const isAddOrCopyMode = mode === 'add' || mode === 'copy';

    const getCircuitChanges = (
        currentRepresentatives: Representative[],
        originalReps: Representative[]
    ): Representative[] => {
        const changedRepresentatives: Representative[] = [];

        currentRepresentatives.forEach((currentRep) => {
            const originalRep = originalReps.find((orig) => orig.id === currentRep.id);

            if (!originalRep && currentRep.circuitId) {
                changedRepresentatives.push(currentRep);
                return;
            }

            if (originalRep && currentRep.circuitId !== originalRep.circuitId) {
                changedRepresentatives.push(currentRep);
            }
        });

        return changedRepresentatives;
    };

    const handleCircuitAssignment = async (values: IPassengerList): Promise<SaveResult> => {
        const currentRepresentatives = values.representatives || [];
        const changedRepresentatives = getCircuitChanges(
            currentRepresentatives,
            originalRepresentatives
        );

        if (changedRepresentatives.length === 0) {
            return { success: true };
        }

        const representativesWithNewCircuit = changedRepresentatives.filter((rep) => rep.circuitId);

        if (representativesWithNewCircuit.length === 0) {
            return { success: true };
        }

        const passengerIds = [Number(values.id)];

        for (const representative of representativesWithNewCircuit) {
            const circuitId = representative.circuitId;
            if (!circuitId) continue;

            const addPayload: AddPassengerToCircuit = {
                circuitId,
                passengersIds: passengerIds,
            };

            try {
                await addPassengersToCircuit(addPayload);
            } catch (error: any) {
                enqueueSnackbar(
                    error.message || `Échec de l'affectation au circuit ${circuitId}`,
                    { variant: 'error' }
                );
                return {
                    success: false,
                    error: error.message || "Erreur lors de l'affectation au circuit",
                };
            }

            const assignRequest: CircuitAssignmentRequest = {
                passengerIds,
                circuitId,
            };

            try {
                const blockedMessages = await assignCircuitToRepresentatives(assignRequest);

                if (blockedMessages && blockedMessages.length > 0) {
                    try {
                        await cancelCircuitAssignmentForRepresentatives(passengerIds);
                    } catch (rollbackError: any) {
                        enqueueSnackbar(
                            rollbackError.message || `Rollback failed for circuit ${circuitId}:`,
                            { variant: 'error' }
                        );
                    }

                    blockedMessages.forEach((message) => {
                        enqueueSnackbar(message, { variant: 'warning' });
                    });
                    return {
                        success: false,
                        error: `Assignation bloquée: ${blockedMessages}`,
                    };
                }
            } catch (error: any) {
                try {
                    await cancelCircuitAssignmentForRepresentatives(passengerIds);
                } catch (rollbackError: any) {
                    enqueueSnackbar(
                        rollbackError.message || `Rollback failed for circuit ${circuitId}:`,
                        { variant: 'error' }
                    );
                }

                enqueueSnackbar(`Échec de l'assignation du circuit ${circuitId} aux représentants`, {
                    variant: 'error',
                });
                return {
                    success: false,
                    error: error.message || "Erreur lors de l'assignation",
                };
            }
        }

        return { success: true };
    };

    const savePassenger = async (values: IPassengerList): Promise<SaveResult> => {
        if (isEditMode) {
            try {
                await updatePassenger(values);
                return { success: true, data: values };
            } catch (error: any) {
                return {
                    success: false,
                    error: error.message || 'Erreur lors de la modification',
                };
            }
        }

        if (isAddOrCopyMode) {
            try {
                const { id, createdAt, updatedAt, ...valuesWithoutId } = values;
                const result = await addPassenger(valuesWithoutId as IPassengerList);
                return { success: true, data: result };
            } catch (error: any) {
                return {
                    success: false,
                    error: error.message || "Erreur lors de l'ajout",
                };
            }
        }

        return { success: false, error: 'Mode non supporté' };
    };

    const restoreOriginalCircuits = (values: IPassengerList): IPassengerList => {
        return {
            ...values,
            representatives: values.representatives?.map((rep) => {
                const originalRep = originalRepresentatives.find((orig) => orig.id === rep.id);
                return {
                    ...rep,
                    circuitId: originalRep?.circuitId || rep.circuitId,
                };
            }),
        };
    };

    const showSuccessMessage = (circuitAssignmentSuccess: boolean) => {
        if (isEditMode && !circuitAssignmentSuccess) {
            enqueueSnackbar('Passenger sauvegardé avec succès (sans assignation de circuit)', {
                variant: 'success',
            });
        } else if (isEditMode && circuitAssignmentSuccess) {
            enqueueSnackbar('Passenger et circuit sauvegardés avec succès', { variant: 'success' });
        } else {
            enqueueSnackbar('Passenger sauvegardé avec succès', { variant: 'success' });
        }
    };

    const handleFormSubmit = async (
        values: IPassengerList,
        resetForm: (values: IPassengerList) => void
    ): Promise<void> => {
        setIsSaving(true);

        try {
            let circuitAssignmentSuccess = true;
            let valuesToSave = values;

            if (isEditMode) {
                const circuitResult = await handleCircuitAssignment(values);

                if (!circuitResult.success) {
                    circuitAssignmentSuccess = false;
                    valuesToSave = restoreOriginalCircuits(values);
                    enqueueSnackbar(
                        "L'assignation du circuit a échoué, le passenger sera sauvegardé avec les circuits originaux",
                        { variant: 'warning' }
                    );
                }
            }

            const saveResult = await savePassenger(valuesToSave);

            if (!saveResult.success) {
                enqueueSnackbar(saveResult.error || 'Erreur lors de la sauvegarde', { variant: 'error' });
                return;
            }

            const savedPassenger = saveResult.data;
            if (savedPassenger) {
                markTabAsSaved(tabId, savedPassenger);
                resetForm(savedPassenger);
            }

            showSuccessMessage(circuitAssignmentSuccess);

            if (isAddOrCopyMode) {
                setTabReplaceCurrentTab(tabId, true);
            }
        } finally {
            setIsSaving(false);
        }
    };

    return {
        handleFormSubmit,
        isSaving,
    };
};
