import axiosInstance from "@/utils/axios";
import { create } from "zustand";
import { circuitEndpoints } from "../../endpoints/circuit";
import { Circuit, CircuitState, SaveCircuit, SearchCircuitParams } from "@/shared/types/circuit";

export interface CircuitAutocompleteResponse {
    id: string;
    circuitCode: string;
  }
type CircuitStore = {
    circuits: Circuit[];
    circuit: Circuit | null;
    loading: boolean;
    generateTripsLoading: boolean;
    error: string | null;
    totalElements: number;
    lastUsedCircuitParams: SearchCircuitParams | null;
    searchCircuit: (params?: SearchCircuitParams, signal?: AbortSignal) => Promise<void>;
    addCircuit: (circuit: SaveCircuit) => Promise<void>;
    updateCircuit: (circuit: Circuit) => Promise<void>;
    toggleActive: (circuitCode: string) => Promise<void>;
    updateCircuitStatus: (id: string, circuitState: CircuitState) => Promise<void>;
    autocompleteCircuits: (circuitCode?: string) => Promise<CircuitAutocompleteResponse[]>;
    generateTrips: (circuitId: string) => Promise<void>;
};

export const useCircuitStore = create<CircuitStore>((set, get) => ({
    circuits: [],
    circuit: null,
    loading: false,
    generateTripsLoading: false,
    error: null,
    totalElements: 0,
    lastUsedCircuitParams: null,
    searchCircuit: async (params, externalSignal) => {
        set({ error: null, loading: true, lastUsedCircuitParams: params });

        try {
            const response = await axiosInstance.get(circuitEndpoints.circuit.search, {
                params,
                signal: externalSignal,
            });

            if (!externalSignal?.aborted) {
                const { content, totalElements } = response.data;
                set({
                    circuits: content,
                    totalElements,
                    loading: false,
                });
            }
        } catch (error: any) {
            if (error.name !== "CanceledError" && error.code !== "ERR_CANCELED") {
                set({
                    error: error.message || "Erreur lors de la recherche des circuits",
                    loading: false,
                });
                throw error;
            }
        }
    },
    addCircuit: async (circuit: SaveCircuit) => {
        set({ loading: true, error: null });
        try {
            await axiosInstance.post(circuitEndpoints.circuit.add, circuit);
            const { lastUsedCircuitParams, searchCircuit } = get();
            if (lastUsedCircuitParams) {
                await searchCircuit(lastUsedCircuitParams);
            }
            set({ loading: false });
        } catch (error: any) {
            set({
                error: error.message || 'Erreur lors de l\'ajout du circuit',
                loading: false,
            });
            throw error;
        }
    },

    updateCircuit: async (circuit: Circuit) => {
        set({ loading: true, error: null });
        try {
            await axiosInstance.put(circuitEndpoints.circuit.update, circuit);
            set((state) => ({
                circuits: state.circuits.map((c) => (c.id === circuit.id ? circuit : c)),
                loading: false,
            }));
        } catch (error: any) {
            set({
                error: error.message || 'Erreur lors de la mise à jour du circuit',
                loading: false,
            });
            throw error;
        }
    },

    toggleActive: async (circuitCode: string) => {
        set({ loading: true, error: null });
        try {
            await axiosInstance.put<boolean>(circuitEndpoints.circuit.toggleActive(circuitCode));
            set((state) => ({
                circuits: state.circuits.map((c) => (c.circuitCode === circuitCode ? { ...c, active: !c.active } : c)),
                loading: false,
            }));
        } catch (error: any) {
            set({
                error: error.message || 'Erreur lors du changement de statut',
                loading: false,
            });
            throw error;
        }
    },

    updateCircuitStatus: async (id, circuitState) => {
        set({ loading: true, error: null });
        try {
            await axiosInstance.put<CircuitState>(
            circuitEndpoints.circuit.updateStatus(id), null, { params: { circuitState } }
            );  
            set((state) => ({
                circuits: state.circuits.map((c) => (c.id === id ? { ...c, circuitState: circuitState } : c)),
                loading: false,
            }));
        } catch (error: any) {
            set({
                error: error.message || 'Failed to update circuit status',
                loading: false,
            });
            throw error;
        }
    },

    autocompleteCircuits: async (circuitCode?: string) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(circuitEndpoints.circuit.autocomplete, {
                params: { circuitCode },
            });
            set({ loading: false });
            return response.data;
        } catch (error: any) {
            set({
                error: error.message || 'Erreur lors de la recherche des circuits',
                loading: false,
            });
            throw error;
        }
    },
    generateTrips: async (circuitId: string) => {
        set({ generateTripsLoading: true, error: null });
        try {
            await axiosInstance.get(circuitEndpoints.circuit.trip.generateTripsTemp(circuitId));
            set({ generateTripsLoading: false });
        } catch (error: any) {
            set({ error: error.message || 'Erreur lors de la génération des trajets', generateTripsLoading: false });
            throw error;
        }
    }
}));