/**
 * Shared helpers for the boxRadius style-schema field type.
 */

export const DEFAULT_BORDER_RADIUS = '8px';

/**
 * Derive CSS custom-property keys for a boxRadius field.
 *
 * Root from `field.key` (e.g. `--bm-item-border-radius`) yields:
 * `--bm-item-border-radius` and `--bm-item-border-{corner}-radius`.
 *
 * @param {object} field
 * @return {{
 *   all: string,
 *   topLeft: string,
 *   topRight: string,
 *   bottomRight: string,
 *   bottomLeft: string
 * }}
 */
export function boxRadiusKeys( field ) {
	const raw = String( field?.key || '--bm-border-radius' ).trim();
	const base = raw.replace(
		/-(?:top-left|top-right|bottom-right|bottom-left)?-?radius$/i,
		''
	);
	const root = base || '--bm-border';
	return {
		all: field?.allKey || field?.key || `${ root }-radius`,
		topLeft: field?.topLeftKey || `${ root }-top-left-radius`,
		topRight: field?.topRightKey || `${ root }-top-right-radius`,
		bottomRight: field?.bottomRightKey || `${ root }-bottom-right-radius`,
		bottomLeft: field?.bottomLeftKey || `${ root }-bottom-left-radius`,
	};
}

/**
 * Whether a corner value counts as "on".
 *
 * Empty is always off. By default `0` / `0px` is also off (sharp = disabled).
 * Pass `zeroIsOn` when empty means inherit and an explicit `0` is a real value.
 *
 * @param {string}  value
 * @param {object}  [options]
 * @param {boolean} [options.zeroIsOn]
 * @return {boolean}
 */
export function isRadiusCornerOn( value, options = {} ) {
	const v = String( value || '' ).trim().toLowerCase();
	if ( ! v ) {
		return false;
	}
	const isZero =
		v === '0' ||
		v === '0px' ||
		v === '0rem' ||
		v === '0em' ||
		v === '0%' ||
		v === 'none';
	if ( isZero ) {
		return Boolean( options.zeroIsOn );
	}
	return true;
}

/**
 * Normalize corner radius for storage.
 *
 * @param {boolean} on
 * @param {string}  radius
 * @param {object}  [options]
 * @param {boolean} [options.emptyWhenOff] Write '' when off (inherit) instead of 0.
 * @param {boolean} [options.allowEmpty]   Allow empty radius when on (no default).
 * @return {string}
 */
export function radiusCornerValue( on, radius, options = {} ) {
	if ( ! on ) {
		return options.emptyWhenOff ? '' : '0';
	}
	const r = String( radius ?? '' ).trim();
	if ( ! r ) {
		return options.allowEmpty ? '' : DEFAULT_BORDER_RADIUS;
	}
	return r;
}

/**
 * Split a CSS border-radius shorthand into four corner values.
 *
 * @param {string} value
 * @return {{ topLeft: string, topRight: string, bottomRight: string, bottomLeft: string }|null}
 */
export function parseRadiusShorthand( value ) {
	const parts = String( value || '' )
		.trim()
		.split( /\s+/ )
		.filter( Boolean );
	if ( ! parts.length ) {
		return null;
	}
	if ( parts.length === 1 ) {
		return {
			topLeft: parts[ 0 ],
			topRight: parts[ 0 ],
			bottomRight: parts[ 0 ],
			bottomLeft: parts[ 0 ],
		};
	}
	if ( parts.length === 2 ) {
		return {
			topLeft: parts[ 0 ],
			topRight: parts[ 1 ],
			bottomRight: parts[ 0 ],
			bottomLeft: parts[ 1 ],
		};
	}
	if ( parts.length === 3 ) {
		return {
			topLeft: parts[ 0 ],
			topRight: parts[ 1 ],
			bottomRight: parts[ 2 ],
			bottomLeft: parts[ 1 ],
		};
	}
	return {
		topLeft: parts[ 0 ],
		topRight: parts[ 1 ],
		bottomRight: parts[ 2 ],
		bottomLeft: parts[ 3 ],
	};
}

/**
 * Resolve active radius + corner flags from stored CSS vars.
 *
 * @param {object} values
 * @param {ReturnType<typeof boxRadiusKeys>} keys
 * @param {object} [options]
 * @param {boolean} [options.allowEmpty]
 * @param {boolean} [options.inheritWhenOff]
 * @param {boolean} [options.zeroIsOn]
 * @return {{ radius: string, corners: { topLeft: boolean, topRight: boolean, bottomRight: boolean, bottomLeft: boolean } }}
 */
export function resolveBoxRadiusState( values = {}, keys, options = {} ) {
	const inheritWhenOff = Boolean( options.inheritWhenOff );
	const allowEmpty = Boolean( options.allowEmpty || inheritWhenOff );
	const zeroIsOn = Boolean( options.zeroIsOn || inheritWhenOff );
	const cornerOn = ( value ) => isRadiusCornerOn( value, { zeroIsOn } );

	const read = ( key ) => String( values[ key ] || '' ).trim();
	const all = read( keys.all );
	const parsed = parseRadiusShorthand( all );
	const hasCornerVars =
		read( keys.topLeft ) ||
		read( keys.topRight ) ||
		read( keys.bottomRight ) ||
		read( keys.bottomLeft );

	const cornerVals = {
		topLeft: read( keys.topLeft ) || ( parsed ? parsed.topLeft : '' ),
		topRight: read( keys.topRight ) || ( parsed ? parsed.topRight : '' ),
		bottomRight:
			read( keys.bottomRight ) || ( parsed ? parsed.bottomRight : '' ),
		bottomLeft:
			read( keys.bottomLeft ) || ( parsed ? parsed.bottomLeft : '' ),
	};

	if ( allowEmpty && ! hasCornerVars && ! parsed ) {
		return {
			radius: '',
			corners: {
				topLeft: false,
				topRight: false,
				bottomRight: false,
				bottomLeft: false,
			},
		};
	}

	const onVals = Object.values( cornerVals ).filter( cornerOn );
	const radius =
		( onVals.length
			? onVals.find( ( v ) => v && ! /\s/.test( v ) )
			: '' ) ||
		( parsed && ! /\s/.test( all ) ? all : '' ) ||
		( allowEmpty ? '' : DEFAULT_BORDER_RADIUS );

	const corners =
		hasCornerVars || parsed
			? {
					topLeft: cornerOn( cornerVals.topLeft ),
					topRight: cornerOn( cornerVals.topRight ),
					bottomRight: cornerOn( cornerVals.bottomRight ),
					bottomLeft: cornerOn( cornerVals.bottomLeft ),
			  }
			: {
					topLeft: true,
					topRight: true,
					bottomRight: true,
					bottomLeft: true,
			  };

	return { radius, corners };
}
