import { translate } from 'i18n-calypso';
import { REWIND_RESTORE_PROGRESS_REQUEST } from 'calypso/state/action-types';
import { updateRewindRestoreProgress } from 'calypso/state/activity-log/actions';
import { registerHandlers } from 'calypso/state/data-layer/handler-registry';
import { http } from 'calypso/state/data-layer/wpcom-http/actions';
import { dispatchRequest } from 'calypso/state/data-layer/wpcom-http/utils';
import { errorNotice } from 'calypso/state/notices/actions';

/** @type {number} how many ms between polls for same data */
const POLL_INTERVAL = 1500;

/** @type {Map<string, number>} stores most-recent polling times */
const recentRequests = new Map();

/** @type {string} Request error notice id. Prevents polling from creating endless notices */
const ERROR_NOTICE_ID = 'AL_REW_RESTORESTATUS_ERR';

/**
 * Fetch status updates for restore operations
 *
 * Note! Eventually the manual "caching" here should be
 * replaced by the `freshness` system in the data layer
 * when it arrives. For now, it's statefully ugly.
 * @param  {Object} action Redux action
 * @returns {Object | undefined} Redux action
 */
const fetchProgress = ( action ) => {
	const { restoreId, siteId } = action;
	const key = `${ siteId }-${ restoreId }`;

	const lastUpdate = recentRequests.get( key ) || -Infinity;
	const now = Date.now();

	if ( now - lastUpdate < POLL_INTERVAL ) {
		return;
	}

	recentRequests.set( key, now );

	return http(
		{
			apiVersion: '1',
			method: 'GET',
			path: `/activity-log/${ siteId }/rewind/${ restoreId }/restore-status`,
		},
		action
	);
};

export const fromApi = ( {
	restore_status: {
		error_code = '',
		failure_reason = '',
		message = '',
		percent = 0,
		status = '',
		rewind_id = '',
		context = '',
		current_entry = '',
	} = {},
} ) => ( {
	errorCode: error_code,
	failureReason: failure_reason,
	message,
	percent: +percent,
	status,
	rewindId: rewind_id,
	context,
	currentEntry: current_entry,
} );

export const updateProgress = ( { siteId, restoreId, timestamp }, data ) =>
	updateRewindRestoreProgress( siteId, timestamp, restoreId, data );

export const announceFailure = () =>
	errorNotice(
		translate( "Hmm, we can't update the status of your restore. Please refresh this page." ),
		{ id: ERROR_NOTICE_ID }
	);

registerHandlers( 'state/data-layer/wpcom/activity-log/rewind/restore-status/index.js', {
	[ REWIND_RESTORE_PROGRESS_REQUEST ]: [
		dispatchRequest( {
			fetch: fetchProgress,
			onSuccess: updateProgress,
			onError: announceFailure,
			fromApi,
		} ),
	],
} );
