<?php
/**
 * RSF (RSMSpark Focus) global settings.
 *
 * @package Rsmspark_Suite
 */

defined( 'ABSPATH' ) || exit;

/**
 * RSMSPARK_RSF_Settings
 */
final class RSMSPARK_RSF_Settings {

	const OPTION_KEY = 'rsmspark_rsf_settings';

	/**
	 * @return array<string, mixed>
	 */
	public static function defaults() {
		return array(
			'animations_enabled'     => true,
			'default_animation'      => 'fade',
			'default_duration_ms'    => 600,
			'default_delay_ms'       => 0,
			'default_easing'         => 'ease-out',
			'respect_reduced_motion' => true,
			'breakpoints'            => array(
				'mobile'  => 480,
				'tablet'  => 782,
				'desktop' => 1200,
			),
			'breakpoint_labels'      => array(
				'mobile'  => 'Mobile',
				'tablet'  => 'Tablet',
				'desktop' => 'Desktop',
			),
		);
	}

	/**
	 * @return array<string, mixed>
	 */
	public static function get() {
		$stored = get_option( self::OPTION_KEY, array() );
		if ( ! is_array( $stored ) ) {
			$stored = array();
		}

		$merged = wp_parse_args( $stored, self::defaults() );

		$merged['animations_enabled']     = ! empty( $merged['animations_enabled'] );
		$merged['respect_reduced_motion'] = ! empty( $merged['respect_reduced_motion'] );
		$merged['default_duration_ms']    = max( 0, (int) $merged['default_duration_ms'] );
		$merged['default_delay_ms']       = max( 0, (int) $merged['default_delay_ms'] );
		$merged['default_animation']      = sanitize_key( (string) $merged['default_animation'] );
		$merged['default_easing']         = sanitize_key( (string) $merged['default_easing'] );

		$defaults = self::defaults();
		$bps      = is_array( $merged['breakpoints'] ?? null ) ? $merged['breakpoints'] : array();
		foreach ( array( 'mobile', 'tablet', 'desktop' ) as $key ) {
			$bps[ $key ] = max( 0, (int) ( $bps[ $key ] ?? $defaults['breakpoints'][ $key ] ) );
		}
		$merged['breakpoints'] = $bps;

		$labels = is_array( $merged['breakpoint_labels'] ?? null ) ? $merged['breakpoint_labels'] : array();
		foreach ( array( 'mobile', 'tablet', 'desktop' ) as $key ) {
			$labels[ $key ] = sanitize_text_field(
				(string) ( $labels[ $key ] ?? $defaults['breakpoint_labels'][ $key ] )
			);
		}
		$merged['breakpoint_labels'] = $labels;

		return $merged;
	}

	/**
	 * @param array<string, mixed> $settings Settings.
	 * @return void
	 */
	public static function save( array $settings ) {
		update_option( self::OPTION_KEY, wp_parse_args( $settings, self::defaults() ), false );
	}

	/**
	 * @return bool
	 */
	public static function animations_enabled() {
		$settings = self::get();
		return ! empty( $settings['animations_enabled'] );
	}

	/**
	 * Whether Pro features (custom breakpoints, responsive alignment, layout width tables) are unlocked.
	 *
	 * @return bool
	 */
	public static function breakpoints_pro_enabled() {
		return (bool) apply_filters( 'rsmspark_rsf_breakpoints_pro_enabled', false );
	}

	/**
	 * Normalized breakpoint bands for CSS generation.
	 *
	 * @return array{mobile_max:int,tablet_min:int,tablet_max:int,desktop_min:int}
	 */
	public static function get_normalized_breakpoints() {
		// Free builds keep the default bands; custom widths require Pro (filter).
		if ( ! self::breakpoints_pro_enabled() ) {
			return array(
				'mobile_max'  => 480,
				'tablet_min'  => 481,
				'tablet_max'  => 782,
				'desktop_min' => 783,
			);
		}

		$settings = self::get();
		$mobile   = max( 320, (int) ( $settings['breakpoints']['mobile'] ?? 480 ) );
		$tablet   = max( $mobile + 1, (int) ( $settings['breakpoints']['tablet'] ?? 782 ) );

		return array(
			'mobile_max'  => $mobile,
			'tablet_min'  => $mobile + 1,
			'tablet_max'  => $tablet,
			'desktop_min' => $tablet + 1,
		);
	}

