<?php
/**
 * Basic Forms - Design Defaults
 * Single source of truth for all form design option defaults.
 *
 * @package BasicForms
 * @since 1.0.0
 */

namespace BasicForms;

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

final class DesignDefaults {

	/**
	 * Normalize design for the admin form: clamp numbers and whitelist selects so HTML5 validation
	 * never blocks Save when values sit in hidden design tabs or typography popovers.
	 *
	 * @param array<string, string> $design Parsed design with defaults merged.
	 * @return array<string, string>
	 */
	public static function normalizeForAdminForm( array $design ): array {
		$clamp = static function ( $val, int $min, int $max, int $step = 1 ) {
			$n = is_numeric( $val ) ? (int) $val : $min;
			$n = max( $min, min( $max, $n ) );
			if ( $step > 1 ) {
				$n = (int) ( round( $n / $step ) * $step );
				$n = max( $min, min( $max, $n ) );
			}
			return (string) $n;
		};

		if ( isset( $design['field_gap'] ) ) {
			$design['field_gap'] = $clamp( $design['field_gap'], 0, 120, 1 );
		}
		if ( isset( $design['max_width'] ) ) {
			$design['max_width'] = $clamp( $design['max_width'], 200, 1200, 10 );
		}
		if ( isset( $design['padding'] ) ) {
			$design['padding'] = $clamp( $design['padding'], 0, 80, 4 );
		}
		if ( isset( $design['border_width'] ) ) {
			$design['border_width'] = $clamp( $design['border_width'], 0, 8, 1 );
		}
		if ( isset( $design['border_radius'] ) ) {
			$design['border_radius'] = $clamp( $design['border_radius'], 0, 24, 1 );
		}
		if ( isset( $design['input_border_width'] ) ) {
			$design['input_border_width'] = $clamp( $design['input_border_width'], 0, 4, 1 );
		}
		if ( isset( $design['input_padding'] ) ) {
			$design['input_padding'] = $clamp( $design['input_padding'], 4, 24, 2 );
		}
		if ( isset( $design['help_text_font_size'] ) ) {
			$design['help_text_font_size'] = $clamp( $design['help_text_font_size'], 10, 18, 1 );
		}
		if ( isset( $design['button_border_width'] ) ) {
			$design['button_border_width'] = $clamp( $design['button_border_width'], 0, 4, 1 );
		}
		if ( isset( $design['button_border_radius'] ) ) {
			$design['button_border_radius'] = $clamp( $design['button_border_radius'], 0, 24, 1 );
		}
		$ir = $design['input_border_radius'] ?? '';
		if ( $ir !== '' && is_numeric( $ir ) ) {
			$design['input_border_radius'] = $clamp( $ir, 0, 24, 1 );
		}

		// Typography popovers: font size (number, optional empty) and line height (0.5–3, step 0.1).
		$typo_prefixes = [ 'label', 'field', 'placeholder' ];
		foreach ( $typo_prefixes as $px ) {
			foreach ( [ 'font_size_desktop', 'font_size_tablet', 'font_size_mobile' ] as $suffix ) {
				$key = $px . '_' . $suffix;
				$design[ $key ] = self::clampOptionalIntInRange( $design[ $key ] ?? '', 10, 72 );
			}
			foreach ( [ 'line_height_desktop', 'line_height_tablet', 'line_height_mobile' ] as $suffix ) {
				$key = $px . '_' . $suffix;
				$design[ $key ] = self::clampOptionalLineHeight( $design[ $key ] ?? '' );
			}
		}
		$design['placeholder_font_size'] = self::clampOptionalIntInRange( $design['placeholder_font_size'] ?? '', 10, 72 );

		// Font weight options match TypographyHelper select.
		$fw_allowed = [ '', '300', '400', '500', '600', '700' ];
		$design['label_font_weight']     = self::whitelistScalar( $design['label_font_weight'] ?? '', $fw_allowed, '' );
		$design['field_font_weight']     = self::whitelistScalar( $design['field_font_weight'] ?? '', $fw_allowed, '' );
		$design['placeholder_font_weight'] = self::whitelistScalar( $design['placeholder_font_weight'] ?? '', $fw_allowed, '' );

		$tt_allowed = [ '', 'none', 'lowercase', 'uppercase', 'capitalize' ];
		foreach ( [ 'label_text_transform', 'field_text_transform', 'placeholder_text_transform' ] as $k ) {
			$design[ $k ] = self::whitelistScalar( $design[ $k ] ?? '', $tt_allowed, '' );
		}

		$fs_allowed = [ '', 'normal', 'italic', 'oblique' ];
		foreach ( [ 'label_font_style', 'field_font_style', 'placeholder_font_style' ] as $k ) {
			$design[ $k ] = self::whitelistScalar( $design[ $k ] ?? '', $fs_allowed, '' );
		}

		$design['layout']        = self::whitelistScalar( $design['layout'] ?? '', [ 'default', 'full', 'compact', 'narrow', 'custom' ], 'default' );
		$design['align']         = self::whitelistScalar( $design['align'] ?? '', [ 'left', 'center', 'right' ], 'center' );
		$design['field_spacing'] = self::whitelistScalar( $design['field_spacing'] ?? '', [ 'tight', 'normal', 'relaxed', 'spacious' ], 'normal' );
		$design['label_position'] = self::whitelistScalar( $design['label_position'] ?? '', [ 'above', 'left' ], 'above' );
		$design['button_shadow']  = self::whitelistScalar( $design['button_shadow'] ?? '', [ 'none', 'sm', 'md', 'lg' ], 'none' );
		$design['button_style']   = self::whitelistScalar( $design['button_style'] ?? '', [ 'solid', 'outline', 'flat' ], 'solid' );
		$design['button_size']    = self::whitelistScalar( $design['button_size'] ?? '', [ 'small', 'medium', 'large' ], 'medium' );

		return $design;
	}

