<?php

namespace DIFL\Server\Modules\BackgroundSwitcher;

if (!defined('ABSPATH')) {
	die('Direct access forbidden.');
}

use ET\Builder\FrontEnd\Module\Style;
use ET\Builder\Packages\Module\Layout\Components\StyleCommon\CommonStyle;
use ET\Builder\Packages\Module\Options\Css\CssStyle;

trait Styles {

	public static function custom_css() {
		return \WP_Block_Type_Registry::get_instance()->get_registered('difl/backgroundswitcher')->customCssFields;
	}

	/**
	 * Extract a style_settings subfield as a responsive attr structure,
	 * appending $suffix. Keep IN SYNC with module-styles.jsx extractStyleAttr().
	 */
	private static function extract_style_attr($attrs, $field, $default = '', $suffix = 'px') {
		$result = [];
		foreach (['desktop', 'tablet', 'phone'] as $bp) {
			$val = $attrs['style_settings']['innerContent'][$bp]['value'][$field] ?? null;
			if ($val !== null && $val !== '') {
				$result[$bp] = ['value' => $val . $suffix];
			}
		}
		if (empty($result) && $default !== '') {
			$result['desktop'] = ['value' => $default . $suffix];
		}
		return $result;
	}

	/**
	 * Build a responsive attr for a bgs_settings layout subfield, filling each breakpoint with the
	 * user's value or the per-breakpoint default, so the PHONE default actually emits as CSS (else
	 * the desktop value cascades onto phone and beats the SCSS media query). tablet emits only when
	 * the user set it. Keep IN SYNC with module-styles.jsx layoutAttrWithDefaults().
	 */
	private static function layout_attr_with_defaults(array $inner, string $sub, array $defaults): array {
		$out = [];
		foreach (['desktop', 'tablet', 'phone'] as $bp) {
			$u   = $inner[$bp]['value'][$sub] ?? null;
			$val = ($u !== null && $u !== '') ? $u : ($defaults[$bp] ?? null);
			if ($val !== null && $val !== '') {
				$out[$bp] = ['value' => [$sub => $val]];
			}
		}
		return $out;
	}

	/**
	 * Responsive flex-direction from bgs_settings.flex_direction. Keep IN SYNC with
	 * module-styles.jsx flexDirectionDeclaration().
	 */
	public static function flex_direction_style(array $args): string {
		$v = $args['attrValue']['flex_direction'] ?? '';
		if ('horizontal' === $v) {
			return 'flex-direction: row;';
		}
		if ('vertical' === $v) {
			return 'flex-direction: column;';
		}
		return '';
	}

	/**
	 * Responsive Hover Blur (--bgs-blur) from style_settings.hover_blur. Bare number,
	 * px appended. declarationFunction so tablet/phone media queries apply. Keep IN
	 * SYNC with module-styles.jsx hoverBlurDeclaration().
	 */
	public static function hover_blur_style(array $args): string {
		$v = $args['attrValue']['hover_blur'] ?? '';
		if ('' === $v || null === $v) {
			return '';
		}
		return "--bgs-blur: {$v}px;";
	}

	/**
	 * Responsive Divider Width (--bgs-divider-width) from style_settings.divider_width.
	 * Bare number, px appended. Drives the inter-panel gap + the divider overlay. Keep
	 * IN SYNC with module-styles.jsx dividerWidthDeclaration().
	 */
	public static function divider_width_style(array $args): string {
		$v = $args['attrValue']['divider_width'] ?? '';
		if ('' === $v || null === $v) {
			return '';
		}
		return "--bgs-divider-width: {$v}px;";
	}

	/** Responsive grid columns from bgs_settings.grid_columns. */
	public static function grid_columns_style(array $args): string {
		$n = intval($args['attrValue']['grid_columns'] ?? 0);
		if ($n < 1) {
			return '';
		}
		return "grid-template-columns: repeat({$n}, 1fr);";
	}

