<?php
/**
 * Styling settings page.
 *
 * @package FoodOrd
 */

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

/**
 * Class Foodord_Styling
 */
class Foodord_Styling {

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

	/**
	 * Output static admin markup with a restricted allowlist.
	 *
	 * @param string $html Raw HTML.
	 * @return void
	 */
	private function output_static_markup( string $html ): void {
		echo wp_kses( $html, $this->get_allowed_static_markup() );
	}

	/**
	 * Allowed HTML tags/attributes for static admin markup.
	 *
	 * @return array<string, array<string, bool>>
	 */
	private function get_allowed_static_markup(): array {
		return array(
			'div'    => array(
				'class' => true,
				'id'    => true,
			),
			'hr'     => array(
				'class' => true,
			),
			'form'   => array(
				'class'  => true,
				'method' => true,
				'action' => true,
			),
			'select' => array(
				'id'   => true,
				'name' => true,
			),
		);
	}

	/**
	 * Render the settings page.
	 */
	public function render_page(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'foodord' ) );
		}

		$saved    = $this->maybe_handle_post();
		$settings = $this->get_settings();

		$this->output_static_markup( '<div class="wrap foodord-styling-page">' );
		echo '<h1 class="wp-heading-inline">' . esc_html__( 'Styling Settings', 'foodord' ) . '</h1>';
		if ( function_exists( 'foodord_admin_render_horizontal_menu' ) ) {
			foodord_admin_render_horizontal_menu();
		}
		$this->output_static_markup( '<hr class="wp-header-end">' );

		if ( $saved ) {
			echo '<div class="notice notice-success is-dismissible"><p class="notice-text">' . esc_html__( 'Styling settings saved successfully.', 'foodord' ) . '</p></div>';
		}

		$this->output_static_markup( '<div class="wrc-admin-content">' );
		$this->output_static_markup( '<form class="wrc-settings-form" method="post" action="">' );
		wp_nonce_field( 'foodord_save_styling', 'foodord_styling_nonce' );

		// Section: Delivery / Pickup Toggle.
		$this->render_section_header( __( 'Delivery & Pickup Toggle', 'foodord' ), __( 'Customize the appearance of the main delivery mode toggle.', 'foodord' ) );
		$this->output_static_markup( '<div class="foodord-styling-grid">' );
		$this->render_style_card(
			__( 'Delivery & Pickup Toggle', 'foodord' ),
			__( 'Typography for the toggle buttons and active state colors (buttons: .wr-card__mode-btn, slider: .wr-card__mode-slider)', 'foodord' ),
			'toggle_active',
			$settings,
			'button'
		);
		$this->output_static_markup( '</div>' );

		// Section: Product Cards.
		$this->render_section_header( __( 'Product Cards', 'foodord' ), __( 'Control the look of product listings.', 'foodord' ) );
		$this->output_static_markup( '<div class="foodord-styling-grid">' );
		$this->render_style_card( __( 'Product Name', 'foodord' ), '.foodord-product-card .product-title', 'card_title', $settings, 'text' );
		$this->render_style_card( __( 'Category Title', 'foodord' ), '.foodord-product-category', 'category_title', $settings, 'text' );
		$this->render_style_card( __( 'Product Description', 'foodord' ), '.foodord-product-card .product-description p', 'card_description', $settings, 'text' );
		$this->render_style_card( __( 'Product Price', 'foodord' ), '.foodord-product-card .product-price', 'card_price', $settings, 'text' );
		$this->output_static_markup( '</div>' );

		// Section: Cart CTA.
		$this->render_section_header( __( 'Floating Cart Button', 'foodord' ), __( 'Appearance of the floating cart call-to-action.', 'foodord' ) );
		$this->output_static_markup( '<div class="foodord-styling-grid">' );
		$this->render_style_card( __( 'Cart Checkout Button', 'foodord' ), '.wr-card__cta', 'cart_cta', $settings, 'button' );
		$this->output_static_markup( '</div>' );

		// Section: Product Modal.
		$this->render_section_header( __( 'Product Modal', 'foodord' ), __( 'Styles for the product details popup.', 'foodord' ) );
		$this->output_static_markup( '<div class="foodord-styling-grid">' );
		$this->render_style_card( __( 'Modal Title', 'foodord' ), '.foodord-product-title', 'modal_title', $settings, 'text' );
		$this->render_style_card( __( 'Modal Price', 'foodord' ), '.foodord-product-price', 'modal_price', $settings, 'text' );
		$this->render_style_card( __( 'Modal Description', 'foodord' ), '.foodord-product-description', 'modal_description', $settings, 'text' );
		$this->render_style_card( __( 'Add to Cart Button', 'foodord' ), '.foodord-modal-footer .foodord-add-to-cart-btn', 'modal_add_to_cart', $settings, 'button' );
		$this->output_static_markup( '</div>' );

		// Section: FoodOrd Pro.
		$this->render_section_header( __( 'FoodOrd Pro Features', 'foodord' ), __( 'Styles for Pro-only features.', 'foodord' ) );
		$this->output_static_markup( '<div class="foodord-styling-grid">' );
		$this->render_style_card( __( 'Current Price', 'foodord' ), '.foodord-pro-price__current', 'pro_price_current', $settings, 'text' );
		$this->output_static_markup( '</div>' );

		// Section: Tipping.
		$this->render_section_header( __( 'Tipping Controls', 'foodord' ), __( 'Customize the tipping interface.', 'foodord' ) );
		$this->output_static_markup( '<div class="foodord-styling-grid">' );
		$this->render_style_card( __( 'Tip Option', 'foodord' ), '.foodord-tip-option', 'tip_option', $settings, 'button' );
		$this->render_style_card( __( 'Active Tip Option', 'foodord' ), '.foodord-tip-option.is-active', 'tip_option_active', $settings, 'button' );
		$this->render_style_card( __( 'Custom Tip Button', 'foodord' ), '.foodord-tip-custom__apply', 'tip_custom_apply', $settings, 'button' );
		$this->output_static_markup( '</div>' );

		// Save Button.
		$this->output_static_markup( '<div class="wrc-settings-actions-bar">' );
		echo wp_kses_post( submit_button( __( 'Save Changes', 'foodord' ), 'primary large', 'foodord_styling_submit', false ) );
		$this->output_static_markup( '</div>' );

		$this->output_static_markup( '</form>' );
		$this->output_static_markup( '</div>' ); // .wrc-admin-content
		$this->output_static_markup( '</div>' ); // .wrap
	}

	/**
	 * Handle form submissions.
	 */
	private function maybe_handle_post(): bool {
		$request_method = isset( $_SERVER['REQUEST_METHOD'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ) ) : '';
		if ( 'POST' !== $request_method ) {
			return false;
		}

		if ( empty( $_POST['foodord_styling_nonce'] ) ) {
			return false;
		}

		if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['foodord_styling_nonce'] ) ), 'foodord_save_styling' ) ) {
			return false;
		}

		if ( empty( $_POST['foodord_styling_submit'] ) ) {
			return false;
		}

		$raw_settings = array();
		if ( isset( $_POST['foodord_styling'] ) && is_array( $_POST['foodord_styling'] ) ) {
			$raw_settings = map_deep( wp_unslash( $_POST['foodord_styling'] ), 'sanitize_text_field' );
			if ( ! is_array( $raw_settings ) ) {
				$raw_settings = array();
			}
		}

		$sanitized = $this->sanitize_settings( $raw_settings );
		update_option( self::OPTION_KEY, $sanitized, false );
		return true;
	}

	/**
	 * 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 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'];
		}

		return $settings;
	}

	/**
	 * Sanitize and normalize all settings.
	 *
	 * @param array<string, mixed> $raw Raw settings.
	 * @return array<string, mixed>
	 */
	private function sanitize_settings( array $raw ): array {
		$defaults  = $this->get_defaults();
		$sanitized = array();

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

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

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

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

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

			$sanitized[ $key ] = $default;
		}

		return $sanitized;
	}

	/**
	 * Render a section header.
	 *
	 * @param string $title Section title.
	 * @param string $description Optional section description.
	 * @return void
	 */
	private function render_section_header( string $title, string $description = '' ): void {
		$this->output_static_markup( '<div class="foodord-section-header">' );
		echo '<h2 class="wrc-section-title">' . esc_html( $title ) . '</h2>';
		if ( $description ) {
			echo '<p class="wrc-admin-description">' . esc_html( $description ) . '</p>';
		}
		$this->output_static_markup( '</div>' );
	}

	/**
	 * Render a style card for an element.
	 *
	 * @param string               $title       Element title.
	 * @param string               $selector    Selector/Description.
	 * @param string               $prefix      Setting prefix.
	 * @param array<string, mixed> $settings    Current settings.
	 * @param string               $type        Type ('text' or 'button').
	 */
	private function render_style_card( string $title, string $selector, string $prefix, array $settings, string $type ): void {
		$this->output_static_markup( '<div class="foodord-style-card">' );
		$this->output_static_markup( '<div class="foodord-style-card__header">' );
		echo '<h3 class="foodord-style-card__title">' . esc_html( $title ) . '</h3>';
		if ( $selector ) {
			echo '<span class="foodord-style-card__selector">' . esc_html( $selector ) . '</span>';
		}
		$this->output_static_markup( '</div>' ); // Header.

		$this->output_static_markup( '<div class="foodord-style-card__body">' );

		// Colors.
		$this->output_static_markup( '<div class="foodord-controls-group">' );
		echo '<label class="foodord-group-label">' . esc_html__( 'Colors', 'foodord' ) . '</label>';
		$this->output_static_markup( '<div class="foodord-controls-row">' );
		if ( 'button' === $type ) {
			$this->render_color_dot( $prefix . '_bg', __( 'Background', 'foodord' ), (string) $settings[ $prefix . '_bg' ] );
			$this->render_color_dot( $prefix . '_text', __( 'Text', 'foodord' ), (string) $settings[ $prefix . '_text' ] );
			if ( isset( $settings[ $prefix . '_bg_hover' ] ) ) {
				$this->render_color_dot( $prefix . '_bg_hover', __( 'Hover Background', 'foodord' ), (string) $settings[ $prefix . '_bg_hover' ] );
			}
			if ( isset( $settings[ $prefix . '_text_hover' ] ) ) {
				$this->render_color_dot( $prefix . '_text_hover', __( 'Hover Text', 'foodord' ), (string) $settings[ $prefix . '_text_hover' ] );
			}
		} else {
			$this->render_color_dot( $prefix . '_color', __( 'Text Color', 'foodord' ), (string) $settings[ $prefix . '_color' ] );
		}
		$this->output_static_markup( '</div>' );
		$this->output_static_markup( '</div>' );

		// Typography.
		$this->output_static_markup( '<div class="foodord-controls-group">' );
		echo '<label class="foodord-group-label">' . esc_html__( 'Typography', 'foodord' ) . '</label>';
		$this->output_static_markup( '<div class="foodord-controls-grid">' );
		$this->render_number_input( $prefix . '_font_size', __( 'Size (px)', 'foodord' ), (string) $settings[ $prefix . '_font_size' ], 8, 96, 1 );
		$this->render_number_input( $prefix . '_line_height', __( 'Line Height', 'foodord' ), (string) $settings[ $prefix . '_line_height' ], 0.8, 3.0, 0.05 );
		$this->render_select_input(
			$prefix . '_font_weight',
			__( 'Weight', 'foodord' ),
			(string) $settings[ $prefix . '_font_weight' ],
			array(
				'100' => 'Thin (100)',
				'300' => 'Light (300)',
				'400' => 'Regular (400)',
				'500' => 'Medium (500)',
				'600' => 'SemiBold (600)',
				'700' => 'Bold (700)',
				'900' => 'Black (900)',
			)
		);
		$this->output_static_markup( '</div>' );
		$this->output_static_markup( '</div>' );

		$this->output_static_markup( '</div>' ); // Body.
		$this->output_static_markup( '</div>' ); // Card.
	}

	/**
	 * Render tiny color input.
	 *
	 * @param string $key Setting key suffix.
	 * @param string $label Label text.
	 * @param string $value Current value.
	 * @return void
	 */
	private function render_color_dot( string $key, string $label, string $value ): void {
		$field_id = 'foodord_styling_' . $key;
		$name     = 'foodord_styling[' . $key . ']';
		$this->output_static_markup( '<div class="foodord-control-item foodord-control-color">' );
		echo '<label class="wrc-form-label" for="' . esc_attr( $field_id ) . '">' . esc_html( $label ) . '</label>';
		$this->output_static_markup( '<div class="foodord-color-picker-row">' );
		echo '<input type="text" class="foodord-color-picker" id="' . esc_attr( $field_id ) . '" name="' . esc_attr( $name ) . '" value="' . esc_attr( $value ) . '" data-default-color="' . esc_attr( $value ) . '" />';
		echo '<input type="text" class="foodord-color-code-input" value="' . esc_attr( $value ) . '" data-foodord-color-input-for="' . esc_attr( $field_id ) . '" aria-label="' . esc_attr__( 'Color code', 'foodord' ) . '" />';
		$this->output_static_markup( '</div>' );
		$this->output_static_markup( '</div>' );
	}

	/**
	 * Render numeric input.
	 *
	 * @param string    $key Setting key suffix.
	 * @param string    $label Label text.
	 * @param string    $value Current value.
	 * @param int|float $min Minimum value.
	 * @param int|float $max Maximum value.
	 * @param int|float $step Step value.
	 * @return void
	 */
	private function render_number_input( string $key, string $label, string $value, $min, $max, $step ): void {
		$field_id = 'foodord_styling_' . $key;
		$name     = 'foodord_styling[' . $key . ']';
		$this->output_static_markup( '<div class="foodord-control-item">' );
		echo '<label class="wrc-form-label" for="' . esc_attr( $field_id ) . '">' . esc_html( $label ) . '</label>';
		echo '<input type="number" class="small-text" id="' . esc_attr( $field_id ) . '" name="' . esc_attr( $name ) . '" value="' . esc_attr( $value ) . '" min="' . esc_attr( (string) $min ) . '" max="' . esc_attr( (string) $max ) . '" step="' . esc_attr( (string) $step ) . '" />';
		$this->output_static_markup( '</div>' );
	}

	/**
	 * Render select input.
	 *
	 * @param string               $key Setting key suffix.
	 * @param string               $label Label text.
	 * @param string               $value Current value.
	 * @param array<string, mixed> $options Select options.
	 * @return void
	 */
	private function render_select_input( string $key, string $label, string $value, array $options ): void {
		$field_id = 'foodord_styling_' . $key;
		$name     = 'foodord_styling[' . $key . ']';
		$this->output_static_markup( '<div class="foodord-control-item">' );
		echo '<label class="wrc-form-label" for="' . esc_attr( $field_id ) . '">' . esc_html( $label ) . '</label>';
		echo '<select id="' . esc_attr( $field_id ) . '" name="' . esc_attr( $name ) . '">';
		foreach ( $options as $opt_val => $opt_label ) {
			echo '<option value="' . esc_attr( (string) $opt_val ) . '" ' . selected( $value, (string) $opt_val, false ) . '>' . esc_html( $opt_label ) . '</option>';
		}
		$this->output_static_markup( '</select>' );
		$this->output_static_markup( '</div>' );
	}
}