	/**
	 * @param mixed $val
	 */
	private static function clampOptionalIntInRange( $val, int $min, int $max ): string {
		if ( $val === '' || $val === null ) {
			return '';
		}
		if ( ! is_numeric( $val ) ) {
			return '';
		}
		$n = max( $min, min( $max, (int) $val ) );
		return (string) $n;
	}

	/**
	 * Line height inputs: min 0.5, max 3, step 0.1 (matches TypographyHelper).
	 *
	 * @param mixed $val
	 */
	private static function clampOptionalLineHeight( $val ): string {
		if ( $val === '' || $val === null ) {
			return '';
		}
		if ( ! is_numeric( $val ) ) {
			return '';
		}
		$n = round( max( 0.5, min( 3.0, (float) $val ) ), 1 );
		return (string) $n;
	}

	/**
	 * @param mixed $val
	 */
	private static function whitelistScalar( $val, array $allowed, string $fallback ): string {
		$s = is_scalar( $val ) ? (string) $val : '';
		return in_array( $s, $allowed, true ) ? $s : $fallback;
	}

	/**
	 * Get all form design defaults. Used by form editor, frontend, and shortcode.
	 *
	 * @return array<string, string>
	 */
	public static function get(): array {
		$defaults = [
			// Layout
			'layout'        => 'default',
			'max_width'     => '600',
			'align'         => 'center',
			'field_spacing' => 'normal',
			'field_gap'     => '20',

			// Container
			'bg_color'      => '#ffffff',
			'padding'       => '24',
			'border_width'  => '0',
			'border_color'  => '#c3c4c7',
			'border_radius' => '4',

			// Labels
			'label_position'             => 'above',
			'label_color'                 => '#1d2327',
			'label_font_family'           => '',
			'label_font_weight'           => '600',
			'label_font_size_desktop'     => '14',
			'label_font_size_tablet'      => '',
			'label_font_size_mobile'      => '',
			'label_text_transform'        => '',
			'label_font_style'            => '',
			'label_line_height_desktop'   => '',
			'label_line_height_tablet'    => '',
			'label_line_height_mobile'    => '',
			'label_letter_spacing_desktop' => '',
			'label_letter_spacing_tablet'  => '',
			'label_letter_spacing_mobile'  => '',

			// Inputs
			'input_border_width'   => '1',
			'input_border_color'   => '#c3c4c7',
			'input_bg'             => '#ffffff',
			'input_border_radius'   => '',
			'input_padding'        => '10',
			'placeholder_color'    => '#646970',
			'field_text_color'     => '#1d2327',
			'help_text_color'      => '#646970',
			'help_text_font_size'  => '12',

			// Field typography
			'field_font_family'            => '',
			'field_font_weight'            => '',
			'field_font_size_desktop'      => '14',
			'field_font_size_tablet'       => '',
			'field_font_size_mobile'      => '',
			'field_text_transform'        => '',
			'field_font_style'             => '',
			'field_line_height_desktop'    => '',
			'field_line_height_tablet'    => '',
			'field_line_height_mobile'    => '',
			'field_letter_spacing_desktop' => '',
			'field_letter_spacing_tablet'  => '',
			'field_letter_spacing_mobile'  => '',

			// Placeholder typography
			'placeholder_font_family'              => '',
			'placeholder_font_weight'               => '',
			'placeholder_font_size_desktop'         => '',
			'placeholder_font_size'                 => '',
			'placeholder_font_size_tablet'         => '',
			'placeholder_font_size_mobile'         => '',
			'placeholder_text_transform'          => '',
			'placeholder_font_style'               => '',
			'placeholder_line_height_desktop'    => '',
			'placeholder_line_height_tablet'     => '',
			'placeholder_line_height_mobile'     => '',
			'placeholder_letter_spacing_desktop' => '',
			'placeholder_letter_spacing_tablet'   => '',
			'placeholder_letter_spacing_mobile'   => '',

			// Buttons
			'primary_color'        => '#2271b1',
			'button_hover_color'   => '#135e96',
			'button_shadow'        => 'none',
			'button_border_color'   => '#2271b1',
			'button_border_width'  => '2',
			'button_style'         => 'solid',
			'button_size'          => 'medium',
			'button_border_radius' => '4',
			'button_full_width'   => '0',

			// Messages (success/error)
			'success_msg_bg'     => '#d1f2eb',
			'success_msg_color'  => '#0d5e47',
			'success_msg_border' => '#48c9a9',
			'error_msg_bg'       => '#ffe6e6',
			'error_msg_color'    => '#c41e3a',
			'error_msg_border'   => '#ff6b6b',

			// Advanced per-form CSS (scoped on frontend to .wpps-bf-wrapper.wpps-bf-{form_id})
			'custom_css'         => '',
		];

		if ( is_admin() ) {
			$accent = self::adminAccentColor();
			$defaults['primary_color']       = $accent;
			$defaults['button_border_color'] = $accent;
			$defaults['button_hover_color']  = self::adminAccentHoverColor( $accent );
		}

		return $defaults;
	}

