import { create } from 'zustand';
import axiosInstance from '@/utils/axios';
import { circuitEndpoints } from '@/shared/api/endpoints/circuit';
import {
    AmendmentPassengerList,
    AmendmentPassengerDetails,
    SearchPassengerAmendmentParams
} from '@/shared/types/ammendment-passenger';
import { Pageable } from '@/shared/types/client';
import { convertAmendmentPayload, convertAmendmentPayloadInverse } from '@/shared/sections/usager/components/usager-form/avenants-horaires/utils/converters';

interface AmendmentPassengerStore {
    amendments: AmendmentPassengerList[];
    totalElements: number;
    amendmentDetails: AmendmentPassengerDetails | null;
    loading: boolean;
    error: string | null;
    lastPassengerAmendmentParams: SearchPassengerAmendmentParams | null;
    fetchAmendments: (params: SearchPassengerAmendmentParams) => Promise<void>;
    getAmendmentById: (id: string) => Promise<AmendmentPassengerDetails | null>;
    addAmendment: (data: Partial<AmendmentPassengerDetails>) => Promise<AmendmentPassengerDetails>;
    updateAmendment: (id: string, data: Partial<AmendmentPassengerDetails>) => Promise<void>;
}

export const useAmendmentPassengerStore = create<AmendmentPassengerStore>((set, get) => ({
    amendments: [],
    totalElements: 0,
    amendmentDetails: null,
    loading: false,
    error: null,
    lastPassengerAmendmentParams: null,

    fetchAmendments: async (params) => {
        set({ loading: true, error: null, lastPassengerAmendmentParams: params });
        try {
            const { data } = await axiosInstance.get<Pageable<AmendmentPassengerList>>(
                circuitEndpoints.circuit.amendmentPassenger.getAllAmendmentsPassenger,
                { params }
            );
            set({ amendments: data.content, totalElements: data.totalElements, loading: false });
        } catch (error: any) {
            set({ error: error.message || 'Erreur lors de la récupération des amendements', loading: false });
        }
    },

    getAmendmentById: async (id) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(
                circuitEndpoints.circuit.amendmentPassenger.getAmendmentPassengerById(id)
            );
            const amendmentDetails = convertAmendmentPayloadInverse(response.data);
            set({ loading: false });
            return amendmentDetails as AmendmentPassengerDetails;
        } catch (error: any) {
            set({ error: error.message || 'Erreur lors de la récupération du détail', loading: false });
            throw error;
            return null;
        }
    },
    addAmendment: async (payload) => {
        set({ loading: true, error: null });
        try {
            const convertedPayload = convertAmendmentPayload(payload);
            const response = await axiosInstance.post(
                circuitEndpoints.circuit.amendmentPassenger.addAmendmentPassenger,
                convertedPayload
            );
            const amendment = convertAmendmentPayloadInverse(response.data);
            const { lastPassengerAmendmentParams, fetchAmendments } = get();
            if (lastPassengerAmendmentParams) {
                await fetchAmendments(lastPassengerAmendmentParams);
            }
            set({ loading: false });
            return amendment as AmendmentPassengerDetails;
        } catch (error: any) {
            set({ error: error.message || 'Erreur lors de l\'ajout de l\'amendement', loading: false });
            throw error;
        }
    },

    updateAmendment: async (id: string, payload) => {
        set({ loading: true, error: null });
        try {
            const convertedPayload = convertAmendmentPayload(payload);            
            await axiosInstance.put(
                circuitEndpoints.circuit.amendmentPassenger.updateAmendmentPassenger(id),
                convertedPayload
            );
            set({ loading: false });
        } catch (error: any) {
            set({ error: error.message || 'Erreur lors de la mise à jour de l\'amendement', loading: false });
            throw error;
        }
    },
}));
