<?php
/**
 * Image block styles for full-height image columns. Two opt-in styles appear in
 * the Styles panel of the Kadence Advanced Image block (and core Image block):
 *
 *   • "Cover" — image fills + crops (object-fit:cover) and stays IN FLOW, so it can
 *     also DEFINE the row height. Best when the image is the content: standalone
 *     banners, or rows of only-image columns / galleries.
 *   • "Fill Column" — image is taken OUT of flow (absolute), so it never defines
 *     the height; the row is sized by the neighbouring (text) column and the image
 *     fills/crops to match it. Best for an image beside taller text (no gap below
 *     the text). Needs an equal-height row with a taller sibling.
 *
 * Both are OPT-IN (not default). CSS loads on the front end AND in the editor
 * canvas so the preview matches. Equal-height row = Kadence "Inner column height:
 * 100%", the theme default for new rows (see inc/bw-row-defaults.php).
 *
 * @package Kadence-Child
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/* 1. Register the style so it appears in the block's Styles panel. */
add_action(
	'init',
	function () {
		foreach ( array( 'kadence/image', 'core/image' ) as $block ) {
			register_block_style(
				$block,
				array(
					'name'  => 'bw-cover',
					'label' => __( 'Cover', 'kadence-child' ),
				)
			);
			register_block_style(
				$block,
				array(
					'name'  => 'bw-fill-col',
					'label' => __( 'Fill Column', 'kadence-child' ),
				)
			);
		}
	}
);

/* 2. The CSS that the style applies (used both front end and editor). */
function bw_cover_style_css() {
	return implode(
		"\n",
		array(
			// The image block fills the column height. We rely on the column having a
			// height already — i.e. an equal-height row (the theme default). Kadence sets
			// .kt-inside-inner-col{height:100%} when equal-height is on, and drops it to
			// auto once columns stack on mobile — which is exactly what lets the fixed
			// ratio (below) come back on mobile. So we deliberately do NOT force the column
			// height ourselves; that would keep equal-height alive on mobile too.
			'.wp-block-kadence-image.is-style-bw-cover,',
			'figure.wp-block-image.is-style-bw-cover{height:100%;margin:0}',
			// The <img> fills the block and crops to cover.
			'.wp-block-kadence-image.is-style-bw-cover img,',
			'figure.wp-block-image.is-style-bw-cover img{width:100%;height:100%;object-fit:cover;display:block}',
			// If a Kadence "fixed image ratio" is ALSO set on a Cover image, let Cover win
			// on desktop (fill the column). min-height:100% only resolves when the column has
			// a real height (equal-height desktop); once columns stack the parent height goes
			// auto, min-height no-ops, and Kadence's padding-bottom ratio returns on its own —
			// so the fixed ratio is preserved on mobile automatically.
			'.wp-block-kadence-image.is-style-bw-cover .kb-is-ratio-image{min-height:100%}',
			// On mobile (where rows usually stack), give a fixed-ratio image its ratio back
			// even if the row keeps an equal-height grid: the figure hugs the ratio box and the
			// ratio box uses its own padding-bottom shape again. Uses Kadence's mobile breakpoint.
			'@media (max-width:767px){',
			'.wp-block-kadence-image.is-style-bw-cover.kb-image-is-ratio-image{height:auto}',
			'.wp-block-kadence-image.is-style-bw-cover .kb-is-ratio-image{min-height:0}',
			'}',
			// --- "Fill Column" --------------------------------------------------------
			// Unlike Cover (image stays in flow and can DEFINE the row height), Fill Column
			// makes the image CONFORM to its column and never set the height. Same desktop/
			// mobile strategy as Cover+ratio:
			//   DESKTOP (>=768px): take the image — AND any fixed-ratio wrapper — out of flow
			//   and flatten the ratio's padding-bottom, so neither can set a height; the row
			//   is sized by the text column and the image fills/crops to match it.
			//   MOBILE (<768px): columns stack with no sibling to size the image, so we apply
			//   NOTHING and let Kadence render normally — the image shows at its natural size
			//   (or its fixed ratio) instead of collapsing.
			'.wp-block-kadence-image.is-style-bw-fill-col,',
			'figure.wp-block-image.is-style-bw-fill-col{position:relative;margin:0}',
			'@media (min-width:768px){',
			'.wp-block-kadence-image.is-style-bw-fill-col,',
			// width:100% is essential: the figure is a flex item, and with the image taken
			// out of flow (absolute, below) it has no in-flow content to size it, so it
			// collapses to width:0 — the image goes invisible and any (also-absolute) overlay
			// caption wraps one letter per line. Forcing full column width gives the absolute
			// image and caption a real box to fill.
			'figure.wp-block-image.is-style-bw-fill-col{height:100%;width:100%}',
			// flatten a fixed-ratio wrapper so its padding-bottom can't set the height
			'.wp-block-kadence-image.is-style-bw-fill-col .kb-is-ratio-image{position:absolute;inset:0;padding-bottom:0}',
			// the image fills the column and crops
			'.wp-block-kadence-image.is-style-bw-fill-col img,',
			'figure.wp-block-image.is-style-bw-fill-col img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}',
			'}',
			// --- Captions (overlay) --------------------------------------------------
			// Captions render as white text at the bottom-left of the image, on a subtle
			// dark gradient (brand style) — overlaid, so the image keeps filling. Works for
			// Default, Cover and Fill Column images (and ratio images). Loaded front end +
			// editor so the preview matches.
			'.wp-block-kadence-image:has(> figcaption),',
			'figure.wp-block-image:has(> figcaption){position:relative}',
			'.wp-block-kadence-image > figcaption,',
			'figure.wp-block-image > figcaption{position:absolute;left:0;right:0;bottom:0;z-index:3;margin:0;'
				. 'padding:1.9rem 1.1rem .8rem;color:#fff;text-align:left;font-size:1rem;line-height:1.3;'
				. 'font-weight:600;text-shadow:0 1px 2px rgba(0,0,0,.4);'
				. 'background:linear-gradient(to top,rgba(0,0,0,.72) 0%,rgba(0,0,0,.28) 55%,transparent 100%)}',
		)
	);
}

