<?php
/**
 * Resolve the active color scheme for a user/request.
 *
 * @package WP_PowerSuite\AdminColorCustomizer
 */

namespace WP_PowerSuite\AdminColorCustomizer;

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

class User_Scheme_Resolver {

	private static bool $filtering_admin_color = false;

	/**
	 * @param array<string, mixed> $settings
	 * @return array<string, mixed>|null
	 */
	public function resolve_scheme( array $settings, ?int $user_id = null ): ?array {
		if ( Settings::is_emergency_disabled() ) {
			return null;
		}

		$mode = (string) ( $settings['mode'] ?? 'disabled' );
		if ( $mode === 'disabled' || empty( $settings['enabled'] ) ) {
			return null;
		}

		$user_id  = $user_id ?? get_current_user_id();
		$registry = Scheme_Registry::instance();
		$scheme_id = $this->resolve_scheme_id( $settings, $user_id );

		if ( $scheme_id === null ) {
			return null;
		}

		$scheme = $registry->get_scheme( $scheme_id, $settings );

		if ( $scheme === null ) {
			return null;
		}

		return apply_filters( 'wpps_admin_color_customizer_current_scheme', $scheme, $settings, $user_id );
	}

	/**
	 * @param array<string, mixed> $settings
	 */
	public function resolve_scheme_id( array $settings, int $user_id ): ?string {
		$mode = (string) ( $settings['mode'] ?? 'disabled' );
		if ( $mode === 'disabled' ) {
			return null;
		}

		$registry  = Scheme_Registry::instance();
		$fallback  = sanitize_key( (string) ( $settings['active_scheme'] ?? 'powersuite_blue' ) );
		$valid_ids = $registry->get_all_scheme_ids( $settings );

		if ( ! in_array( $fallback, $valid_ids, true ) ) {
			$fallback = 'powersuite_blue';
		}

		if ( in_array( $mode, [ 'force_all', 'force_by_role' ], true ) && class_exists( Premium::class, false ) ) {
			return Premium::resolve_forced_scheme_id( $mode, $user_id, $settings, $fallback );
		}

		return match ( $mode ) {
			'global_default', 'per_user_selectable', 'force_all', 'force_by_role' => $this->resolve_user_selected_scheme( $user_id, $valid_ids ) ?? $fallback,
			default => null,
		};
	}

	/**
	 * @param list<string> $valid_ids
	 */
	private function resolve_user_selected_scheme( int $user_id, array $valid_ids ): ?string {
		$selected = self::get_raw_user_admin_color( $user_id );
		if ( ! is_string( $selected ) || $selected === '' ) {
			return null;
		}

		$selected = sanitize_key( $selected );

		return in_array( $selected, $valid_ids, true ) ? $selected : null;
	}

	/**
	 * Read admin_color from user meta without triggering get_user_option_admin_color.
	 */
	public static function get_raw_user_admin_color( int $user_id ): ?string {
		if ( $user_id <= 0 ) {
			return null;
		}

		global $wpdb;

		$prefixed = get_user_meta( $user_id, $wpdb->get_blog_prefix() . 'admin_color', true );
		if ( is_string( $prefixed ) && $prefixed !== '' ) {
			return $prefixed;
		}

		$global = get_user_meta( $user_id, 'admin_color', true );
		if ( is_string( $global ) && $global !== '' ) {
			return $global;
		}

		return null;
	}

	/**
	 * Whether the profile color picker should reflect stored user preferences.
	 */
	public static function is_profile_picker_context(): bool {
		return self::is_profile_admin_color_context() && doing_action( 'admin_color_scheme_picker' );
	}

	/**
	 * Profile screens (profile.php / user-edit.php).
	 */
	public static function is_profile_admin_color_context(): bool {
		global $pagenow;

		return in_array( $pagenow, [ 'profile.php', 'user-edit.php' ], true );
	}

