import { useState } from '@wordpress/element';
import { useFormContext } from 'react-hook-form';
import { PrimaryButton } from '@admin/components/PrimaryButton';

/**
 * Settings button. Posts `ajax_action` to `admin-ajax.php`, or opens `href`; optional `include_fields` copies live form values into the request, and optional `buttons` renders several actions in one row. Schema field shape: label, ajax_action, ajax_data, include_fields, reload, href, target, disabled, buttons.
 *
 * @param {Object} props
 * @param {Object} props.field Schema field.
 * @return {React.ReactNode} Action button or button row.
 */
export function ButtonField( { field } ) {
	const { getValues } = useFormContext();
	const [ busy, setBusy ] = useState( false );
	const [ notices, setNotices ] = useState( '' );

	const actions = field.buttons ?? [
		{
			label: field.label,
			ajax_action: field.ajax_action,
			ajax_data: field.ajax_data,
			include_fields: field.include_fields,
			reload: field.reload,
			href: field.href,
			target: field.target,
		},
	];

	/**
	 * Run one action: open a link, or POST to admin-ajax.php.
	 *
	 * @param {Object} action Action from `field` or `field.buttons`.
	 * @return {Promise<void>} Resolves when the request finishes.
	 */
	async function onClick( action ) {
		if ( field.disabled || busy ) {
			return;
		}

		if ( action.href ) {
			return;
		}

		if ( ! action.ajax_action ) {
			return;
		}

		setBusy( true );
		setNotices( '' );

		const body = new FormData();
		body.append( 'action', action.ajax_action );
		if ( ! ( action.ajax_data && action.ajax_data.nonce ) ) {
			body.append( 'nonce', window.advadsglobal?.ajax_nonce ?? '' );
		}
		Object.entries( action.ajax_data ?? {} ).forEach(
			( [ key, value ] ) => {
				body.append( key, String( value ) );
			}
		);

		( action.include_fields ?? [] ).forEach( ( id ) => {
			const value = getValues( id );
			if (
				false === value ||
				null === value ||
				undefined === value ||
				'' === value
			) {
				return;
			}
			body.append( id, true === value ? '1' : String( value ) );
		} );

		const response = await fetch( window.ajaxurl, {
			method: 'POST',
			credentials: 'same-origin',
			body,
		} );

		if ( action.reload ) {
			window.location.reload();
			return;
		}

		try {
			const json = await response.json();
			if ( json?.notices ) {
				setNotices( json.notices );
			}
		} catch {
			setNotices( '' );
		}

		setBusy( false );
	}

	return (
		<div className="flex flex-col gap-3">
			{ notices && (
				<div
					className="text-sm text-red-600"
					dangerouslySetInnerHTML={ { __html: notices } }
				/>
			) }
			<div className="flex flex-wrap gap-2">
				{ actions.map( ( action ) => (
					<PrimaryButton
						key={ action.label }
						href={ action.href }
						target={ action.target }
						onClick={ () => onClick( action ) }
						disabled={ field.disabled || busy }
					>
						{ action.label }
					</PrimaryButton>
				) ) }
			</div>
		</div>
	);
}
