<?php
/**
 * Frontend styling overrides (admin-controlled).
 *
 * @package FoodOrd
 */

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

/**
 * Class Foodord_Styling_Frontend
 */
class Foodord_Styling_Frontend {
	/**
	 * Option key for storing styling values.
	 */
	private const OPTION_KEY = 'foodord_styling';

	/**
	 * Register runtime hooks.
	 */
	public function init(): void {
		add_action( 'wp_enqueue_scripts', array( $this, 'maybe_add_inline_styles' ), 99 );
	}

	/**
	 * Add dynamic CSS when FoodOrd styles are enqueued.
	 */
	public function maybe_add_inline_styles(): void {
		if ( is_admin() ) {
			return;
		}

		if ( function_exists( 'foodord_page_has_order_components' ) && ! foodord_page_has_order_components() ) {
			return;
		}

		// Ensure a stable base handle is enqueued early, so the inline CSS is printed.
		if ( function_exists( 'foodord_enqueue_frontend_styles' ) ) {
			foodord_enqueue_frontend_styles();
		}

		$css = $this->build_css( $this->get_settings() );
		if ( '' === $css ) {
			return;
		}

		$css_safe = $this->sanitize_inline_css( $css );
		if ( '' === $css_safe ) {
			return;
		}

		if ( wp_style_is( 'foodord-frontend', 'enqueued' ) ) {
			wp_add_inline_style( 'foodord-frontend', $css_safe );
		}
	}

	/**
	 * Sanitize inline CSS output for wp_add_inline_style().
	 *
	 * @param string $css Raw CSS.
	 */
	private function sanitize_inline_css( string $css ): string {
		$css = wp_strip_all_tags( $css );
		$css = str_replace( array( "\0", '<', '>' ), '', $css );
		return trim( $css );
	}

	/**
	 * Restrict dynamic styling output to light mode so dark mode tokens stay authoritative.
	 *
	 * @param string $css Raw CSS rules.
	 * @return string
	 */
	private function scope_css_to_light_mode( string $css ): string {
		$rules  = explode( '}', $css );
		$output = '';

		foreach ( $rules as $rule ) {
			$rule = trim( $rule );
			if ( '' === $rule || false === strpos( $rule, '{' ) ) {
				continue;
			}

			list( $selectors, $body ) = explode( '{', $rule, 2 );
			$selectors                = array_filter( array_map( 'trim', explode( ',', trim( $selectors ) ) ) );

			if ( empty( $selectors ) ) {
				continue;
			}

			$scoped_selectors = array();
			foreach ( $selectors as $selector ) {
				if ( 0 === strpos( $selector, 'html:not(.foodord-dark-mode)' ) ) {
					$scoped_selectors[] = $selector;
					continue;
				}

				$scoped_selectors[] = 'html:not(.foodord-dark-mode) ' . $selector;
			}

			$output .= implode( ',', $scoped_selectors ) . '{' . trim( $body ) . '}';
		}

		return $output;
	}