	/**
	 * @param array<string, mixed> $settings
	 */
	public function filter_admin_color_option( mixed $value, string $option, int $user_id ): mixed {
		unset( $option );

		if ( self::$filtering_admin_color ) {
			return $value;
		}

		self::$filtering_admin_color = true;

		try {
			$settings = Settings::get_effective_settings();
			$mode     = (string) ( $settings['mode'] ?? 'disabled' );

			if ( Settings::is_emergency_disabled() || $mode === 'disabled' ) {
				return $value;
			}

			$registry  = Scheme_Registry::instance();
			$valid_ids = $registry->get_all_scheme_ids( $settings );
			$fallback  = sanitize_key( (string) ( $settings['active_scheme'] ?? 'powersuite_blue' ) );
			if ( ! in_array( $fallback, $valid_ids, true ) ) {
				$fallback = 'powersuite_blue';
			}

			// Profile picker: show the stored slug when users may choose their own scheme.
			if ( self::is_profile_picker_context() && in_array( $mode, [ 'global_default', 'per_user_selectable' ], true ) ) {
				if ( is_string( $value ) && $value !== '' ) {
					$stored = sanitize_key( $value );
					if ( in_array( $stored, $valid_ids, true ) ) {
						return $stored;
					}
				}

				$raw = self::get_raw_user_admin_color( $user_id );
				if ( is_string( $raw ) && $raw !== '' ) {
					$raw = sanitize_key( $raw );
					if ( in_array( $raw, $valid_ids, true ) ) {
						return $raw;
					}
				}

				return $fallback;
			}

			$stored = is_string( $value ) ? sanitize_key( $value ) : '';
			if ( $stored === '' ) {
				$stored = sanitize_key( (string) ( self::get_raw_user_admin_color( $user_id ) ?? '' ) );
			}

			if ( $mode === 'per_user_selectable' ) {
				if ( $stored !== '' && in_array( $stored, $valid_ids, true ) ) {
					return $stored;
				}

				$raw = self::get_raw_user_admin_color( $user_id );
				if ( is_string( $raw ) ) {
					$raw = sanitize_key( $raw );
					if ( $raw !== '' && in_array( $raw, $valid_ids, true ) ) {
						return $raw;
					}
				}

				return $fallback;
			}

			if ( $mode === 'global_default' ) {
				if ( $stored !== '' && in_array( $stored, $valid_ids, true ) ) {
					return $stored;
				}

				return $fallback;
			}

			if ( in_array( $mode, [ 'force_all', 'force_by_role' ], true ) && class_exists( Premium::class, false ) ) {
				return Premium::resolve_forced_scheme_id( $mode, $user_id, $settings, $fallback );
			}

			if ( $stored !== '' && in_array( $stored, $valid_ids, true ) ) {
				return $stored;
			}

			return $fallback;
		} finally {
			self::$filtering_admin_color = false;
		}
	}

	/**
	 * @param array<string, mixed> $settings
	 */
	public function should_output_admin_css( array $settings ): bool {
		if ( Settings::is_emergency_disabled() || empty( $settings['enabled'] ) ) {
			return false;
		}

		return is_admin() && ! wp_doing_ajax();
	}

	/**
	 * @param array<string, mixed> $settings
	 */
	public function should_output_frontend_admin_bar_css( array $settings ): bool {
		if ( Settings::is_emergency_disabled() || empty( $settings['enabled'] ) ) {
			return false;
		}

		if ( is_admin() ) {
			return false;
		}

		if ( ! is_user_logged_in() ) {
			return false;
		}

		$scope = (string) ( $settings['scope'] ?? 'admin_only' );
		$allow = $scope === 'admin_and_admin_bar';

		$allow = (bool) apply_filters(
			'wpps_admin_color_customizer_can_output_frontend_admin_bar_css',
			$allow,
			$settings
		);

		return $allow;
	}

	/**
	 * @param array<string, mixed> $settings
	 */
	public function should_output_login_css( array $settings ): bool {
		if ( Settings::is_emergency_disabled() || empty( $settings['enabled'] ) ) {
			return false;
		}

		return ! empty( $settings['login_screen'] );
	}
}
