import {useEffect, useRef} from '@wordpress/element';
import '../scss/_field-control.scss';
import PremiumBadge from '../partials/premium-badge';
import ManualLink from '../partials/ManualLink';

// First element inside the field that should announce help/error text.
const DESCRIBED_TARGET = '[role="group"], [role="radiogroup"], [role="switch"], [role="combobox"], input:not([type="hidden"]), select, textarea, button';

const FieldControl = ( {
						   label,
						   help,
						   id,
						   error,
						   className = '',
						   children,
						   premium = false,
						   labelClassName = '',
						   helpClassName = '',
						   link = '',
						   ...props
					   } ) => {

	const wrapperClasses = [
		'adpresso-field-control',
		className,
		premium && 'is-premium'
	].filter( Boolean ).join( ' ' );

	const helpId = help && id ? `${id}-description` : undefined;
	const errorId = error && id ? `${id}-error` : undefined;
	const innerRef = useRef( null );

	// Wires help/error text to the control without every field component having to pass it through.
	useEffect( () => {
		const target = innerRef.current?.querySelector( DESCRIBED_TARGET );
		if ( !target ) {
			return;
		}

		const ownIds = [helpId, errorId].filter( Boolean );
		const otherIds = ( target.getAttribute( 'aria-describedby' ) || '' )
			.split( ' ' )
			.filter( ( ref ) => ref && ref !== `${id}-description` && ref !== `${id}-error` );
		const describedBy = [...otherIds, ...ownIds].join( ' ' );

		if ( describedBy ) {
			target.setAttribute( 'aria-describedby', describedBy );
		} else {
			target.removeAttribute( 'aria-describedby' );
		}

		if ( errorId ) {
			target.setAttribute( 'aria-invalid', 'true' );
		} else if ( target.getAttribute( 'aria-invalid' ) === 'true' ) {
			target.removeAttribute( 'aria-invalid' );
		}
	} );

	return (
		<div className={wrapperClasses} {...props}>
			{label && (
				<label
					htmlFor={id}
					className={`adpresso-field-label ${labelClassName}`}
				>
					{label}
					{premium && <PremiumBadge/>}
					{!help && link && <ManualLink url={link}/>}
				</label>
			)}

			<div className="adpresso-field-inner" ref={innerRef}>
				{children}
			</div>

			{error && (
				<p id={errorId} className="adpresso-field-error">
					{error}
				</p>
			)}

			{help && (
				<p id={helpId} className={`adpresso-field-help ${helpClassName}`}>
					{help}
					{link && <ManualLink url={link}/>}
				</p>
			)}
		</div>
	);
};

export default FieldControl;