	/**
	 * Default settings.
	 *
	 * @return array<string, mixed>
	 */
	private function get_defaults(): array {
		return array(
			'toggle_active_bg'              => '#ffffff',
			'toggle_active_text'            => '#353535',
			'toggle_active_font_size'       => 14,
			'toggle_active_line_height'     => 1.2,
			'toggle_active_font_weight'     => 600,
			'card_title_color'              => '#0f172a',
			'card_title_font_size'          => 16,
			'card_title_line_height'        => 1.3,
			'card_title_font_weight'        => 600,
			'category_title_color'          => '#323232',
			'category_title_font_size'      => 22,
			'category_title_line_height'    => 1.2,
			'category_title_font_weight'    => 600,
			'card_description_color'        => '#666666',
			'card_description_font_size'    => 13,
			'card_description_line_height'  => 1.5,
			'card_description_font_weight'  => 400,
			'card_price_color'              => '#0f172a',
			'card_price_font_size'          => 16,
			'card_price_line_height'        => 1.2,
			'card_price_font_weight'        => 700,
			'cart_cta_bg'                   => '#ea004b',
			'cart_cta_bg_hover'             => '#c70040',
			'cart_cta_text'                 => '#ffffff',
			'cart_cta_text_hover'           => '#ffffff',
			'cart_cta_font_size'            => 14,
			'cart_cta_line_height'          => 1.2,
			'cart_cta_font_weight'          => 600,
			'modal_title_color'             => '#0f172a',
			'modal_title_font_size'         => 16,
			'modal_title_line_height'       => 1.2,
			'modal_title_font_weight'       => 600,
			'modal_price_color'             => '#0f172a',
			'modal_price_font_size'         => 16,
			'modal_price_line_height'       => 1.2,
			'modal_price_font_weight'       => 600,
			'modal_description_color'       => '#323232',
			'modal_description_font_size'   => 14,
			'modal_description_line_height' => 1.5,
			'modal_description_font_weight' => 400,
			'modal_add_to_cart_bg'          => '#ea004b',
			'modal_add_to_cart_bg_hover'    => '#e2003c',
			'modal_add_to_cart_text'        => '#ffffff',
			'modal_add_to_cart_text_hover'  => '#ffffff',
			'modal_add_to_cart_font_size'   => 14,
			'modal_add_to_cart_line_height' => 1.2,
			'modal_add_to_cart_font_weight' => 600,
			'pro_price_current_color'       => '#0f172a',
			'pro_price_current_font_size'   => 16,
			'pro_price_current_line_height' => 1.2,
			'pro_price_current_font_weight' => 700,
			'tip_option_bg'                 => '#ffffff',
			'tip_option_text'               => '#111927',
			'tip_option_font_size'          => 14,
			'tip_option_line_height'        => 1.2,
			'tip_option_font_weight'        => 600,
			'tip_option_active_bg'          => '#111927',
			'tip_option_active_text'        => '#ffffff',
			'tip_option_active_font_size'   => 14,
			'tip_option_active_line_height' => 1.2,
			'tip_option_active_font_weight' => 600,
			'tip_custom_apply_bg'           => '#ea004b',
			'tip_custom_apply_text'         => '#ffffff',
			'tip_custom_apply_font_size'    => 14,
			'tip_custom_apply_line_height'  => 1.2,
			'tip_custom_apply_font_weight'  => 600,
		);
	}

	/**
	 * Get merged and sanitized settings.
	 *
	 * @return array<string, mixed>
	 */
	private function get_settings(): array {
		$defaults = $this->get_defaults();
		$stored   = get_option( self::OPTION_KEY, array() );
		if ( ! is_array( $stored ) ) {
			$stored = array();
		}

		$settings = wp_parse_args( $stored, $defaults );

		// Backward compatibility: previous versions stored separate delivery/pickup active values.
		if ( ! isset( $stored['toggle_active_bg'] ) && isset( $stored['delivery_active_bg'] ) ) {
			$settings['toggle_active_bg'] = (string) $stored['delivery_active_bg'];
		}
		if ( ! isset( $stored['toggle_active_text'] ) && isset( $stored['delivery_active_text'] ) ) {
			$settings['toggle_active_text'] = (string) $stored['delivery_active_text'];
		}
		if ( ! isset( $stored['toggle_active_font_size'] ) && isset( $stored['delivery_active_font_size'] ) ) {
			$settings['toggle_active_font_size'] = (int) $stored['delivery_active_font_size'];
		}
		if ( ! isset( $stored['toggle_active_line_height'] ) && isset( $stored['delivery_active_line_height'] ) ) {
			$settings['toggle_active_line_height'] = (float) $stored['delivery_active_line_height'];
		}
		if ( ! isset( $stored['toggle_active_font_weight'] ) && isset( $stored['delivery_active_font_weight'] ) ) {
			$settings['toggle_active_font_weight'] = (int) $stored['delivery_active_font_weight'];
		}

		foreach ( $defaults as $key => $default ) {
			$value = isset( $settings[ $key ] ) ? $settings[ $key ] : $default;

			if ( false !== strpos( $key, '_bg' ) || false !== strpos( $key, '_text' ) || false !== strpos( $key, '_color' ) ) {
				$value            = is_string( $value ) ? sanitize_hex_color( $value ) : '';
				$settings[ $key ] = $value ? $value : $default;
				continue;
			}

			if ( false !== strpos( $key, '_font_size' ) ) {
				$value            = is_numeric( $value ) ? (int) $value : (int) $default;
				$settings[ $key ] = max( 8, min( 96, $value ) );
				continue;
			}

			if ( false !== strpos( $key, '_line_height' ) ) {
				$value            = is_numeric( $value ) ? (float) $value : (float) $default;
				$settings[ $key ] = max( 0.8, min( 3.0, $value ) );
				continue;
			}

			if ( false !== strpos( $key, '_font_weight' ) ) {
				$value            = is_numeric( $value ) ? (int) $value : (int) $default;
				$settings[ $key ] = max( 100, min( 900, $value ) );
				continue;
			}

			$settings[ $key ] = $default;
		}

		return $settings;
	}

