export const DEVICE_ORDER = [ 'desktop', 'tablet', 'mobile' ];

export function hasResponsiveContent( value ) {
	if ( typeof value === 'boolean' ) {
		return false;
	}

	if ( Array.isArray( value ) ) {
		return value.some( hasResponsiveContent );
	}

	if ( value && typeof value === 'object' ) {
		return Object.values( value ).some( hasResponsiveContent );
	}

	return value !== undefined && value !== null && value !== '';
}

export function getInheritedResponsiveValue(
	values,
	activeDevice,
	selector = ( value ) => value
) {
	const inheritedMeta = getInheritedResponsiveMeta(
		values,
		activeDevice,
		selector
	);

	return inheritedMeta ? inheritedMeta.value : '';
}

export function getInheritedResponsiveMeta(
	values,
	activeDevice,
	selector = ( value ) => value
) {
	const activeIndex = DEVICE_ORDER.indexOf( activeDevice );

	if ( activeIndex <= 0 ) {
		return null;
	}

	for ( let index = activeIndex - 1; index >= 0; index -= 1 ) {
		const device = DEVICE_ORDER[ index ];
		const candidate = selector( values?.[ device ], device );

		if ( hasResponsiveContent( candidate ) ) {
			return {
				device,
				value: candidate,
			};
		}
	}

	return null;
}

export function getResponsivePlaceholder( {
	values,
	activeDevice,
	selector = ( value ) => value,
	fallback = '',
} ) {
	if ( activeDevice === 'desktop' ) {
		return fallback;
	}

	const inheritedValue = getInheritedResponsiveValue(
		values,
		activeDevice,
		selector
	);

	if (
		typeof inheritedValue === 'string' ||
		typeof inheritedValue === 'number'
	) {
		return String( inheritedValue );
	}

	return fallback;
}

export function getResponsiveSelectOptions( {
	values,
	activeDevice,
	options = [],
	selector = ( value ) => value,
	inheritedLabel = 'Inherited',
} ) {
	if ( activeDevice === 'desktop' || ! Array.isArray( options ) ) {
		return options;
	}

	const inheritedValue = getInheritedResponsiveValue(
		values,
		activeDevice,
		selector
	);

	if ( ! hasResponsiveContent( inheritedValue ) ) {
		return options;
	}

	const defaultIndex = options.findIndex( ( option ) => option.value === '' );

	if ( defaultIndex === -1 ) {
		return options;
	}

	const matchedOption = options.find(
		( option ) => option.value === inheritedValue
	);

	const displayValue = matchedOption?.label || String( inheritedValue );
	const nextOptions = [ ...options ];

	nextOptions[ defaultIndex ] = {
		...nextOptions[ defaultIndex ],
		label: `${ inheritedLabel }: ${ displayValue }`,
	};

	return nextOptions;
}
