import { create } from 'zustand';
import axiosInstance from '@/utils/axios';
import { vehicleEndpoints } from '../../endpoints/fleet-service/vehicle-endpoints';
import { VehicleListResponse, VehicleRequest, VehicleStatus, VehiclePageFilterParams, Vehicle, VehicleDropdown } from '@/shared/types/fleet-management/vehicle';

type VehicleStore = {
    error: string | null;
    loading: boolean;
    vehiclesPage: VehicleListResponse[];
    totalElements: number;
    lastUsedVehiclesParams: VehiclePageFilterParams | null;
    vehicleById: Vehicle | null;
    existsByVehicleIdentificationNumberLoading: boolean;
    existsByRegistrationPlateLoading: boolean;

    fetchVehiclesPage: (params: VehiclePageFilterParams) => Promise<void>;
    getVehicleById: (id: string) => Promise<Vehicle | null>;
    createVehicle: (data: VehicleRequest) => Promise<void>;
    updateVehicle: (id: string, data: VehicleRequest) => Promise<void>;
    toggleActiveStatus: (id: string, active: boolean) => Promise<void>;
    toggleVehicleStatus: (id: string, status: VehicleStatus) => Promise<void>;
    getVehicleShortAll: () => Promise<VehicleDropdown[]>;
    getVehicleShortByBrand: (brandName: string) => Promise<VehicleDropdown[]>;
    getVehicleShortByBrandModel: (brandName: string, modelName: string) => Promise<VehicleDropdown[]>;
    getVehicleShortByType: (vehicleType: string) => Promise<VehicleDropdown[]>;
    existsByVehicleIdentificationNumber: (vehicleIdentificationNumber: string, excludeId?: number) => Promise<boolean>;
    existsByRegistrationPlate: (registrationPlate: string, excludeId?: number) => Promise<boolean>;
    startCsvExport: (userId: string, params: any) => Promise<void>;
    downloadCsvExport: (filePath: string) => Promise<void>;
};

export const useVehicleStore = create<VehicleStore>((set, get) => ({
    error: null,
    loading: false,

    vehiclesPage: [],
    totalElements: 0,
    lastUsedVehiclesParams: null,
    vehicleById: null,
    existsByVehicleIdentificationNumberLoading: false,
    existsByRegistrationPlateLoading: false,

    fetchVehiclesPage: async (params: VehiclePageFilterParams) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(vehicleEndpoints.getPage, { params });
            set({ vehiclesPage: response.data.content, totalElements: response.data.totalElements, loading: false });
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    getVehicleById: async (id: string) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(vehicleEndpoints.getById(id));
            set({ vehicleById: response.data, loading: false });
            return response.data;
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    createVehicle: async (data) => {
        set({ loading: true, error: null });
        try {
            await axiosInstance.post(vehicleEndpoints.create, data);
            const { lastUsedVehiclesParams, fetchVehiclesPage } = get();
            if (lastUsedVehiclesParams) {
                await fetchVehiclesPage(lastUsedVehiclesParams);
            }
            set({ loading: false });
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    updateVehicle: async (id, data) => {
        set({ loading: true, error: null });
        try {
            await axiosInstance.post(vehicleEndpoints.update(id), data);
            const { lastUsedVehiclesParams, fetchVehiclesPage } = get();
            if (lastUsedVehiclesParams) {
                await fetchVehiclesPage(lastUsedVehiclesParams);
            }
            set({ loading: false });
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    toggleActiveStatus: async (id, active) => {
        set({ loading: true, error: null });
        try {
            await axiosInstance.post(vehicleEndpoints.toggleActive(id), null, { params: { active } });
            const { vehiclesPage } = get();
            set({
                vehiclesPage: vehiclesPage.map((v) =>
                    v.id === id ? { ...v, active } : v
                ),
                loading: false
            });
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    toggleVehicleStatus: async (id, status) => {
        set({ loading: true, error: null });
        try {
            await axiosInstance.post(vehicleEndpoints.toggleStatus(id), null, { params: { status } });
            const { vehiclesPage } = get();
            set({
                vehiclesPage: vehiclesPage.map((v) =>
                    v.id === id ? { ...v, status } : v
                ),
                loading: false
            });
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    getVehicleShortAll: async () => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(vehicleEndpoints.getShortAll);
            set({ vehiclesPage: response.data, loading: false });
            return response.data;
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    getVehicleShortByBrand: async (brandName) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(vehicleEndpoints.getShortByBrand(brandName));
            set({ vehiclesPage: response.data, loading: false });
            return response.data;
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    getVehicleShortByBrandModel: async (brandName, modelName) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(vehicleEndpoints.getShortByBrandModel(brandName, modelName));
            set({ vehiclesPage: response.data, loading: false });
            return response.data;
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    getVehicleShortByType: async (vehicleType) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(vehicleEndpoints.getShortByType(vehicleType));
            set({ vehiclesPage: response.data, loading: false });
            return response.data;
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    existsByVehicleIdentificationNumber: async (vehicleIdentificationNumber: string, excludeId?: number) => {
        set({ existsByVehicleIdentificationNumberLoading: true, error: null });
        try {
            const response = await axiosInstance.get(
                vehicleEndpoints.existsByVehicleIdentificationNumber,
                {
                    params: {
                        vehicleIdentificationNumber,
                        excludeId
                    }
                }
            );
            return response.data;
        } catch (error: any) {
            set({
                error: error.message || "Failed to check if contract exists by title",
            });
            throw error;
        } finally {
            set({ existsByVehicleIdentificationNumberLoading: false });
        }
    },

    existsByRegistrationPlate: async (registrationPlate: string, excludeId?: number) => {
        set({ existsByRegistrationPlateLoading: true, error: null });
        try {
            const response = await axiosInstance.get(
                vehicleEndpoints.existsByRegistrationPlate,
                {
                    params: {
                        registrationPlate,
                        excludeId
                    }
                }
            );
            return response.data;
        } catch (error: any) {
            set({
                error: error.message || "Failed to check if contract exists by title",
            });
            throw error;
        } finally {
            set({ existsByRegistrationPlateLoading: false });
        }
    },

    startCsvExport: async (userId, params) => {
        set({ loading: true, error: null });
        try {
            await axiosInstance.get(vehicleEndpoints.startCsvExport, {
                params: { ...params, userId }
            });
            set({ loading: false });
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    downloadCsvExport: async (filePath) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(vehicleEndpoints.downloadCsvExport, { params: { filePath }, responseType: 'blob' });
            set({ loading: false });
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },
}));