/* 3a. Load it on the front end (inline — no separate stylesheet file). */
add_action(
	'wp_enqueue_scripts',
	function () {
		wp_register_style( 'bw-cover', false ); // phpcs:ignore -- inline-only handle
		wp_enqueue_style( 'bw-cover' );
		wp_add_inline_style( 'bw-cover', bw_cover_style_css() );
	}
);

/* 3b. Load it inside the block-editor canvas (iframe) so the preview matches. */
add_filter(
	'block_editor_settings_all',
	function ( $settings ) {
		$settings['styles'][] = array( 'css' => bw_cover_style_css() );

		// Editor-only fixes so the canvas matches the front end (verified against the live
		// editor DOM). These selectors target editor internals, so they live ONLY in the
		// editor canvas — never shipped to the front end.
		$editor = implode(
			"\n",
			array(
				// (1) The editor canvas iframe is narrow (~600px), so our front-end mobile
				// media query (max-width:767px) wrongly fires even in DESKTOP preview and
				// restores the ratio. In desktop preview, force desktop Cover back on.
				'.is-desktop-preview .wp-block-kadence-image.is-style-bw-cover.kb-image-is-ratio-image{height:100%!important}',
				'.is-desktop-preview .wp-block-kadence-image.is-style-bw-cover .kb-is-ratio-image{min-height:100%!important}',
				// (2) Gutenberg wraps the <img> in .components-resizable-box__container (its
				// resize handles), which sits at the image's natural height and breaks the
				// height chain. Pass height through it so the image fills the figure.
				'.wp-block-kadence-image.is-style-bw-cover .components-resizable-box__container,',
				'.wp-block-kadence-image.is-style-bw-cover .components-resizable-box__container>div{height:100%!important}',
				'.wp-block-kadence-image.is-style-bw-cover img{height:100%!important}',
				// Fill Column in the editor: the front-end uses absolute positioning, but in the
				// canvas that collapses Gutenberg's resize wrapper to ~30px and the image becomes
				// a sliver. So in the EDITOR we display it exactly like Cover — image IN FLOW,
				// height:100% + object-fit:cover via the resize-box bridge. It LOOKS filled for
				// the author; the real (absolute) behaviour only matters on the front end.
				'.is-desktop-preview .wp-block-kadence-image.is-style-bw-fill-col{height:100%!important}',
				'.is-desktop-preview .wp-block-kadence-image.is-style-bw-fill-col .kb-is-ratio-image{min-height:100%!important}',
				'.is-desktop-preview .wp-block-kadence-image.is-style-bw-fill-col .components-resizable-box__container,',
				'.is-desktop-preview .wp-block-kadence-image.is-style-bw-fill-col .components-resizable-box__container>div{height:100%!important}',
				'.is-desktop-preview .wp-block-kadence-image.is-style-bw-fill-col img{position:static!important;width:100%!important;height:100%!important;object-fit:cover}',
			)
		);
		$settings['styles'][] = array( 'css' => $editor );
		return $settings;
	}
);
