import { create } from 'zustand';
import {
    VehicleBrandModel,
    VehicleBrandModelPageFilterParams,
    VehicleBrandModelRequest
} from '@/shared/types/fleet-management/vehicle-brand-model';
import axiosInstance from '@/utils/axios';
import { vehicleBrandModelEndpoints } from '../../endpoints/fleet-service/vehicle-brand-model-endpoints';
import { VehicleType } from '@/shared/types/fleet-management/vehicleType';

type VehicleBrandModelStore = {
    error: string | null;
    loading: boolean;

    vehicleBrandModelsPage: VehicleBrandModel[];
    totalElements: number;
    lastUsedBrandModelsParams: VehicleBrandModelPageFilterParams | null;
    vehicleBrandModelById: VehicleBrandModel | null;
    brands: string[];
    models: string[];
    existsByBrandNameAndModelNameLoading: boolean;

    fetchVehicleBrandModelsPage: (params?: VehicleBrandModelPageFilterParams) => Promise<void>;
    getVehicleBrandModelById: (id: string) => Promise<VehicleBrandModel | null>;
    fetchBrands: () => Promise<void>;
    fetchModels: () => Promise<void>;
    fetchModelsByBrandName: (brandName: string) => Promise<void>;
    createVehicleBrandModel: (data: VehicleBrandModelRequest) => Promise<void>;
    updateVehicleBrandModel: (id: string, data: VehicleBrandModelRequest) => Promise<void>;
    toggleActiveStatus: (id: string, active: boolean) => Promise<void>;
    startExportFiltredVehicleBrandModels: (userId: string, params?: VehicleBrandModelPageFilterParams) => Promise<void>;
    existsByBrandNameAndModelName: (brandName: string, modelName: string, excludeId?: string) => Promise<boolean>;
    getVehicleTypeByBrandModel: (brandName: string, modelName: string, excludeId?: string) => Promise<VehicleType>;
};

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

    vehicleBrandModelsPage: [],
    totalElements: 0,
    lastUsedBrandModelsParams: null,
    vehicleBrandModelById: null,
    brands: [],
    models: [],
    existsByBrandNameAndModelNameLoading: false,

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

    getVehicleBrandModelById: async (id) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(vehicleBrandModelEndpoints.getById(id));
            set({ loading: false, vehicleBrandModelById: response.data as VehicleBrandModel });
            return response.data as VehicleBrandModel;
        } catch (error: any) {
            set({
                error: error.message || 'Failed to fetch vehicleBrandModel by ID',
                loading: false,
            });
            throw error;
        }
    },

    fetchBrands: async () => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(vehicleBrandModelEndpoints.getBrands);
            set({ brands: response.data, loading: false });
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    fetchModels: async () => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(vehicleBrandModelEndpoints.getModels);
            set({ models: response.data, loading: false });
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    fetchModelsByBrandName: async (brandName: string) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(vehicleBrandModelEndpoints.getModelsByBrand(brandName));
            set({ models: response.data, loading: false });
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    createVehicleBrandModel: async (data: VehicleBrandModelRequest) => {
        set({ loading: true, error: null });
        try {
            await axiosInstance.post(vehicleBrandModelEndpoints.create, data);
            const { lastUsedBrandModelsParams, fetchVehicleBrandModelsPage } = get();
            if (lastUsedBrandModelsParams) {
                await fetchVehicleBrandModelsPage(lastUsedBrandModelsParams);
            }
            set({ loading: false });
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    updateVehicleBrandModel: async (id: string, data: VehicleBrandModelRequest) => {
        set({ loading: true, error: null });
        try {
            await axiosInstance.put(vehicleBrandModelEndpoints.update(id), data);
            const { lastUsedBrandModelsParams, fetchVehicleBrandModelsPage } = get();
            if (lastUsedBrandModelsParams) {
                await fetchVehicleBrandModelsPage(lastUsedBrandModelsParams);
            }
            set({ loading: false });
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    toggleActiveStatus: async (id: string, active: boolean) => {
        set({ loading: true, error: null });
        try {
            await axiosInstance.patch(vehicleBrandModelEndpoints.toggleActive(id), null, { params: { active } });
            const { vehicleBrandModelsPage } = get();
            set({
                vehicleBrandModelsPage: vehicleBrandModelsPage.map((vbm) =>
                    vbm.id === id ? { ...vbm, active } : vbm
                ),
                loading: false
            });
        } catch (error: any) {
            set({ error: error.message, loading: false });
            throw error;
        }
    },

    startExportFiltredVehicleBrandModels: async (userId, params) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(vehicleBrandModelEndpoints.startCsvExport, {
                params: { ...params, userId: userId }
            });
            return response.data;
        } catch (error: any) {
            set({
                error: error.message || 'Failed to start export fuel types',
                loading: false,
            });
            throw error;
        }
    },

    existsByBrandNameAndModelName: async (brandName: string, modelName: string, excludeId?: string) => {
        set({ existsByBrandNameAndModelNameLoading: true, error: null });
        try {
            const response = await axiosInstance.get(
                vehicleBrandModelEndpoints.existsByBrandNameAndModelName,
                { params: { brandName, modelName, excludeId } }
            );
            return response.data;
        } catch (error: any) {
            set({
                error: error.message || "Failed to check if contract exists by code",
            });
            throw error;
        } finally {
            set({ existsByBrandNameAndModelNameLoading: false });
        }
    },

    getVehicleTypeByBrandModel: async (brandName, modelName, excludeId) => {
        set({ loading: true, error: null });
        try {
            const response = await axiosInstance.get(vehicleBrandModelEndpoints.getVehicleTypeByBrandModel, {
                params: {
                    brandName,
                    modelName,
                    excludeId
                }
            });
            set({ loading: false });
            return response.data as VehicleType;
        } catch (error: any) {
            set({
                error: error.message || 'Failed to fetch VehicleType by brandModel',
                loading: false,
            });
            throw error;
        }
    }
}));