	/**
	 * @param int $mobile Mobile max width.
	 * @param int $tablet Tablet max width.
	 * @return void
	 */
	public static function save_breakpoints( $mobile, $tablet ) {
		if ( ! self::breakpoints_pro_enabled() ) {
			return;
		}

		$settings = self::get();
		$mobile   = max( 320, min( 1200, (int) $mobile ) );
		$tablet   = max( $mobile + 1, min( 1920, (int) $tablet ) );

		$settings['breakpoints']['mobile'] = $mobile;
		$settings['breakpoints']['tablet'] = $tablet;

		self::save( $settings );
	}

	/**
	 * Responsive visibility + text-align CSS from saved breakpoint values.
	 *
	 * @return string
	 */
	public static function build_responsive_css() {
		$n = self::get_normalized_breakpoints();

		$css  = sprintf(
			"@media (max-width:%dpx){.rsm-rsf-hide-mobile{display:none!important}}\n",
			$n['mobile_max']
		);
		$css .= sprintf(
			"@media (min-width:%dpx) and (max-width:%dpx){.rsm-rsf-hide-tablet{display:none!important}}\n",
			$n['tablet_min'],
			$n['tablet_max']
		);
		$css .= sprintf(
			"@media (min-width:%dpx){.rsm-rsf-hide-desktop{display:none!important}}\n",
			$n['desktop_min']
		);

		$alignments = array( 'left', 'center', 'right' );
		foreach ( array( 'mobile' => $n['mobile_max'], 'tablet' => $n['tablet_max'] ) as $slug => $max ) {
			$min = 'mobile' === $slug ? 0 : $n['tablet_min'];
			foreach ( $alignments as $align ) {
				if ( 'mobile' === $slug ) {
					$query = sprintf( '@media (max-width:%dpx)', $max );
				} else {
					$query = sprintf( '@media (min-width:%dpx) and (max-width:%dpx)', $min, $max );
				}
				$css .= sprintf(
					"%s{.rsm-rsf-text-%s-%s{text-align:%s!important}}\n",
					$query,
					$slug,
					$align,
					$align
				);
			}
		}

		foreach ( $alignments as $align ) {
			$css .= sprintf(
				"@media (min-width:%dpx){.rsm-rsf-text-desktop-%s{text-align:%s!important}}\n",
				$n['desktop_min'],
				$align,
				$align
			);
		}

		$flex_align = array(
			'left'   => 'flex-start',
			'center' => 'center',
			'right'  => 'flex-end',
		);
		foreach ( array( 'mobile' => $n['mobile_max'], 'tablet' => $n['tablet_max'] ) as $slug => $max ) {
			foreach ( $flex_align as $align => $justify ) {
				if ( 'mobile' === $slug ) {
					$query = sprintf( '@media (max-width:%dpx)', $max );
				} else {
					$query = sprintf( '@media (min-width:%dpx) and (max-width:%dpx)', $n['tablet_min'], $max );
				}
				$css .= sprintf(
					"%s{.wp-block-navigation.rsm-rsf-text-%s-%s{justify-content:%s!important}}\n",
					$query,
					$slug,
					$align,
					$justify
				);
			}
		}
		foreach ( $flex_align as $align => $justify ) {
			$css .= sprintf(
				"@media (min-width:%dpx){.wp-block-navigation.rsm-rsf-text-desktop-%s{justify-content:%s!important}}\n",
				$n['desktop_min'],
				$align,
				$justify
			);
		}

		return $css;
	}
}
