import { defineStore } from "pinia";

export const useLoadingStore = defineStore("loading", {
	state: () => ({
		// Global loading state
		isLoading: false,

		// Component-specific loading states for more granular control
		componentLoading: {
			dataTable: false,
			form: false,
			clients: false,
			jobs: false,
			timesheets: false,
			warranties: false,
			routes: false,
			api: false,
		},

		// Loading messages for different contexts
		loadingMessage: "Loading...",

		// Track loading operations with custom keys
		operations: new Map(),
	}),

	getters: {
		// Check if any loading is happening
		isAnyLoading: (state) => {
			return (
				state.isLoading ||
				Object.values(state.componentLoading).some((loading) => loading) ||
				state.operations.size > 0
			);
		},

		// Get loading state for a specific component
		getComponentLoading: (state) => (componentName) => {
			return state.componentLoading[componentName] || false;
		},

		// Check if a specific operation is loading
		isOperationLoading: (state) => (operationKey) => {
			return state.operations.has(operationKey);
		},
	},

	actions: {
		// Set global loading state
		setLoading(isLoading, message = "Loading...") {
			this.isLoading = isLoading;
			this.loadingMessage = message;
		},

		// Set component-specific loading state
		setComponentLoading(componentName, isLoading, message = "Loading...") {
			if (this.componentLoading.hasOwnProperty(componentName)) {
				this.componentLoading[componentName] = isLoading;
			} else {
				this.componentLoading[componentName] = isLoading;
			}
			if (isLoading) {
				this.loadingMessage = message;
			}
		},

		// Start loading for a specific operation
		startOperation(operationKey, message = "Loading...") {
			this.operations.set(operationKey, {
				startTime: Date.now(),
				message: message,
			});
			this.loadingMessage = message;
		},

		// Stop loading for a specific operation
		stopOperation(operationKey) {
			this.operations.delete(operationKey);
		},

		// Clear all loading states
		clearAllLoading() {
			this.isLoading = false;
			Object.keys(this.componentLoading).forEach((key) => {
				this.componentLoading[key] = false;
			});
			this.operations.clear();
			this.loadingMessage = "Loading...";
		},

		// Convenience methods for common operations
		startApiCall(apiName = "api") {
			this.setComponentLoading("api", true, `Loading ${apiName}...`);
		},

		stopApiCall() {
			this.setComponentLoading("api", false);
		},

		startDataTableLoading(message = "Loading data...") {
			this.setComponentLoading("dataTable", true, message);
		},

		stopDataTableLoading() {
			this.setComponentLoading("dataTable", false);
		},

		startFormLoading(message = "Processing...") {
			this.setComponentLoading("form", true, message);
		},

		stopFormLoading() {
			this.setComponentLoading("form", false);
		},

		// Async wrapper for operations
		async withLoading(operationKey, asyncOperation, message = "Loading...") {
			try {
				this.startOperation(operationKey, message);
				const result = await asyncOperation();
				return result;
			} finally {
				this.stopOperation(operationKey);
			}
		},

		// Async wrapper for component loading
		async withComponentLoading(componentName, asyncOperation, message = "Loading...") {
			try {
				this.setComponentLoading(componentName, true, message);
				const result = await asyncOperation();
				return result;
			} finally {
				this.setComponentLoading(componentName, false);
			}
		},
	},
});