	/**
	 * When the module has a border radius, clip inner elements (images/overlays/
	 * content) to the rounded corners. Mirrors the FAQ module pattern. Keep IN SYNC
	 * with module-styles.jsx border_overflow_style().
	 */
	public static function border_overflow_style(array $args): string {
		$r = $args['attrValue']['radius'] ?? [];
		$has = isset($r['topLeft']) || isset($r['topRight'])
			|| isset($r['bottomLeft']) || isset($r['bottomRight']);
		return $has ? 'overflow: hidden !important;' : '';
	}

	/**
	 * Zoom amount for the bg image effect from bgs_settings.animation_intensity -> --bgs-zoom.
	 * Raw percentage number; the SCSS does the /100 in calc(). Keep IN SYNC with module-styles.jsx.
	 */
	public static function animation_intensity_style(array $args): string {
		$raw = $args['attrValue']['animation_intensity'] ?? '';
		if ('' === $raw || null === $raw) {
			return '';
		}
		$n = intval($raw);
		return "--bgs-zoom: {$n};";
	}

	/**
	 * Active Border Color: recolor the active panel's real border from
	 * style_settings.active_border_color. Emitted only when set so an unset color
	 * never clobbers the default border. The :not(.df_bg_switcher--progress-active)
	 * guard (class added by the frontend JS) lets the directional progress overlay
	 * take over when the animation is enabled. Keep IN SYNC with module-styles.jsx
	 * activeBorderColorDeclaration().
	 */
	public static function active_border_color_style(array $args): string {
		$c = $args['attrValue']['active_border_color'] ?? '';
		if ('' === $c || null === $c) {
			return '';
		}
		// Route through the resolved CSS var (emitted via property mode in $style_fields) so
		// global colors resolve consistently. Keep IN SYNC with module-styles.jsx.
		return 'border-color: var(--bgs-active-border-color) !important;';
	}

	/**
	 * Content-reveal CSS vars from bgs_settings.* content fields. Emits only the
	 * vars whose source field is set; the SCSS supplies fallbacks via var() defaults.
	 * Keep IN SYNC with module-styles.jsx contentFxDeclaration().
	 */
	public static function content_fx_style(array $args): string {
		$v = $args['attrValue'] ?? [];
		// [field, css var, suffix]
		$map = [
			['def_duration',  '--bgs-cd-dur',   'ms'],
			['anim_duration', '--bgs-an-dur',   'ms'],
		];
		$out = '';
		foreach ($map as [$field, $css_var, $suffix]) {
			$raw = $v[$field] ?? '';
			if ('' === $raw || null === $raw) {
				continue;
			}
			$out .= "{$css_var}: {$raw}{$suffix};";
		}
		return $out;
	}

	/**
	 * Icon/Image Size (icon_image_size — standalone group-item; value is the scalar size).
	 * Emitted as a CSS var on .df_bg_switcher_icon so BOTH renderings consume it: styles.scss
	 * sets .et-pb-icon { font-size: var(--bgs-icon-size) } and .df_bg_switcher_icon_img {
	 * width: var(...) }. Mirrors AdvancedBarCounter abc_icon_size. Keep IN SYNC with
	 * module-styles.jsx iconSizeDeclaration().
	 */
	public static function icon_size_style(array $args): string {
		$v = $args['attrValue'] ?? '';
		return (is_string($v) && '' !== $v) ? '--bgs-icon-size: ' . $v . ';' : '';
	}

	/** Image object-fit (icon_design.image_fit), default contain. Keep IN SYNC with module-styles.jsx icon_fit_style(). */
	public static function icon_fit_style(array $args): string {
		$v = $args['attrValue']['image_fit'] ?? '';
		return 'object-fit: ' . ('' !== $v ? $v : 'contain') . ';';
	}

