import { useQueryClient } from '@tanstack/react-query';
import { useCallback } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { applyFix, undoFix } from '../api/fixRuns';
import { refreshLinkData } from '../api/refreshLinkData';
import type { Fix, FixRequest } from '../api/types/fixes';
import { errorMessage } from '../ui/errorMessage';
import { useToast } from '../ui/Toasts';
import { fixDoneText } from './fixDoneText';
import { withUnchangedPlaces } from './unchangedPlacesText';

export type UndoableFix = Pick< Fix, 'id' | 'links_total' >;

function undoneText( fix: UndoableFix ): string {
	if ( fix.links_total > 1 ) {
		return __(
			'Undone. The links are back in the list.',
			'aiplaz-link-checkup'
		);
	}

	return __( 'Undone. The link is back in the list.', 'aiplaz-link-checkup' );
}

function failedChangeMessage( error: unknown ): string {
	return errorMessage(
		error,
		__(
			'Something went wrong. Nothing was changed.',
			'aiplaz-link-checkup'
		)
	);
}

export function useFixActions() {
	const queryClient = useQueryClient();
	const showToast = useToast();

	const undo = useCallback(
		async ( fix: UndoableFix ): Promise< void > => {
			try {
				await undoFix( fix.id );
				showToast( { text: undoneText( fix ) } );
			} catch ( error ) {
				showToast( {
					text: failedChangeMessage( error ),
					tone: 'bad',
				} );
			} finally {
				refreshLinkData( queryClient );
			}
		},
		[ queryClient, showToast ]
	);

	const apply = useCallback(
		async ( request: FixRequest ): Promise< Fix | null > => {
			try {
				const fix = await applyFix( request );

				showToast( {
					text: withUnchangedPlaces( fixDoneText( fix ), fix ),
					action: {
						label: __( 'Undo', 'aiplaz-link-checkup' ),
						onClick: () => {
							void undo( fix );
						},
					},
				} );

				return fix;
			} catch ( error ) {
				showToast( {
					text: failedChangeMessage( error ),
					tone: 'bad',
				} );

				return null;
			} finally {
				refreshLinkData( queryClient );
			}
		},
		[ queryClient, showToast, undo ]
	);

	return { apply, undo };
}
