/**
 * Enhanced API wrapper with integrated error handling and notifications
 *
 * This example shows how to use the error store and notification system together
 * to provide comprehensive error handling and user feedback for API calls.
 */

import { useErrorStore } from "@/stores/errors";
import { useNotificationStore } from "@/stores/notifications";
import { useLoadingStore } from "@/stores/loading";
import Api from "./api";

export class ApiWithErrorHandling {
	static async makeApiCall(apiFunction, options = {}) {
		const {
			// Error handling options
			componentName = null,
			showErrorNotifications = true,
			showSuccessNotifications = true,

			// Loading options
			showLoading = true,
			loadingMessage = "Loading...",

			// Success options
			successMessage = null,
			successTitle = "Success",

			// Error options
			errorTitle = "Error",
			customErrorMessage = null,

			// Retry options
			retryCount = 0,
			retryDelay = 1000,

			// Operation identifier for tracking
			operationKey = null,
		} = options;

		const errorStore = useErrorStore();
		const notificationStore = useNotificationStore();
		const loadingStore = useLoadingStore();

		// Generate operation key if not provided
		const operation = operationKey || `api-${Date.now()}`;

		try {
			// Clear any existing errors
			if (componentName) {
				errorStore.clearComponentError(componentName);
			}

			// Show loading state
			if (showLoading) {
				if (componentName) {
					loadingStore.setComponentLoading(componentName, true, loadingMessage);
				} else {
					loadingStore.startOperation(operation, loadingMessage);
				}
			}

			// Make the API call with retry logic
			const result = await errorStore.handleApiCall(operation, apiFunction, {
				showNotification: showErrorNotifications,
				retryCount,
				retryDelay,
			});

			// Show success notification
			if (showSuccessNotifications && successMessage) {
				notificationStore.addSuccess(successMessage, successTitle);
			}

			return result;
		} catch (error) {
			// The error store has already handled the error notification
			// But we can add custom handling here if needed
			console.error("API call failed:", error);

			// Optionally show a custom error message
			if (customErrorMessage && !showErrorNotifications) {
				notificationStore.addError(customErrorMessage, errorTitle);
			}

			// Re-throw the error so calling code can handle it if needed
			throw error;
		} finally {
			// Always clear loading state
			if (showLoading) {
				if (componentName) {
					loadingStore.setComponentLoading(componentName, false);
				} else {
					loadingStore.stopOperation(operation);
				}
			}
		}
	}

	// Convenience methods for common API operations
	static async getClientStatusCounts(options = {}) {
		return this.makeApiCall(() => Api.getClientStatusCounts(), {
			operationKey: "client-status-counts",
			componentName: "clients",
			loadingMessage: "Loading client status data...",
			successMessage: null, // Don't show success for data fetches
			...options,
		});
	}

	static async getPaginatedClientDetails(paginationParams, filters, sorting, options = {}) {
		return this.makeApiCall(
			() => Api.getPaginatedClientDetails(paginationParams, filters, sorting),
			{
				operationKey: "client-table-data",
				componentName: "dataTable",
				loadingMessage: "Loading client data...",
				successMessage: null, // Don't show success for data fetches
				...options,
			},
		);
	}

	static async createClient(clientData, options = {}) {
		return this.makeApiCall(() => Api.createClient(clientData), {
			operationKey: "create-client",
			componentName: "form",
			loadingMessage: "Creating client...",
			successMessage: "Client created successfully!",
			errorTitle: "Failed to Create Client",
			...options,
		});
	}

	static async getPaginatedJobDetails(paginationParams, filters, sorting, options = {}) {
		return this.makeApiCall(
			() => Api.getPaginatedJobDetails(paginationParams, filters, sorting),
			{
				operationKey: "job-table-data",
				componentName: "jobs",
				loadingMessage: "Loading job data...",
				successMessage: null,
				...options,
			},
		);
	}

	static async getPaginatedWarrantyData(paginationParams, filters, sorting, options = {}) {
		return this.makeApiCall(
			() => Api.getPaginatedWarrantyData(paginationParams, filters, sorting),
			{
				operationKey: "warranty-table-data",
				componentName: "warranties",
				loadingMessage: "Loading warranty data...",
				successMessage: null,
				...options,
			},
		);
	}

	static async getCityStateByZip(zipcode, options = {}) {
		return this.makeApiCall(() => Api.getCityStateByZip(zipcode), {
			operationKey: "zip-lookup",
			componentName: "form",
			loadingMessage: "Looking up location...",
			successMessage: null,
			errorTitle: "Zip Code Lookup Failed",
			customErrorMessage: "Unable to find location for the provided zip code",
			retryCount: 2,
			retryDelay: 1000,
			...options,
		});
	}
}

/**
 * Example usage in Vue components:
 *
 * <script setup>
 * import { ref, onMounted } from 'vue';
 * import { ApiWithErrorHandling } from '@/api-enhanced';
 * import { useErrorStore } from '@/stores/errors';
 * import { useNotificationStore } from '@/stores/notifications';
 *
 * const errorStore = useErrorStore();
 * const notificationStore = useNotificationStore();
 *
 * const clientData = ref([]);
 * const pagination = ref({ page: 0, pageSize: 10 });
 * const filters = ref({});
 *
 * // Example 1: Basic API call with automatic error handling
 * const loadClientData = async () => {
 *   try {
 *     const result = await ApiWithErrorHandling.getPaginatedClientDetails(
 *       pagination.value,
 *       filters.value,
 *       []
 *     );
 *     clientData.value = result.data;
 *   } catch (error) {
 *     // Error has already been handled by the error store and notifications shown
 *     // This catch block is optional - you only need it if you want custom handling
 *     console.log('Failed to load client data, but user has been notified');
 *   }
 * };
 *
 * // Example 2: API call with custom options
 * const createNewClient = async (formData) => {
 *   try {
 *     await ApiWithErrorHandling.createClient(formData, {
 *       componentName: 'createClientForm',
 *       successMessage: 'New client added successfully!',
 *       errorTitle: 'Client Creation Failed',
 *       customErrorMessage: 'There was an issue creating the client. Please try again.',
 *       retryCount: 1
 *     });
 *
 *     // Refresh data after successful creation
 *     await loadClientData();
 *   } catch (error) {
 *     // Handle any additional logic needed on error
 *   }
 * };
 *
 * // Example 3: Using error store directly for custom error handling
 * const handleCustomOperation = async () => {
 *   await errorStore.withErrorHandling('custom-operation', async () => {
 *     // Your custom async operation here
 *     const result = await someApiCall();
 *     return result;
 *   }, {
 *     componentName: 'customComponent',
 *     showNotification: true,
 *     rethrow: false // Don't re-throw errors, just handle them
 *   });
 * };
 *
 * // Example 4: Using notification store directly
 * const showCustomNotification = () => {
 *   notificationStore.addNotification({
 *     type: 'info',
 *     title: 'Custom Notification',
 *     message: 'This is a custom message with actions',
 *     actions: [
 *       {
 *         label: 'Retry',
 *         variant: 'primary',
 *         handler: () => loadClientData()
 *       },
 *       {
 *         label: 'Cancel',
 *         variant: 'secondary'
 *       }
 *     ]
 *   });
 * };
 *
 * onMounted(() => {
 *   loadClientData();
 * });
 * </script>
 */

export default ApiWithErrorHandling;