	/**
	 * Icon/Image Alignment (icon_design.icon_alignment) → position the fit-content
	 * .df_bg_switcher_icon box left/center/right via auto margins. Keep IN SYNC with
	 * module-styles.jsx iconAlignmentDeclaration() and the child's override.
	 */
	public static function icon_alignment_style(array $args): string {
		$v   = $args['attrValue']['icon_alignment'] ?? '';
		$map = [
			'left'   => 'margin-left:0;margin-right:auto;',
			'center' => 'margin-left:auto;margin-right:auto;',
			'right'  => 'margin-left:auto;margin-right:0;',
		];
		return $map[$v] ?? '';
	}

	/** overflow:hidden on the icon wrapper when it has a border radius (icon_box). Keep IN SYNC with module-styles.jsx. */
	public static function icon_overflow_style(array $args): string {
		$r   = $args['attrValue']['radius'] ?? [];
		$has = isset($r['topLeft']) || isset($r['topRight'])
			|| isset($r['bottomLeft']) || isset($r['bottomRight']);
		return $has ? 'overflow: hidden !important;' : '';
	}

	public static function styles($args) {
		$attrs       = $args['attrs'] ?? [];
		$order_class = $args['orderClass'];
		$elements    = $args['elements'];
		$settings    = $args['settings'] ?? [];

		// [field, default, suffix, selector, CSS property] — keep IN SYNC with module-styles.jsx.
		$style_fields = [
			['animation_duration',     '500',     'ms', '.df_bg_switcher',       '--bgs-in'],
			['animation_duration',     '500',     'ms', '.df_bg_switcher',       '--bgs-out'],
			['divider_color',          '#dddddd', '',   '.df_bg_switcher',       '--bgs-divider-color'],
			['active_border_color',    '',        '',   '.df_bg_switcher',       '--bgs-active-border-color'],
		];

		$common_styles = [];
		foreach ($style_fields as [$field, $default, $suffix, $selector, $property]) {
			$attr = self::extract_style_attr($attrs, $field, $default, $suffix);
			if (!empty($attr)) {
				$common_styles[] = CommonStyle::style([
					'selector' => "{$order_class} {$selector}",
					'attr'     => $attr,
					'property' => $property,
				]);
			}
		}

		Style::add(
			[
				'id'            => $args['id'],
				'name'          => $args['name'],
				'orderIndex'    => $args['orderIndex'],
				'storeInstance' => $args['storeInstance'],
				'styles'        => array_merge(
					[
						$elements->style(
							[
								'attrName'   => 'module',
								'styleProps' => [
									'disabledOn' => [
										'disabledModuleVisibility' => $settings['disabledModuleVisibility'] ?? null,
									],
									'background' => [
										'featureSelectors' => [
											'mask' => [
												'desktop' => [
													'value' => "{$order_class} .et_pb_background_mask",
												],
											],
											'pattern' => [
												'desktop' => [
													'value' => "{$order_class} .et_pb_background_pattern",
												],
											],
										],
									],
								],
							]
						),

						CssStyle::style(
							[
								'selector'  => $order_class,
								'attr'      => $attrs['css'] ?? [],
								'cssFields' => self::custom_css(),
							]
						),

						// Responsive layout: flex direction + grid columns.
						CommonStyle::style([
							'selector'            => "{$order_class} .df_bg_switcher",
							'attr'                => self::layout_attr_with_defaults($attrs['bgs_settings']['innerContent'] ?? [], 'flex_direction', ['desktop' => 'horizontal', 'phone' => 'vertical']),
							'declarationFunction' => [self::class, 'flex_direction_style'],
						]),
						CommonStyle::style([
							'selector'            => "{$order_class} .df_bg_switcher",
							'attr'                => $attrs['bgs_settings']['innerContent'] ?? [],
							'declarationFunction' => [self::class, 'grid_columns_style'],
						]),

						// Bg image zoom intensity -> --bgs-zoom.
						CommonStyle::style([
							'selector'            => "{$order_class} .df_bg_switcher",
							'attr'                => $attrs['bgs_settings']['innerContent'] ?? [],
							'declarationFunction' => [self::class, 'animation_intensity_style'],
						]),

						// Responsive Hover Blur -> --bgs-blur.
						CommonStyle::style([
							'selector'            => "{$order_class} .df_bg_switcher",
							'attr'                => $attrs['style_settings']['innerContent'] ?? [],
							'declarationFunction' => [self::class, 'hover_blur_style'],
						]),

						// Responsive Divider Width -> --bgs-divider-width (drives the gap + divider overlay).
						CommonStyle::style([
							'selector'            => "{$order_class} .df_bg_switcher",
							'attr'                => $attrs['style_settings']['innerContent'] ?? [],
							'declarationFunction' => [self::class, 'divider_width_style'],
						]),

						// Active Border Color → recolor the active panel's real border.
						CommonStyle::style([
							'selector'            => "{$order_class} .df_bg_switcher:not(.df_bg_switcher--progress-active) .df_bg_switcher_item.is-active .df_bg_switcher_panel",
							'attr'                => $attrs['style_settings']['innerContent'] ?? [],
							'declarationFunction' => [self::class, 'active_border_color_style'],
						]),

						// Content-reveal vars -> --bgs-cd-*, --bgs-an-*, --bgs-tr-*.
						CommonStyle::style([
							'selector'            => "{$order_class} .df_bg_switcher",
							'attr'                => $attrs['bgs_settings']['innerContent'] ?? [],
							'declarationFunction' => [self::class, 'content_fx_style'],
						]),

						// Border radius → clip inner elements to the rounded corners.
						CommonStyle::style([
							'selector'            => $order_class,
							'attr'                => $attrs['module']['decoration']['border'] ?? [],
							'declarationFunction' => [self::class, 'border_overflow_style'],
						]),

						// Icon/Image design (applies to every panel's .df_bg_switcher_icon).
						// Colors via native `property` so Divi global colors resolve (VB + FE).
						CommonStyle::style([
							'selector' => "{$order_class} .df_bg_switcher_icon .et-pb-icon",
							'attr'     => $attrs['icon_color']['innerContent'] ?? [],
							'property' => 'color',
						]),
						CommonStyle::style([
							'selector' => "{$order_class} .df_bg_switcher_icon",
							'attr'     => $attrs['icon_bg_color']['innerContent'] ?? [],
							'property' => 'background-color',
						]),
						// Icon/Image Size → CSS var consumed by both the glyph (font-size) and image (width).
						CommonStyle::style([
							'selector'            => "{$order_class} .df_bg_switcher_icon",
							'attr'                => $attrs['icon_image_size']['innerContent'] ?? [],
							'declarationFunction' => [self::class, 'icon_size_style'],
						]),
						// Image object-fit.
						CommonStyle::style([
							'selector'            => "{$order_class} .df_bg_switcher_icon .df_bg_switcher_icon_img",
							'attr'                => $attrs['icon_design']['innerContent'] ?? [],
							'declarationFunction' => [self::class, 'icon_fit_style'],
						]),
						// Icon/Image Alignment → align the icon box (left/center/right) for every panel.
						CommonStyle::style([
							'selector'            => "{$order_class} .df_bg_switcher_icon",
							'attr'                => $attrs['icon_design']['innerContent'] ?? [],
							'declarationFunction' => [self::class, 'icon_alignment_style'],
						]),
						CommonStyle::style([
							'selector'            => "{$order_class} .df_bg_switcher_icon",
							'attr'                => $attrs['icon_box']['decoration']['border'] ?? [],
							'declarationFunction' => [self::class, 'icon_overflow_style'],
						]),

						// Sub-element decoration (Pattern B): content spacing + item border/box-shadow + bg-image filters/border + icon spacing/border/box-shadow + title font/spacing.
						$elements->style(['attrName' => 'content_spacing']),
						$elements->style(['attrName' => 'content_design']),
						$elements->style(['attrName' => 'item_design']),
						$elements->style(['attrName' => 'bg_design']),
						$elements->style(['attrName' => 'icon_box']),
						$elements->style(['attrName' => 'title_font']),
						$elements->style(['attrName' => 'desc_font']),
					],
					$common_styles
				),
			]
		);
	}
}
