<?php
/**
 * Shared color utility methods used by both block renderers.
 *
 * Provides hex↔rgb conversion, WCAG contrast calculation,
 * and CSS custom-property generation for accent theming.
 *
 * @package CRTodayCurrencyBlocks
 */

declare(strict_types=1);

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

trait CRToday_Color_Helpers {

	/**
	 * Convert a hex colour string to an [r, g, b] array.
	 *
	 * @param string $hex Hex colour with or without leading '#'. Supports 3- and 6-digit forms.
	 * @return array{r:int, g:int, b:int}
	 */
	private static function hex_to_rgb(string $hex): array {
		$clean = ltrim($hex, '#');
		if (strlen($clean) === 3) {
			$clean = $clean[0] . $clean[0] . $clean[1] . $clean[1] . $clean[2] . $clean[2];
		}

		return [
			'r' => hexdec(substr($clean, 0, 2)),
			'g' => hexdec(substr($clean, 2, 2)),
			'b' => hexdec(substr($clean, 4, 2)),
		];
	}

	/**
	 * Build an rgba() CSS string from a hex colour and alpha value.
	 */
	private static function rgba_from_hex(string $hex, float $alpha): string {
		$rgb = self::hex_to_rgb($hex);
		return sprintf('rgba(%d, %d, %d, %.3f)', $rgb['r'], $rgb['g'], $rgb['b'], $alpha);
	}

	/**
	 * Calculate relative luminance per WCAG 2.x.
	 */
	private static function relative_luminance(string $hex): float {
		$rgb = self::hex_to_rgb($hex);
		$to_linear = static function (float $channel): float {
			$normalized = $channel / 255;
			return $normalized <= 0.03928
				? $normalized / 12.92
				: (($normalized + 0.055) / 1.055) ** 2.4;
		};

		$r = $to_linear((float) $rgb['r']);
		$g = $to_linear((float) $rgb['g']);
		$b = $to_linear((float) $rgb['b']);

		return (0.2126 * $r) + (0.7152 * $g) + (0.0722 * $b);
	}

	/**
	 * WCAG contrast ratio between two hex colours.
	 */
	private static function contrast_ratio(string $a, string $b): float {
		$l1 = self::relative_luminance($a);
		$l2 = self::relative_luminance($b);
		$light = max($l1, $l2);
		$dark  = min($l1, $l2);
		return ($light + 0.05) / ($dark + 0.05);
	}

	/**
	 * Pick a text colour (dark or light) that has better contrast against $background.
	 */
	private static function pick_contrast_text(string $background): string {
		$dark_text  = '#0f172a';
		$light_text = '#f8fafc';
		$dark_ratio  = self::contrast_ratio($background, $dark_text);
		$light_ratio = self::contrast_ratio($background, $light_text);

		return $dark_ratio >= $light_ratio ? $dark_text : $light_text;
	}

	/**
	 * Build inline CSS custom properties for accent theming.
	 *
	 * @param array $settings Block settings containing accentTheme, accentAngle, radius.
	 */
	private static function build_accent_style_vars(array $settings): string {
		$accent_presets = CRToday_Plugin_Settings::get_accent_theme_presets();
		$theme_key = (string) ($settings['accentTheme'] ?? 'default');
		$theme = $accent_presets[$theme_key] ?? $accent_presets['default'];
		$angle = max(0, min(360, (int) ($settings['accentAngle'] ?? 135)));

		$light = $theme['light'];
		$dark  = $theme['dark'];

		$light_rgb = self::hex_to_rgb($light['primary']);
		$dark_rgb  = self::hex_to_rgb($dark['primary']);

		$light_text = self::pick_contrast_text($light['primary']);
		$dark_text  = self::pick_contrast_text($dark['primary']);

		$vars = [
			'--crtoday-radius:' . (string) $settings['radius'] . 'px',
			'--crtoday-accent-1-light:' . $light['primary'],
			'--crtoday-accent-2-light:' . $light['secondary'],
			'--crtoday-accent-3-light:' . $light['tertiary'],
			'--crtoday-accent-1-dark:' . $dark['primary'],
			'--crtoday-accent-2-dark:' . $dark['secondary'],
			'--crtoday-accent-3-dark:' . $dark['tertiary'],
			'--crtoday-accent-gradient-light:linear-gradient(' . $angle . 'deg, ' . $light['primary'] . ' 0%, ' . $light['secondary'] . ' 55%, ' . $light['tertiary'] . ' 100%)',
			'--crtoday-accent-gradient-dark:linear-gradient(' . $angle . 'deg, ' . $dark['primary'] . ' 0%, ' . $dark['secondary'] . ' 55%, ' . $dark['tertiary'] . ' 100%)',
			'--crtoday-accent-color-light:' . $light['primary'],
			'--crtoday-accent-color-dark:' . $dark['primary'],
			'--crtoday-accent-rgb-light:' . $light_rgb['r'] . ' ' . $light_rgb['g'] . ' ' . $light_rgb['b'],
			'--crtoday-accent-rgb-dark:' . $dark_rgb['r'] . ' ' . $dark_rgb['g'] . ' ' . $dark_rgb['b'],
			'--crtoday-row-hover-light:' . self::rgba_from_hex($light['primary'], 0.06),
			'--crtoday-row-hover-dark:' . self::rgba_from_hex($dark['primary'], 0.14),
			'--crtoday-accent-contrast-light:' . $light_text,
			'--crtoday-accent-contrast-dark:' . $dark_text,
		];

		return implode(';', $vars);
	}
}
