/**
 * Hook for managing export profiles via the REST API.
 *
 * @package RawTypeOE
 */

import { useState, useEffect, useCallback, useRef } from '@wordpress/element';
import apiFetch from '../utils/apiFetch';

/**
 * CRUD operations for saved export profiles.
 *
 * @return {Object} { profiles, isLoading, error, isRunning, createProfile, updateProfile, deleteProfile, runProfile, refetch }
 */
export function useProfiles() {
	const [ profiles, setProfiles ] = useState( [] );
	const [ isLoading, setIsLoading ] = useState( true );
	const [ error, setError ] = useState( null );
	const [ isRunning, setIsRunning ] = useState( null );
	const listAbortRef = useRef( null );

	const fetchProfiles = useCallback( () => {
		if ( listAbortRef.current ) {
			listAbortRef.current.abort();
		}
		const controller = new AbortController();
		listAbortRef.current = controller;

		setIsLoading( true );
		setError( null );

		apiFetch( { path: '/rawtype_oe/v1/profiles', signal: controller.signal } )
			.then( ( data ) => {
				setProfiles( Array.isArray( data ) ? data : [] );
				setIsLoading( false );
			} )
			.catch( ( err ) => {
				if ( 'AbortError' !== err.name ) {
					setError( err );
					setIsLoading( false );
				}
			} );
	}, [] );

	useEffect( () => {
		fetchProfiles();
		return () => {
			if ( listAbortRef.current ) {
				listAbortRef.current.abort();
			}
		};
	}, [ fetchProfiles ] );

	const createProfile = useCallback(
		async ( name, config ) => {
			const result = await apiFetch( {
				path: '/rawtype_oe/v1/profiles',
				method: 'POST',
				data: { name, config },
			} );
			fetchProfiles();
			return result;
		},
		[ fetchProfiles ],
	);

	const updateProfile = useCallback(
		async ( id, name, config ) => {
			const result = await apiFetch( {
				path: '/rawtype_oe/v1/profiles/' + id,
				method: 'PUT',
				data: { name, config },
			} );
			fetchProfiles();
			return result;
		},
		[ fetchProfiles ],
	);

	const deleteProfile = useCallback(
		async ( id ) => {
			await apiFetch( {
				path: '/rawtype_oe/v1/profiles/' + id,
				method: 'DELETE',
			} );
			fetchProfiles();
		},
		[ fetchProfiles ],
	);

	const runProfile = useCallback(
		async ( id, format ) => {
			// Client-side ceiling for the synchronous export (5 minutes) — a
			// hung backend must not leave the row stuck on "Exporting…".
			const controller = new AbortController();
			const timeoutId = setTimeout( () => controller.abort(), 5 * 60 * 1000 );

			setIsRunning( id );
			try {
				const result = await apiFetch( {
					path: '/rawtype_oe/v1/profiles/' + id + '/run',
					method: 'POST',
					data: format ? { format } : undefined,
					signal: controller.signal,
				} );
				fetchProfiles();
				return result;
			} finally {
				clearTimeout( timeoutId );
				setIsRunning( null );
			}
		},
		[ fetchProfiles ],
	);

	return {
		profiles,
		isLoading,
		error,
		isRunning,
		createProfile,
		updateProfile,
		deleteProfile,
		runProfile,
		refetch: fetchProfiles,
	};
}

export default useProfiles;
