import apiFetch from '@wordpress/api-fetch';
import { date } from '@wordpress/date';
import { useState, useEffect } from '@wordpress/element';
import { BACKUP_STATE } from '../constants';

const useBackupsState = () => {
	const progressInterval = 1 * 1000; // How often to poll for backup progress updates.
	const [ backupState, setBackupState ] = useState( BACKUP_STATE.LOADING );
	const [ latestTime, setLatestTime ] = useState( '' );
	const [ progress, setProgress ] = useState( 0 );
	const [ stats, setStats ] = useState( {
		posts: 0,
		uploads: 0,
		plugins: 0,
		themes: 0,
		warnings: false,
	} );

	const fetchBackupsState = () =>
		apiFetch( { path: '/jetpack/v4/backups' } ).then(
			res => {
				// If we have no backups don't load up stats.
				let latestBackup = null;
				if ( res.length === 0 ) {
					setBackupState( BACKUP_STATE.NO_BACKUPS );
				} else if ( res.length === 1 && 'error-will-retry' === res[ 0 ].status ) {
					setBackupState( BACKUP_STATE.NO_BACKUPS_RETRY );
				} else {
					// Check for the first completed backups.
					res.forEach( backup => {
						if ( null !== latestBackup ) {
							return;
						}

						if ( 'finished' === backup.status && backup.stats ) {
							latestBackup = backup;
							setBackupState( BACKUP_STATE.COMPLETE );
						}
					} );

					// Only the first backup can be in progress.
					if ( null === latestBackup && 'started' === res[ 0 ].status ) {
						latestBackup = res[ 0 ];
						setProgress( latestBackup.percent );
						setBackupState( BACKUP_STATE.IN_PROGRESS );
					}

					// No complete or in progress backups.
					if ( ! latestBackup ) {
						setBackupState( BACKUP_STATE.NO_GOOD_BACKUPS );
						return;
					}

					// Setup data for COMPLETE state.
					if ( 'finished' === latestBackup.status ) {
						const postsTable = latestBackup.stats.prefix + 'posts';
						setStats( {
							plugins: latestBackup.stats.plugins.count,
							themes: latestBackup.stats.themes.count,
							uploads: latestBackup.stats.uploads.count,
							posts: latestBackup.stats.tables[ postsTable ].post_published,
							warnings: latestBackup.has_warnings ? true : false,
						} );
						setLatestTime( date( 'c', latestBackup.last_updated + '+00:00' ) );
					}
				}

				// Repeat query for NO_BACKUPS (before first) and IN_PROGRESS
				if ( res.length === 0 || 'started' === latestBackup.status ) {
					// Grab progress and update every progressInterval until complete.
					setTimeout( () => {
						fetchBackupsState();
					}, progressInterval );
				}
			},
			() => {
				setBackupState( BACKUP_STATE.NO_GOOD_BACKUPS );
			}
		);

	// Start the initial state fetch
	useEffect( () => {
		fetchBackupsState();
	}, [] ); // eslint-disable-line react-hooks/exhaustive-deps

	return {
		backupState,
		fetchBackupsState,
		latestTime,
		progress,
		stats,
	};
};

export default useBackupsState;