	/**
	 * Active WordPress admin color scheme accent (index 2).
	 */
	private static function adminAccentColor(): string {
		global $_wp_admin_css_colors;

		if ( ! isset( $_wp_admin_css_colors ) || ! is_array( $_wp_admin_css_colors ) ) {
			require_once ABSPATH . 'wp-admin/includes/admin.php';
		}

		$scheme = get_user_option( 'admin_color', get_current_user_id() );
		if ( empty( $scheme ) || ! isset( $_wp_admin_css_colors[ $scheme ] ) ) {
			$scheme = 'fresh';
		}

		$colors = $_wp_admin_css_colors[ $scheme ]->colors ?? [];
		$accent = sanitize_hex_color( $colors[2] ?? '#2271b1' );

		return $accent ?: '#2271b1';
	}

	/**
	 * Darker accent for button hover, aligned with --wp-admin-theme-color-darker-10.
	 */
	private static function adminAccentHoverColor( string $accent ): string {
		$hex = ltrim( $accent, '#' );
		if ( strlen( $hex ) === 3 ) {
			$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
		}
		if ( strlen( $hex ) !== 6 || ! ctype_xdigit( $hex ) ) {
			return '#135e96';
		}

		$r = max( 0, (int) round( hexdec( substr( $hex, 0, 2 ) ) * 0.85 ) );
		$g = max( 0, (int) round( hexdec( substr( $hex, 2, 2 ) ) * 0.85 ) );
		$b = max( 0, (int) round( hexdec( substr( $hex, 4, 2 ) ) * 0.85 ) );

		return sprintf( '#%02x%02x%02x', $r, $g, $b );
	}
}