	/**
	 * Build CSS rules from settings.
	 *
	 * @param array<string, mixed> $settings Settings.
	 */
	private function build_css( array $settings ): string {
		$css        = '';
		$shared_css = $this->build_dark_mode_button_vars( $settings );

		// Delivery/Pickup toggle.
		// Typography must target the actual buttons (.wr-card__mode-btn), not the slider.
		$toggle_button_selector           = implode(
			',',
			array(
				'.wr-card.has-mode-toggle .wr-card__mode-btn',
				'.foodord-mode-toggle-mobile .wr-card__mode-btn',
				'[data-foodord-mode-toggle="products"] .wr-card__mode-btn',
			)
		);
		$toggle_slider_selector           = implode(
			',',
			array(
				'.wr-card.has-mode-toggle .wr-card__mode-slider',
				'.foodord-mode-toggle-mobile .wr-card__mode-slider',
				'[data-foodord-mode-toggle="products"] .wr-card__mode-slider',
			)
		);
		$toggle_active_button_selector    = implode(
			',',
			array(
				'.wr-card.has-mode-toggle .wr-card__mode-btn.is-active',
				'.foodord-mode-toggle-mobile .wr-card__mode-btn.is-active',
				'[data-foodord-mode-toggle="products"] .wr-card__mode-btn.is-active',
			)
		);
		$toggle_active_button_descendants = implode(
			',',
			array(
				'.wr-card.has-mode-toggle .wr-card__mode-btn.is-active *',
				'.foodord-mode-toggle-mobile .wr-card__mode-btn.is-active *',
				'[data-foodord-mode-toggle="products"] .wr-card__mode-btn.is-active *',
			)
		);

		$css .= $this->build_text_css(
			$toggle_button_selector,
			'',
			(int) $settings['toggle_active_font_size'],
			(float) $settings['toggle_active_line_height'],
			(int) $settings['toggle_active_font_weight']
		);

		// Active state background uses the slider pill.
		$css .= $this->build_button_css(
			$toggle_slider_selector,
			$settings['toggle_active_bg'],
			'',
			0,
			0,
			0,
			''
		);

		// Closed hours: force the slider/background to be transparent regardless of Styling settings.
		$css .= '.wr-card__mode-toggle.is-store-closed .wr-card__mode-slider{background-color:transparent !important;background:transparent !important;}';

		// Active state text/icon color lives on the active button.
		$css .= $this->build_text_css(
			$toggle_active_button_selector,
			$settings['toggle_active_text'],
			0,
			0,
			0
		);
		if ( '' !== $settings['toggle_active_text'] ) {
			$css .= $toggle_active_button_descendants . '{color:inherit !important;}';
		}

		$css .= $this->build_text_css(
			'.foodord-product-card .product-title',
			$settings['card_title_color'],
			(int) $settings['card_title_font_size'],
			(float) $settings['card_title_line_height'],
			(int) $settings['card_title_font_weight']
		);
		$css .= '.foodord-product-card .product-title a{color:inherit !important;}';

		$css .= $this->build_text_css(
			'.foodord-product-category',
			$settings['category_title_color'],
			(int) $settings['category_title_font_size'],
			(float) $settings['category_title_line_height'],
			(int) $settings['category_title_font_weight']
		);

		$css .= $this->build_text_css(
			'.foodord-product-card .product-description p',
			$settings['card_description_color'],
			(int) $settings['card_description_font_size'],
			(float) $settings['card_description_line_height'],
			(int) $settings['card_description_font_weight']
		);

		// Card price: apply to wrapper and WooCommerce amount/currency.
		$price_selectors = array(
			'.foodord-product-card .product-price',
			'.foodord-product-card .product-price .woocommerce-Price-amount',
			'.foodord-product-card .product-price .woocommerce-Price-currencySymbol',
		);
		$css            .= $this->build_text_css(
			implode( ',', $price_selectors ),
			$settings['card_price_color'],
			(int) $settings['card_price_font_size'],
			(float) $settings['card_price_line_height'],
			(int) $settings['card_price_font_weight']
		);

		$css .= $this->build_button_css(
			'.wr-card__cta',
			$settings['cart_cta_bg'],
			$settings['cart_cta_text'],
			(int) $settings['cart_cta_font_size'],
			(float) $settings['cart_cta_line_height'],
			(int) $settings['cart_cta_font_weight'],
			'.wr-card__cta *:not(.wr-card__cta-count)'
		);
		$css .= '.wr-card__cta-left,.wr-card__cta-label,.wr-card__cta-total{color:inherit !important;}';
		$css .= $this->build_button_css(
			'.wr-card__cta:not(.disabled):hover',
			$settings['cart_cta_bg_hover'],
			$settings['cart_cta_text_hover'],
			0,
			0,
			0,
			'.wr-card__cta:not(.disabled):hover *:not(.wr-card__cta-count)'
		);

		// Mobile cart header should also reflect the Cart CTA styling settings.
		$mobile_cart_header_vars = array();
		if ( '' !== $settings['cart_cta_bg'] ) {
			$mobile_cart_header_vars[] = '--button-bg:' . $settings['cart_cta_bg'] . ' !important;';
		}
		if ( '' !== $settings['cart_cta_text'] ) {
			$mobile_cart_header_vars[] = '--button-text-color:' . $settings['cart_cta_text'] . ' !important;';
		}
		if ( '' !== $settings['cart_cta_bg_hover'] ) {
			$mobile_cart_header_vars[] = '--button-on-hover:' . $settings['cart_cta_bg_hover'] . ' !important;';
		}
		if ( ! empty( $mobile_cart_header_vars ) ) {
			$css .= '.foodord-mobile-cart__header{' . implode( '', $mobile_cart_header_vars ) . '}';
		}
		$css .= $this->build_text_css(
			'.foodord-mobile-cart__header',
			$settings['cart_cta_text'],
			(int) $settings['cart_cta_font_size'],
			(float) $settings['cart_cta_line_height'],
			(int) $settings['cart_cta_font_weight']
		);
		if ( '' !== $settings['cart_cta_text'] || (int) $settings['cart_cta_font_weight'] > 0 || (int) $settings['cart_cta_font_size'] > 0 ) {
			$css .= '.foodord-mobile-cart__header *:not(.foodord-mobile-cart__count){color:inherit !important;font-weight:inherit !important;font-size:inherit !important;line-height:inherit !important;}';
		}
		$css .= $this->build_button_css(
			'.foodord-mobile-cart__header:hover',
			$settings['cart_cta_bg_hover'],
			$settings['cart_cta_text_hover'],
			0,
			0,
			0,
			'.foodord-mobile-cart__header:hover *:not(.foodord-mobile-cart__count)'
		);

		$css .= $this->build_text_css(
			'.foodord-product-title',
			$settings['modal_title_color'],
			(int) $settings['modal_title_font_size'],
			(float) $settings['modal_title_line_height'],
			(int) $settings['modal_title_font_weight']
		);

		// Modal price: apply to wrapper and WooCommerce amount/currency.
		$modal_price_selectors = array(
			'.foodord-product-price',
			'.foodord-product-price .woocommerce-Price-amount',
			'.foodord-product-price .woocommerce-Price-currencySymbol',
		);
		$css                  .= $this->build_text_css(
			implode( ',', $modal_price_selectors ),
			$settings['modal_price_color'],
			(int) $settings['modal_price_font_size'],
			(float) $settings['modal_price_line_height'],
			(int) $settings['modal_price_font_weight']
		);

		$css .= $this->build_text_css(
			'.foodord-product-description',
			$settings['modal_description_color'],
			(int) $settings['modal_description_font_size'],
			(float) $settings['modal_description_line_height'],
			(int) $settings['modal_description_font_weight']
		);
		$css .= '.foodord-product-description *{color:inherit !important;}';

		$css .= $this->build_button_css(
			'.foodord-modal-footer .foodord-add-to-cart-btn',
			$settings['modal_add_to_cart_bg'],
			$settings['modal_add_to_cart_text'],
			(int) $settings['modal_add_to_cart_font_size'],
			(float) $settings['modal_add_to_cart_line_height'],
			(int) $settings['modal_add_to_cart_font_weight'],
			'.foodord-modal-footer .foodord-add-to-cart-btn *:not(.foodord-add-to-cart-count)'
		);
		$css .= $this->build_button_css(
			'.foodord-modal-footer .foodord-add-to-cart-btn:hover',
			$settings['modal_add_to_cart_bg_hover'],
			$settings['modal_add_to_cart_text_hover'],
			0,
			0,
			0,
			'.foodord-modal-footer .foodord-add-to-cart-btn:hover *:not(.foodord-add-to-cart-count)'
		);

		$css .= $this->build_text_css(
			'.foodord-pro-price__current',
			$settings['pro_price_current_color'],
			(int) $settings['pro_price_current_font_size'],
			(float) $settings['pro_price_current_line_height'],
			(int) $settings['pro_price_current_font_weight']
		);

		$css .= $this->build_button_css(
			'.foodord-tip-option',
			$settings['tip_option_bg'],
			$settings['tip_option_text'],
			(int) $settings['tip_option_font_size'],
			(float) $settings['tip_option_line_height'],
			(int) $settings['tip_option_font_weight'],
			'.foodord-tip-option *'
		);

		$css .= $this->build_button_css(
			'.foodord-tip-option.is-active',
			$settings['tip_option_active_bg'],
			$settings['tip_option_active_text'],
			(int) $settings['tip_option_active_font_size'],
			(float) $settings['tip_option_active_line_height'],
			(int) $settings['tip_option_active_font_weight'],
			'.foodord-tip-option.is-active *'
		);

		$css .= $this->build_button_css(
			'.foodord-tip-custom__apply',
			$settings['tip_custom_apply_bg'],
			$settings['tip_custom_apply_text'],
			(int) $settings['tip_custom_apply_font_size'],
			(float) $settings['tip_custom_apply_line_height'],
			(int) $settings['tip_custom_apply_font_weight'],
			'.foodord-tip-custom__apply *'
		);

		return $shared_css . $this->scope_css_to_light_mode( trim( $css ) );
	}

