/**
 * External dependencies.
 */
import {
	createContext,
	useState,
	useContext,
	useEffect,
	useCallback,
} from "@wordpress/element";
import { __ } from "@wordpress/i18n";
import toast from "react-hot-toast";

/**
 * Internal dependencies.
 */
import { fetchSyncingData, runUpdate } from "../api/settings";

// Create the sync context
const SyncContext = createContext();

/**
 * Custom hook to use the sync context
 */
export const useSyncData = () => {
	const context = useContext(SyncContext);
	if (!context) {
		throw new Error("useSyncData must be used within a SyncDataProvider");
	}
	return context;
};

/**
 * Provider component for sync data
 */
export const SyncDataProvider = ({ children }) => {
	// Initialize with default values reflecting the new API response structure
	const [syncData, setSyncData] = useState({
		is_initiating: false,
		is_processing: false,
		queue_count: 0,
		next_scheduled: null,
		next_scheduled_human: __("Loading...", "openasset"),
		totals: { projects: 0, employees: 0 },
		progress: { projects: 0, employees: 0 },
	});
	const [isInitialized, setIsInitialized] = useState(false);
	const [isTriggering, setIsTriggering] = useState(false);

	// Fetch function using useCallback to avoid recreating on every render
	const fetchAndUpdateSyncStatus = useCallback(async () => {
		try {
			const data = await fetchSyncingData();
			setSyncData(data);
		} catch (error) {
			console.error("Error fetching sync data:", error);
		}
	}, []);

	// Initial data load
	useEffect(() => {
		// Fetch initial sync state from the server
		fetchAndUpdateSyncStatus().finally(() => setIsInitialized(true));
	}, [fetchAndUpdateSyncStatus]);

	// Poll for updates after initialization
	useEffect(() => {
		if (!isInitialized) return;

		const intervalId = setInterval(() => {
			fetchAndUpdateSyncStatus();
		}, 5000);

		return () => clearInterval(intervalId);
	}, [isInitialized, fetchAndUpdateSyncStatus]);

	// Function to manually trigger sync initiation
	const handleTriggerSync = useCallback(async () => {
		if (isTriggering) return;
		setIsTriggering(true);

		// Optimistic update: show sync bar immediately before server responds
		setSyncData((prev) => ({
			...prev,
			is_initiating: true,
			current_sync_context: { type: "preparing", name: "Preparing sync..." },
		}));

		try {
			const response = await runUpdate();
			// No toast notification needed - sync banner provides better feedback
			// Immediately fetch status after triggering
			await fetchAndUpdateSyncStatus();
		} catch (error) {
			console.error("Error triggering sync:", error);
			const errorMessage = error?.message || __("Failed to trigger sync.", "openasset");
			// Check for specific conflict error from API
			if (error?.code === 'sync_already_initiating') {
				toast.error(errorMessage);
			} else {
				toast.error(errorMessage);
			}
			// Revert optimistic state on error
			await fetchAndUpdateSyncStatus();
		} finally {
			setIsTriggering(false);
		}
	}, [isTriggering, fetchAndUpdateSyncStatus]);

	const value = {
		syncData,
		setSyncData,
		isInitialized,
		handleTriggerSync,
		isTriggering,
	};

	return (
		<SyncContext.Provider value={value}>{children}</SyncContext.Provider>
	);
};

export default SyncContext;
