/**
 * Shared slider config + hero slide flatten helpers (JS interpolator / preview).
 */

import {
	composeButtonInlineStyleVars,
	createDefaultHeroButton,
	normalizeButtonStyleItem,
} from './buttonStyleBaseline';
import { buildButtonIconTokens } from './buttonIconTokens';
import { defaultSlideLayoutCssVars } from './slideLayoutStyle';
import { SLIDE_LAYOUT_ELEMENTS } from './sliderElements';
import {
	TITLE_ALLOWED_COMMANDS,
	sanitizeAllowedHtml,
} from './allowedHtml';

function truthy( value, fallback = false ) {
	if ( value === true || value === 1 || value === '1' || value === 'true' ) {
		return true;
	}
	if ( value === false || value === 0 || value === '0' || value === 'false' ) {
		return false;
	}
	if ( value == null || value === '' ) {
		return fallback;
	}
	return Boolean( value );
}

function escapeHtml( str ) {
	return String( str || '' )
		.replace( /&/g, '&amp;' )
		.replace( /</g, '&lt;' )
		.replace( />/g, '&gt;' )
		.replace( /"/g, '&quot;' );
}

/**
 * Resolve plugin-bundled media URLs (`bm-asset:path`).
 * Kept local to avoid a circular import with interpolate.js.
 *
 * @param {string} url
 * @return {string}
 */
function resolveMediaUrl( url ) {
	const raw = String( url || '' ).trim();
	if ( ! raw.startsWith( 'bm-asset:' ) ) {
		return raw;
	}
	const rel = raw.slice( 'bm-asset:'.length ).replace( /^\//, '' );
	const base = String(
		( typeof window !== 'undefined' &&
			( window.jocbmEditor?.pluginUrl ||
				window.jocbmAdmin?.pluginUrl ||
				window.jocbmFront?.pluginUrl ) ) ||
			''
	).replace( /\/?$/, '/' );
	return base && base !== '/' ? `${ base }${ rel }` : rel;
}

function sanitizeTag( tag, fallback = 'h2' ) {
	const t = String( tag || fallback ).toLowerCase().replace( /[^a-z0-9]/g, '' );
	const allowed = [ 'div', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ];
	return allowed.includes( t ) ? t : fallback;
}

function normalizeLink( link = {} ) {
	return {
		title: String( link.title || '' ),
		url: String( link.url || '' ),
		opensInNewTab: Boolean( link.opensInNewTab ),
	};
}

/**
 * Animation effects available on the hero slider.
 * `slide` uses Splide’s horizontal move; the rest use fade + CSS.
 */
export const SLIDER_EFFECTS = [
	'slide',
	'fade',
	'zoom',
	'fade-up',
	'fade-down',
	'blur',
];

/**
 * Normalize effect → Splide type + CSS effect slug.
 *
 * @param {string} effect
 * @return {{ type: 'loop'|'fade', effect: string }}
 */
export function resolveSliderEffect( effect ) {
	let raw = String( effect || 'slide' )
		.toLowerCase()
		.trim();
	// Legacy “loop” was continuous slide — keep that motion as Slide.
	if ( raw === 'loop' || raw === 'rewind' ) {
		raw = 'slide';
	}
	if ( ! SLIDER_EFFECTS.includes( raw ) ) {
		raw = 'slide';
	}
	if ( raw === 'slide' ) {
		return { type: 'loop', effect: 'slide' };
	}
	return { type: 'fade', effect: raw };
}

/**
 * CSS class for the active animation effect.
 *
 * @param {string} effect
 * @return {string}
 */
export function sliderEffectClass( effect ) {
	const { effect: slug } = resolveSliderEffect( effect );
	return `bm-slider--effect-${ slug }`;
}

/** @type {readonly string[]} */
export const SLIDER_ARROW_SIZES = [ 'sm', 'md', 'lg', 'xl', 'xxl', 'xxxl' ];

/**
 * @param {string} size
 * @return {string}
 */
export function resolveSliderArrowSize( size ) {
	const raw = String( size || 'md' )
		.toLowerCase()
		.trim();
	return SLIDER_ARROW_SIZES.includes( raw ) ? raw : 'md';
}

/**
 * @param {string} size
 * @return {string}
 */
export function sliderArrowSizeClass( size ) {
	return `bm-slider--arrow-${ resolveSliderArrowSize( size ) }`;
}

/** @type {readonly string[]} */
export const SLIDER_ARROW_BEHAVIORS = [ 'fixed', 'hover' ];

/**
 * @param {string} behavior
 * @return {string}
 */
export function resolveSliderArrowBehavior( behavior ) {
	const raw = String( behavior || 'fixed' )
		.toLowerCase()
		.trim();
	return SLIDER_ARROW_BEHAVIORS.includes( raw ) ? raw : 'fixed';
}

/**
 * @param {string} behavior
 * @return {string}
 */
export function sliderArrowBehaviorClass( behavior ) {
	return `bm-slider--arrows-${ resolveSliderArrowBehavior( behavior ) }`;
}

/**
 * @param {object} attrs Block attributes
 * @return {object}
 */
export function buildSliderConfig( attrs = {} ) {
	const resolved = resolveSliderEffect( attrs.effect );
	return {
		type: resolved.type,
		effect: resolved.effect,
		arrowSize: resolveSliderArrowSize( attrs.arrowSize ),
		arrowBehavior: resolveSliderArrowBehavior( attrs.arrowBehavior ),
		speed: Number( attrs.speed ) > 0 ? Number( attrs.speed ) : 400,
		autoplay: truthy( attrs.autoplay, false ),
		interval:
			Number( attrs.autoplayInterval ?? attrs.interval ) > 0
				? Number( attrs.autoplayInterval ?? attrs.interval )
				: 4000,
		arrows: truthy( attrs.enableArrow ?? attrs.arrows, true ),
		pagination: truthy( attrs.enableDots ?? attrs.pagination, true ),
		drag: truthy( attrs.drag ?? attrs.swipe, true ),
		equalHeight: truthy( attrs.equalHeight, true ),
		rewind: resolved.type !== 'loop',
	};
}

/**
 * HTML-escaped JSON for data-bm-slider="…".
 *
 * @param {object} attrs
 * @return {string}
 */
export function sliderConfigAttr( attrs = {} ) {
	return JSON.stringify( buildSliderConfig( attrs ) ).replace( /"/g, '&quot;' );
}

/**
 * Resolve button styles (custom + optional library bag from flattenButton).
 *
 * @param {object} item
 * @param {Function|null} flattenButton
 * @param {number} index
 * @return {object}
 */
function resolveSlideButton( item, flattenButton, index ) {
	if ( typeof flattenButton === 'function' ) {
		return flattenButton( item, index );
	}
	const link = normalizeLink( item?.link || {} );
	const styles = normalizeButtonStyleItem( item || {} );
	const iconTokens = buildButtonIconTokens( {
		icon: styles.icon,
		iconPosition: styles.iconPosition,
		iconSize: styles.iconSize,
		iconColor: styles.iconColor,
	} );
	const title = String( link.title || '' ).trim();
	return {
		link,
		'link.url': link.url,
		'link.targetAttr': link.opensInNewTab
			? ' target="_blank" rel="noopener noreferrer"'
			: '',
		btnStyle: composeButtonInlineStyleVars( styles ),
		btnIconFlex: iconTokens.btnIconFlex || 'row',
		iconHtml: iconTokens.iconHtml || '',
		labelHtml: title
			? `<span class="bm-hero__btn-label">${ escapeHtml( title ) }</span>`
			: '',
		'@index': String( index ),
	};
}

/**
 * Build buttons + logos HTML for a slide (mirrors hero partials).
 *
 * @param {object} item
 * @param {object} opts
 * @return {{ buttonsHtml: string, logosHtml: string, buttons: Array, logos: Array }}
 */
function buildSlideActionsHtml( item, opts = {} ) {
	const { flattenButton = null } = opts;
	let buttons = Array.isArray( item?.buttons ) ? item.buttons : [];
	const logos = Array.isArray( item?.logos ) ? item.logos : [];

	// Migrate legacy CTA fields.
	if ( ! buttons.length ) {
		const ctaLabel = String( item?.ctaLabel || '' ).trim();
		const ctaUrl = String( item?.ctaUrl || '#' ).trim() || '#';
		if ( ctaLabel ) {
			buttons = [
				createDefaultHeroButton( {
					link: {
						title: ctaLabel,
						url: ctaUrl,
						opensInNewTab: false,
					},
					shadow: '0 12px 28px rgba(19, 27, 46, 0.18)',
				} ),
			];
		}
	}

	const btnParts = [];
	buttons.forEach( ( raw, i ) => {
		const hidden = raw?.hidden;
		if (
			hidden === true ||
			hidden === 1 ||
			hidden === '1' ||
			hidden === 'true'
		) {
			return;
		}
		const ctx = resolveSlideButton( raw, flattenButton, i );
		if ( ! ctx.labelHtml && ! ctx.iconHtml ) {
			return;
		}
		const href = escapeHtml( ctx['link.url'] || ctx.link?.url || '#' );
		const targetAttr = ctx['link.targetAttr'] || '';
		btnParts.push(
			`<a class="bm-hero__btn" data-bm-btn-index="${ i }" href="${ href }"${ targetAttr } style="display:inline-flex;align-items:center;gap:0.45em;flex-direction:${ ctx.btnIconFlex || 'row' };text-decoration:none;border-style:var(--bm-btn-border-style, none);border-color:var(--bm-btn-border-color, transparent);border-top-width:var(--bm-btn-border-top-width, var(--bm-btn-border-width, 0));border-right-width:var(--bm-btn-border-right-width, var(--bm-btn-border-width, 0));border-bottom-width:var(--bm-btn-border-bottom-width, var(--bm-btn-border-width, 0));border-left-width:var(--bm-btn-border-left-width, var(--bm-btn-border-width, 0));border-top-left-radius:var(--bm-btn-border-top-left-radius, var(--bm-btn-radius, 8px));border-top-right-radius:var(--bm-btn-border-top-right-radius, var(--bm-btn-radius, 8px));border-bottom-right-radius:var(--bm-btn-border-bottom-right-radius, var(--bm-btn-radius, 8px));border-bottom-left-radius:var(--bm-btn-border-bottom-left-radius, var(--bm-btn-radius, 8px));padding:var(--bm-btn-pad-y, var(--bm-buttons-pad-y, 0.75rem)) var(--bm-btn-pad-x, var(--bm-buttons-pad-x, 1.25rem));box-shadow:var(--bm-btn-shadow, none);font-size:var(--bm-btn-font-size, 1rem);font-weight:600;${ ctx.btnStyle || '' }">${ ctx.iconHtml || '' }${ ctx.labelHtml || '' }</a>`
		);
	} );

	const buttonsHtml = btnParts.length
		? `<div class="bm-hero__buttons" data-bm-el="buttons" style="display:flex;flex-wrap:wrap;justify-content:var(--bm-justify-content, var(--bm-align-items, center));align-items:center;gap:var(--bm-buttons-gap, 0.75rem);flex-direction:var(--bm-buttons-flex-direction, row);margin:var(--bm-buttons-margin-top, 0.5rem) 0 var(--bm-buttons-margin-bottom, 0);width:100%">${ btnParts.join( '' ) }</div>`
		: '';

	const logoParts = [];
	logos.forEach( ( logo ) => {
		const image =
			logo?.image && typeof logo.image === 'object' ? logo.image : {};
		const url = resolveMediaUrl( String( image.url || '' ).trim() );
		if ( ! url ) {
			return;
		}
		const alt = escapeHtml( image.alt || '' );
		logoParts.push(
			`<img class="bm-hero__logo" src="${ escapeHtml( url ) }" alt="${ alt }" loading="lazy" decoding="async" style="display:block;height:var(--bm-logos-height, 2.75rem);width:auto;max-width:100%;object-fit:contain" />`
		);
	} );

	const logosHtml = logoParts.length
		? `<div class="bm-hero__logos" data-bm-el="logos" style="display:flex;flex-wrap:wrap;justify-content:var(--bm-justify-content, var(--bm-align-items, center));align-items:center;gap:var(--bm-logos-gap, 1.5rem);margin:var(--bm-logos-margin-top, 1rem) 0 var(--bm-logos-margin-bottom, 0);width:100%">${ logoParts.join( '' ) }</div>`
		: '';

	return { buttonsHtml, logosHtml, buttons, logos };
}

/** Default content stack order for one hero slide (simple layout). */
export const DEFAULT_SLIDE_ELEMENTS_ORDER = [
	...( SLIDE_LAYOUT_ELEMENTS.simple || [
		'badge',
		'header',
		'subheader',
		'image',
		'buttons',
		'logos',
	] ),
];

/**
 * Resolve slide content element order (badge, header, …).
 *
 * @param {string[]} [order]
 * @param {string}   [layout]
 * @return {string[]}
 */
function resolveSlideContentOrder( order, layout = 'simple' ) {
	const defaults =
		SLIDE_LAYOUT_ELEMENTS[ String( layout || 'simple' ).toLowerCase() ] ||
		SLIDE_LAYOUT_ELEMENTS.simple;
	const next =
		Array.isArray( order ) && order.length
			? order.filter( ( k ) => defaults.includes( k ) )
			: [ ...defaults ];
	defaults.forEach( ( key ) => {
		if ( ! next.includes( key ) ) {
			next.push( key );
		}
	} );
	return next;
}

/**
 * Build inner HTML for one hero slide.
 *
 * @param {object} item Slide attrs
 * @param {number} index
 * @param {Function} mediaToHtml (media, elKey) => string
 * @param {{ flattenButton?: Function, elementsOrder?: string[] }} [opts]
 * @return {object} Flattened token map including slideHtml
 */
export function flattenSlideItem( item, index, mediaToHtml, opts = {} ) {
	const layout = String( item?.layout || 'simple' ).toLowerCase();
	const badge = String( item?.badge || '' ).trim();
	const header = String( item?.header || '' ).trim();
	const subheader = String( item?.subheader || '' ).trim();
	const headerTag = sanitizeTag( item?.headerTag, 'h2' );
	const subheaderTag = sanitizeTag( item?.subheaderTag || 'div', 'div' );

	const image =
		item?.image && typeof item.image === 'object' ? item.image : {};
	const video =
		item?.video && typeof item.video === 'object' ? item.video : {};

	const imageHtml =
		typeof mediaToHtml === 'function' ? mediaToHtml( image, 'image' ) : '';
	const videoUrl = resolveMediaUrl( String( video.url || '' ).trim() );

	const { buttonsHtml, logosHtml, buttons, logos } = buildSlideActionsHtml(
		item,
		{
			flattenButton: opts.flattenButton,
		}
	);

	/*
	 * Simple layout: put the media frame (data-bm-el="image") directly in the
	 * content flex stack — same as main hero partials. An extra .bm-hero__media
	 * wrapper without data-bm-el broke CSS `order` for Media.
	 * Column layouts keep media in its own grid column (not in this stack).
	 */
	const fragments = {
		badge: badge
			? `<span class="bm-hero__badge" data-bm-el="badge" style="display:inline-block;font-size:var(--bm-badge-font-size);font-weight:var(--bm-badge-font-weight);line-height:var(--bm-badge-line-height);letter-spacing:var(--bm-badge-letter-spacing);color:var(--bm-badge-color, var(--bm-text));background:var(--bm-badge-bg);margin-top:var(--bm-badge-margin-top, 0);margin-bottom:var(--bm-badge-margin-bottom, 0);padding:0.35rem 0.75rem;border-style:var(--bm-badge-border-style, none);border-color:var(--bm-badge-border-color, transparent);border-top-width:var(--bm-badge-border-top-width, var(--bm-badge-border-width, 0));border-right-width:var(--bm-badge-border-right-width, var(--bm-badge-border-width, 0));border-bottom-width:var(--bm-badge-border-bottom-width, var(--bm-badge-border-width, 0));border-left-width:var(--bm-badge-border-left-width, var(--bm-badge-border-width, 0));border-top-left-radius:var(--bm-badge-border-top-left-radius, var(--bm-badge-border-radius, 4px));border-top-right-radius:var(--bm-badge-border-top-right-radius, var(--bm-badge-border-radius, 4px));border-bottom-right-radius:var(--bm-badge-border-bottom-right-radius, var(--bm-badge-border-radius, 4px));border-bottom-left-radius:var(--bm-badge-border-bottom-left-radius, var(--bm-badge-border-radius, 4px));box-shadow:var(--bm-badge-shadow, none);box-sizing:border-box">${ escapeHtml( badge ) }</span>`
			: '',
		header: header
			? `<${ headerTag } class="bm-hero__header" data-bm-el="header" style="font-size:var(--bm-header-font-size);font-weight:var(--bm-header-font-weight);line-height:var(--bm-header-line-height);color:var(--bm-header-color, var(--bm-text));margin:0;align-self:stretch;width:100%;box-sizing:border-box">${ sanitizeAllowedHtml( header, TITLE_ALLOWED_COMMANDS ) }</${ headerTag }>`
			: '',
		subheader: subheader
			? `<${ subheaderTag } class="bm-hero__subheader" data-bm-el="subheader" style="font-size:var(--bm-subheader-font-size);font-weight:var(--bm-subheader-font-weight);line-height:var(--bm-subheader-line-height);color:var(--bm-subheader-color, var(--bm-text));margin:0;align-self:stretch;width:100%;box-sizing:border-box">${ sanitizeAllowedHtml( subheader, null ) }</${ subheaderTag }>`
			: '',
		buttons: buttonsHtml,
		logos: logosHtml,
		image: layout === 'simple' ? imageHtml : '',
	};

	const contentHtml = resolveSlideContentOrder(
		opts.elementsOrder ?? item?.elementsOrder,
		layout
	)
		.map( ( key ) => fragments[ key ] || '' )
		.filter( Boolean )
		.join( '' );

	let slideHtml = '';
	const sectionStyle =
		'position:relative;overflow:visible;display:flex;flex-direction:column;justify-content:center;box-sizing:border-box;background-color:var(--bm-bg);background-image:var(--bm-bg-image, none),var(--bm-bg-gradient, none);background-size:cover;background-position:center;color:var(--bm-text);min-height:var(--bm-min-height, 28rem);padding-top:var(--bm-padding-top, var(--bm-padding-y));padding-right:var(--bm-padding-right, var(--bm-padding-x));padding-bottom:var(--bm-padding-bottom, var(--bm-padding-y));padding-left:var(--bm-padding-left, var(--bm-padding-x))';

	const slideIndexAttr = ` data-bm-slide-index="${ index }"`;
	if ( layout === 'video-background' ) {
		const videoTag = videoUrl
			? `<video class="bm-hero__video" data-bm-el="video" src="${ escapeHtml( videoUrl ) }" autoplay muted loop playsinline aria-hidden="true" style="position:absolute;top:0;right:0;bottom:0;left:0;z-index:0;width:100%;height:100%;object-fit:cover;pointer-events:none"></video>`
			: '';
		slideHtml = `<section class="bm-hero bm-hero--video bm-hero--slide"${ slideIndexAttr } data-layout="video-background" style="${ sectionStyle }">${ videoTag }<div class="bm-hero__overlay" aria-hidden="true" style="position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;background:var(--bm-overlay);pointer-events:none"></div><div class="bm-hero__inner" style="position:relative;z-index:1;display:flex;flex-direction:column;align-items:var(--bm-align-items, center);gap:var(--bm-gap);max-width:var(--bm-content-max-width, 48rem);width:100%;margin:var(--bm-inner-margin, 0 auto);text-align:var(--bm-text-align, center)">${ contentHtml }</div></section>`;
	} else if ( layout === 'image-left' || layout === 'image-right' ) {
		/*
		 * Match main hero column templates: image-left = media then content,
		 * image-right = content then media. Do not rely on inline `order` alone —
		 * wp_kses strips CSS `order` on the frontend, which left media-right
		 * looking like media-left.
		 */
		const mod = layout === 'image-right' ? 'image-right' : 'image-left';
		const mediaCell = `<div class="bm-hero__media" style="order:var(--bm-media-order, 0);width:var(--bm-mf-media-width, 100%);max-width:var(--bm-mf-media-max-width, 100%);height:var(--bm-mf-media-height, auto);align-self:var(--bm-mf-media-align-self, auto);display:flex;flex-direction:column;align-items:var(--bm-mf-media-align-items, var(--bm-align-items, flex-start));margin-left:var(--bm-mf-margin-left, 0);margin-right:var(--bm-mf-margin-right, 0);box-sizing:border-box">${ imageHtml }</div>`;
		const contentCell = `<div class="bm-hero__content" style="display:flex;flex-direction:column;justify-content:center;align-items:var(--bm-align-items, flex-start);gap:var(--bm-gap);text-align:var(--bm-text-align, left);order:var(--bm-content-order, 0)">${ contentHtml }</div>`;
		const columns =
			layout === 'image-right'
				? `${ contentCell }${ mediaCell }`
				: `${ mediaCell }${ contentCell }`;
		slideHtml = `<section class="bm-hero bm-hero--${ mod } bm-hero--slide"${ slideIndexAttr } data-layout="${ mod }" style="${ sectionStyle }"><div class="bm-hero__overlay" aria-hidden="true" style="position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;background:var(--bm-overlay);pointer-events:none"></div><div class="bm-hero__grid" style="position:relative;z-index:1;display:grid;grid-template-columns:var(--bm-grid-template-columns, minmax(0,1fr) minmax(0,1fr));gap:var(--bm-columns-gap, var(--bm-gap));align-items:var(--bm-mf-grid-align, center);max-width:var(--bm-content-max-width, 72rem);width:100%;margin:var(--bm-inner-margin, 0 auto)">${ columns }</div></section>`;
	} else {
		slideHtml = `<section class="bm-hero bm-hero--simple bm-hero--slide"${ slideIndexAttr } data-layout="simple" style="${ sectionStyle };text-align:var(--bm-text-align, center)"><div class="bm-hero__overlay" aria-hidden="true" style="position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;background:var(--bm-overlay);pointer-events:none"></div><div class="bm-hero__inner" style="position:relative;z-index:1;display:flex;flex-direction:column;align-items:var(--bm-align-items, center);gap:var(--bm-gap);max-width:var(--bm-content-max-width, 48rem);width:100%;margin:var(--bm-inner-margin, 0 auto)">${ contentHtml }</div></section>`;
	}

	return {
		...( item || {} ),
		layout,
		badge,
		header,
		subheader,
		headerTag,
		subheaderTag,
		buttons,
		logos,
		image,
		video,
		'image.html': imageHtml,
		'video.url': videoUrl,
		slideHtml,
		'@index': String( index ),
	};
}

/**
 * Whether attrs include any hero-style buttons (top-level or in slides).
 *
 * @param {object} attrs
 * @return {boolean}
 */
export function attrsHaveHeroButtons( attrs = {} ) {
	if ( Array.isArray( attrs.buttons ) && attrs.buttons.length ) {
		return true;
	}
	if ( Array.isArray( attrs.slides ) ) {
		const inSlides = attrs.slides.some(
			( slide ) =>
				( Array.isArray( slide?.buttons ) && slide.buttons.length > 0 ) ||
				String( slide?.ctaLabel || '' ).trim() !== ''
		);
		if ( inSlides ) {
			return true;
		}
	}
	if ( Array.isArray( attrs.cards ) ) {
		const inCards = attrs.cards.some(
			( card ) =>
				Array.isArray( card?.buttons ) && card.buttons.length > 0
		);
		if ( inCards ) {
			return true;
		}
	}
	if ( Array.isArray( attrs.items ) ) {
		const inItems = attrs.items.some(
			( item ) =>
				Array.isArray( item?.buttons ) && item.buttons.length > 0
		);
		if ( inItems ) {
			return true;
		}
	}
	if ( Array.isArray( attrs.tabs ) ) {
		return attrs.tabs.some(
			( tab ) => Array.isArray( tab?.buttons ) && tab.buttons.length > 0
		);
	}
	return false;
}

/** Minimum slides to keep in a hero slider (hide remove at this count). */
export const MIN_HERO_SLIDES = 2;

/**
 * New hero slider slide with sensible defaults.
 *
 * @param {object} [overrides]
 * @return {object}
 */
export function createDefaultHeroSlide( overrides = {} ) {
	const layout = String( overrides.layout || 'simple' ).toLowerCase();
	const base = {
		layout: layout || 'simple',
		badge: '',
		header: 'New slide',
		subheader: 'Add your message here.',
		headerTag: 'h2',
		subheaderTag: 'div',
		image: {
			id: 0,
			url: 'bm-asset:assets/images/image-placeholder.jpg',
			alt: '',
			mime: 'image/jpeg',
			type: 'image',
		},
		video: {
			id: 0,
			url: '',
			alt: '',
			mime: '',
			type: 'video',
		},
		buttons: [ createDefaultHeroButton() ],
		logos: [],
		elementsOrder: {
			desktop: [
				...( SLIDE_LAYOUT_ELEMENTS[ layout ] ||
					SLIDE_LAYOUT_ELEMENTS.simple ),
			],
		},
		elementsVisibility: {
			badge: true,
			header: true,
			subheader: true,
			image: true,
			buttons: true,
			logos: true,
		},
		cssVars: defaultSlideLayoutCssVars( layout || 'simple' ),
	};
	const merged = {
		...base,
		...( overrides && typeof overrides === 'object' ? overrides : {} ),
		layout: String( overrides.layout || base.layout ).toLowerCase() || 'simple',
	};
	if ( ! merged.cssVars ) {
		merged.cssVars = defaultSlideLayoutCssVars( merged.layout );
	}
	return merged;
}