	/**
	 * Expose selected admin button colors as shared CSS variables for dark mode.
	 *
	 * @param array<string, mixed> $settings Styling settings.
	 * @return string
	 */
	private function build_dark_mode_button_vars( array $settings ): string {
		$vars = array();

		if ( ! empty( $settings['cart_cta_bg'] ) ) {
			$vars[] = '--foodord-cart-cta-admin-bg:' . $settings['cart_cta_bg'] . ';';
		}
		if ( ! empty( $settings['cart_cta_text'] ) ) {
			$vars[] = '--foodord-cart-cta-admin-text:' . $settings['cart_cta_text'] . ';';
		}
		if ( ! empty( $settings['cart_cta_bg_hover'] ) ) {
			$vars[] = '--foodord-cart-cta-admin-bg-hover:' . $settings['cart_cta_bg_hover'] . ';';
		}
		if ( ! empty( $settings['cart_cta_text_hover'] ) ) {
			$vars[] = '--foodord-cart-cta-admin-text-hover:' . $settings['cart_cta_text_hover'] . ';';
		}
		if ( ! empty( $settings['modal_add_to_cart_bg'] ) ) {
			$vars[] = '--foodord-modal-add-to-cart-admin-bg:' . $settings['modal_add_to_cart_bg'] . ';';
		}
		if ( ! empty( $settings['modal_add_to_cart_bg_hover'] ) ) {
			$vars[] = '--foodord-modal-add-to-cart-admin-bg-hover:' . $settings['modal_add_to_cart_bg_hover'] . ';';
		}
		if ( ! empty( $settings['modal_add_to_cart_text'] ) ) {
			$vars[] = '--foodord-modal-add-to-cart-admin-text:' . $settings['modal_add_to_cart_text'] . ';';
		}
		if ( ! empty( $settings['modal_add_to_cart_text_hover'] ) ) {
			$vars[] = '--foodord-modal-add-to-cart-admin-text-hover:' . $settings['modal_add_to_cart_text_hover'] . ';';
		}

		if ( empty( $vars ) ) {
			return '';
		}

		return ':root{' . implode( '', $vars ) . '}';
	}

