/**
 * Persist linked / axial / sides UI mode for spacing & border controls.
 * Stored as a CSS custom property on the block (not used for layout).
 */

export const LINK_MODES = [ 'linked', 'axial', 'sides' ];

/**
 * @param {unknown} value
 * @return {'linked'|'axial'|'sides'|''}
 */
export function normalizeLinkMode( value ) {
	const v = String( value || '' )
		.trim()
		.toLowerCase();
	return LINK_MODES.includes( v ) ? v : '';
}

/**
 * Build a link-mode CSS var from a side/root key.
 *
 * `--bm-padding-top` → `--bm-padding-link-mode`
 * `padding-top` → `padding-link-mode` (element-relative; ElementToolbar prefixes)
 *
 * @param {string} sideOrRootKey
 * @return {string}
 */
export function linkModeKeyFromSideKey( sideOrRootKey ) {
	const raw = String( sideOrRootKey || '' ).trim();
	if ( ! raw ) {
		return '';
	}
	const root = raw.replace( /-(?:top|right|bottom|left)$/i, '' );
	if ( ! root || root === raw ) {
		return `${ raw }-link-mode`;
	}
	return `${ root }-link-mode`;
}

/**
 * @param {{ key?: string }[]} sides
 * @param {string} [explicit]
 * @return {string}
 */
export function resolveLinkModeKey( sides = [], explicit = '' ) {
	const fromProp = String( explicit || '' ).trim();
	if ( fromProp ) {
		return fromProp;
	}
	return linkModeKeyFromSideKey( sides[ 0 ]?.key || '' );
}

/**
 * Infer spacing link mode from side values (fallback when none stored).
 *
 * @param {{ key: string }[]} sides
 * @param {Record<string, string>} values
 * @return {'linked'|'axial'|'sides'}
 */
export function inferSpacingLinkMode( sides, values ) {
	const count = sides.length;
	const vals = sides.map( ( s ) => String( values[ s.key ] ?? '' ).trim() );
	const filled = vals.filter( ( v ) => v !== '' );
	const unique = [ ...new Set( filled ) ];

	if ( count < 4 ) {
		if ( filled.length <= 1 || unique.length <= 1 ) {
			return 'linked';
		}
		return 'sides';
	}

	const [ top, right, bottom, left ] = vals;
	const onTop = top !== '';
	const onRight = right !== '';
	const onBottom = bottom !== '';
	const onLeft = left !== '';
	const onCount =
		( onTop ? 1 : 0 ) +
		( onRight ? 1 : 0 ) +
		( onBottom ? 1 : 0 ) +
		( onLeft ? 1 : 0 );

	if ( onCount === 0 ) {
		return 'linked';
	}

	// One side set (others empty) → show all four fields.
	if ( onCount === 1 ) {
		return 'sides';
	}

	const onlyVertical = ( onTop || onBottom ) && ! onLeft && ! onRight;
	const onlyHorizontal = ( onLeft || onRight ) && ! onTop && ! onBottom;

	if ( onlyVertical && onTop && onBottom && top === bottom ) {
		return 'axial';
	}
	if ( onlyHorizontal && onLeft && onRight && left === right ) {
		return 'axial';
	}

	if (
		onCount === 4 &&
		top === right &&
		right === bottom &&
		bottom === left
	) {
		return 'linked';
	}

	if (
		onCount === 4 &&
		top === bottom &&
		left === right &&
		top !== left
	) {
		return 'axial';
	}

	// Asymmetric or partial fills with differing values.
	if ( unique.length > 1 ) {
		return 'sides';
	}

	// Multiple sides set to the same value — still prefer linked.
	return 'linked';
}
