<?php
/**
 * WCAG contrast checks for color pairs.
 *
 * @package WP_PowerSuite\AdminColorCustomizer
 */

namespace WP_PowerSuite\AdminColorCustomizer;

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

class Accessibility {

	/**
	 * @param array<string, mixed> $scheme
	 * @return array<int, array<string, mixed>>
	 */
	public function check_scheme( array $scheme ): array {
		$checks = [
			[
				'pair'  => 'menu_text_menu_bg',
				'label' => __( 'Admin menu text / background', 'wp-powersuite' ),
				'fg'    => (string) ( $scheme['menu_text'] ?? '' ),
				'bg'    => (string) ( $scheme['menu_bg'] ?? '' ),
			],
			[
				'pair'  => 'menu_hover_text_menu_hover_bg',
				'label' => __( 'Admin menu hover text / background', 'wp-powersuite' ),
				'fg'    => (string) ( $scheme['menu_hover_text'] ?? '' ),
				'bg'    => (string) ( $scheme['menu_hover_bg'] ?? '' ),
			],
			[
				'pair'  => 'button_text_button_bg',
				'label' => __( 'Button text / background', 'wp-powersuite' ),
				'fg'    => (string) ( $scheme['button_text'] ?? '' ),
				'bg'    => (string) ( $scheme['button_bg'] ?? '' ),
			],
			[
				'pair'  => 'toolbar_text_toolbar_bg',
				'label' => __( 'Toolbar text / background', 'wp-powersuite' ),
				'fg'    => (string) ( $scheme['toolbar_text'] ?? '' ),
				'bg'    => (string) ( $scheme['toolbar_bg'] ?? '' ),
			],
		];

		$warnings = [];
		foreach ( $checks as $check ) {
			$ratio = self::contrast_ratio( $check['fg'], $check['bg'] );
			if ( $ratio === null ) {
				continue;
			}

			$pass = $ratio >= 4.5;
			if ( ! $pass ) {
				$warnings[] = [
					'pair'    => $check['pair'],
					'label'   => $check['label'],
					'ratio'   => round( $ratio, 2 ),
					'minimum' => 4.5,
					'level'   => 'warning',
				];
			}
		}

		return $warnings;
	}

	public static function contrast_ratio( string $fg, string $bg ): ?float {
		$fg_rgb = self::hex_to_rgb( $fg );
		$bg_rgb = self::hex_to_rgb( $bg );

		if ( $fg_rgb === null || $bg_rgb === null ) {
			return null;
		}

		$l1 = self::relative_luminance( $fg_rgb );
		$l2 = self::relative_luminance( $bg_rgb );

		$lighter = max( $l1, $l2 );
		$darker  = min( $l1, $l2 );

		return ( $lighter + 0.05 ) / ( $darker + 0.05 );
	}

	/**
	 * @return array{r: float, g: float, b: float}|null
	 */
	private static function hex_to_rgb( string $hex ): ?array {
		$hex = Scheme_Registry::sanitize_hex_color( $hex );
		if ( $hex === null ) {
			return null;
		}

		return [
			'r' => hexdec( substr( $hex, 1, 2 ) ) / 255,
			'g' => hexdec( substr( $hex, 3, 2 ) ) / 255,
			'b' => hexdec( substr( $hex, 5, 2 ) ) / 255,
		];
	}

	/**
	 * @param array{r: float, g: float, b: float} $rgb
	 */
	private static function relative_luminance( array $rgb ): float {
		$channels = [];
		foreach ( [ 'r', 'g', 'b' ] as $channel ) {
			$c = $rgb[ $channel ];
			$channels[] = $c <= 0.03928 ? $c / 12.92 : ( ( $c + 0.055 ) / 1.055 ) ** 2.4;
		}

		return 0.2126 * $channels[0] + 0.7152 * $channels[1] + 0.0722 * $channels[2];
	}
}