	/**
	 * Build CSS for a "button" style element.
	 *
	 * @param string $selector CSS selector.
	 * @param string $bg Background color.
	 * @param string $text Text color.
	 * @param int    $font_size Font size in pixels.
	 * @param float  $line_height Line height.
	 * @param int    $font_weight Font weight.
	 * @param string $descendant_selector Optional descendant selector.
	 * @return string
	 */
	private function build_button_css( string $selector, string $bg, string $text, int $font_size, float $line_height, int $font_weight, string $descendant_selector ): string {
		$props = array();

		if ( '' !== $bg ) {
			$props[] = 'background-color:' . $bg . ' !important;';
			$props[] = 'background:' . $bg . ' !important;';
		}
		if ( '' !== $text ) {
			$props[] = 'color:' . $text . ' !important;';
		}
		if ( $font_size > 0 ) {
			$props[] = 'font-size:' . $font_size . 'px !important;';
		}
		if ( $line_height > 0 ) {
			$props[] = 'line-height:' . $line_height . ' !important;';
		}
		if ( $font_weight > 0 ) {
			$props[] = 'font-weight:' . $font_weight . ' !important;';
		}

		if ( empty( $props ) ) {
			return '';
		}

		$css = $selector . '{' . implode( '', $props ) . '}';
		if ( '' !== $descendant_selector && ( '' !== $text || $font_weight > 0 ) ) {
			$css .= $descendant_selector . '{color:inherit !important;font-weight:inherit !important;}';
		}

		return $css;
	}

	/**
	 * Build CSS for a text element.
	 *
	 * @param string $selector CSS selector.
	 * @param string $color Text color.
	 * @param int    $font_size Font size in pixels.
	 * @param float  $line_height Line height.
	 * @param int    $font_weight Font weight.
	 * @return string
	 */
	private function build_text_css( string $selector, string $color, int $font_size, float $line_height, int $font_weight = 0 ): string {
		$props = array();

		if ( '' !== $color ) {
			$props[] = 'color:' . $color . ' !important;';
		}
		if ( $font_size > 0 ) {
			$props[] = 'font-size:' . $font_size . 'px !important;';
		}
		if ( $line_height > 0 ) {
			$props[] = 'line-height:' . $line_height . ' !important;';
		}
		if ( $font_weight > 0 ) {
			$props[] = 'font-weight:' . $font_weight . ' !important;';
		}

		if ( empty( $props ) ) {
			return '';
		}

		return $selector . '{' . implode( '', $props ) . '}';
	}
}
