import axiosInstance from "@/utils/axios";
import { create } from "zustand";
import { userEndpoints } from "../endpoints/user";
import { IPassengerList, Representative, SearchPassengerParams } from "@/shared/types/passenger";

type PassengerStore = {
    passengers: IPassengerList[];
    passenger: IPassengerList | null;
    loading: boolean;
    error: string | null;
    totalElements: number;
    lastUsedPassengerParams: SearchPassengerParams | null;
    searchPassengers: (params?: SearchPassengerParams, signal?: AbortSignal) => Promise<void>;
    addPassenger: (passenger: IPassengerList) => Promise<IPassengerList>;
    updatePassenger: (passenger: IPassengerList) => Promise<void>;
    toggleArchive: (id: string) => Promise<void>;
    exportPassengers: (params: SearchPassengerParams & { userId: number }) => Promise<string | null>;
    getShortPassengers: (params?: SearchPassengerParams) => Promise<void>;
    getRepresentativesByPassengerId: (passengerId: string) => Promise<Representative[]>;
    getPassengerById: (id: string) => Promise<IPassengerList>;
};

export const usePassengerStore = create<PassengerStore>((set, get) => ({
    passengers: [],
    passenger: null,
    loading: false,
    error: null,
    totalElements: 0,
    lastUsedPassengerParams: null,
    searchPassengers: async (params, externalSignal) => {
        set({ error: null, loading: true, lastUsedPassengerParams: params })

        try {
            const response = await axiosInstance.get(userEndpoints.user.passenger.getAllPassengers, {
                params,
                signal: externalSignal,
            })

            if (!externalSignal?.aborted) {
                const { content, totalElements } = response.data
                set({
                    passengers: content,
                    totalElements,
                    loading: false,
                })
            }
        } catch (error: any) {
            if (error.name !== "CanceledError" && error.code !== "ERR_CANCELED") {
                set({
                    error: error.message || "Failed to search passengers",
                    loading: false,
                })
                throw error
            }
        }
    },

    addPassenger: async (passenger: IPassengerList) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.post(userEndpoints.user.passenger.addPassenger, passenger);
            const { lastUsedPassengerParams, searchPassengers } = get();
            if (lastUsedPassengerParams) {
                await searchPassengers(lastUsedPassengerParams);
            }
            set({ loading: false });
            return response.data;
            } catch (error: any) {
            set({
                error: error.message || 'Failed to add passenger',
                loading: false,
            });
            throw error
        }
    },

    updatePassenger: async (passenger) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.post(userEndpoints.user.passenger.updatePassenger, passenger);
            set((state) => ({
                passengers: state.passengers.map((c) => (c.id === passenger.id ? passenger : c)),
                loading: false,
            }));
        } catch (error: any) {
            set({
                error: error.message || 'Failed to update passenger',
                loading: false,
            });
            throw error
        }
    },

    toggleArchive: async (id: string) => {
        set({ loading: true, error: null });
        try {
            await axiosInstance.post<boolean>(userEndpoints.user.passenger.toggleArchive(id));
            set((state) => ({
                passengers: state.passengers.map((c) => (c.id === id ? { ...c, archived: !c.archived } : c)),
                loading: false,
            }));
        } catch (error: any) {
            set({
                error: error.message || 'Failed to toggle archive',
                loading: false,
            });
            throw error;
        }
    },
    exportPassengers: async (params) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.post<{ ExportPath: string }>(
                userEndpoints.user.passenger.exportPassengers,
                null,
                { params }
            );

            return response.data.ExportPath;
        } catch (error: any) {
            set({ error: error.message || 'Échec de l’export des usagers', loading: false });
            throw error;
        } finally {
            set({ loading: false });
        }
    },

    getShortPassengers: async (params?: SearchPassengerParams) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(userEndpoints.user.passenger.getShortPassengers, {
                params,
            });
            set({
                passengers: response.data.content,
                loading: false,
            });
        } catch (error: any) {
            set({
                error: error.message || 'Failed to fetch short passengers',
                loading: false,
            });
            throw error;
        }
    },
    getRepresentativesByPassengerId: async (passengerId: string) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get<Representative[]>(userEndpoints.user.passenger.getRepresentativesByPassengerId(passengerId));
            return response.data;
        } catch (error: any) {
            set({
                error: error.message || 'Failed to fetch representatives',
                loading: false,
            });
            throw error;
        }
    },
    getPassengerById: async (id: string) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get<IPassengerList>(userEndpoints.user.passenger.getPassengerById(id));
            set({ 
                passenger: response.data,
                loading: false 
            });
            return response.data;
        } catch (error: any) {
            set({
                error: error.message || 'Failed to fetch passenger by ID',
                loading: false,
            });
            throw error;
        }
    }
}));
