/**
 * Enhanced API wrapper with PrimeVue Toast integration
 *
 * This provides a cleaner, simpler API error handling system using PrimeVue Toast
 * instead of a complex custom notification system.
 */

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

export class ApiWithToast {
	static async makeApiCall(apiFunction, options = {}) {
		const {
			// Error handling options
			componentName = null,
			showErrorToast = true,
			showSuccessToast = false,

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

			// Success options
			successMessage = null,

			// Error options
			customErrorMessage = null,

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

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

		const errorStore = useErrorStore();
		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
			let attempt = 0;
			while (attempt <= retryCount) {
				try {
					const result = await apiFunction();

					// Show success toast if requested
					if (showSuccessToast && successMessage) {
						errorStore.setSuccess(successMessage);
					}

					return result;
				} catch (error) {
					attempt++;

					if (attempt <= retryCount) {
						// Wait before retry
						await new Promise((resolve) => setTimeout(resolve, retryDelay));
						continue;
					}

					// Final attempt failed - handle error
					if (componentName) {
						errorStore.setComponentError(componentName, error, false);
					}

					// Show error toast
					if (showErrorToast) {
						const errorMessage = customErrorMessage || this.extractErrorMessage(error);
						errorStore.setGlobalError(new Error(errorMessage));
					}

					// Rethrow error if requested (default is to rethrow)
					if (rethrow) {
						throw error;
					}

					// If not rethrowing, return null to indicate failure
					return null;
				}
			}
		} finally {
			// Always clear loading state
			if (showLoading) {
				if (componentName) {
					loadingStore.setComponentLoading(componentName, false);
				} else {
					loadingStore.stopOperation(operation);
				}
			}
		}
	}

	// Helper to extract meaningful error messages
	static extractErrorMessage(error) {
		if (typeof error === "string") {
			return error;
		}

		if (error?.response?.data?.message) {
			return error.response.data.message;
		}

		if (error?.message) {
			return error.message;
		}

		if (error?.request) {
			return "Network error - please check your connection";
		}

		return "An unexpected error occurred";
	}

	// 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...",
			showSuccessToast: false, // 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...",
				showSuccessToast: false,
				...options,
			},
		);
	}

	static async createClient(clientData, options = {}) {
		return this.makeApiCall(() => Api.createClient(clientData), {
			operationKey: "create-client",
			componentName: "form",
			loadingMessage: "Creating client...",
			showSuccessToast: true,
			successMessage: "Client created successfully!",
			...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...",
				showSuccessToast: false,
				...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...",
				showSuccessToast: false,
				...options,
			},
		);
	}

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

/**
 * Simple usage examples:
 *
 * // Basic API call with automatic toast notifications
 * try {
 *   const result = await ApiWithToast.getPaginatedClientDetails(pagination, filters, []);
 *   // Success - data loaded, no toast shown for data fetches
 * } catch (error) {
 *   // Error toast automatically shown, component error set
 * }
 *
 * // Create operation with success toast
 * try {
 *   await ApiWithToast.createClient(formData);
 *   // Success toast shown automatically: "Client created successfully!"
 * } catch (error) {
 *   // Error toast shown automatically with appropriate message
 * }
 *
 * // Custom options
 * await ApiWithToast.makeApiCall(
 *   () => someApiCall(),
 *   {
 *     componentName: 'myComponent',
 *     showSuccessToast: true,
 *     successMessage: 'Operation completed!',
 *     retryCount: 3,
 *     customErrorMessage: 'Custom error message'
 *   }
 * );
 */

export default ApiWithToast;
