<?php
/**
 * Design tokens → CSS custom properties.
 *
 * Static token map + Theme Options overrides. Does not change Arabic UI.
 *
 * @package Kutby
 * @since   2.5.0
 */

declare(strict_types=1);

namespace Kutby\Design;

use Kutby\ThemeOptions\Manager;

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

/**
 * Class Tokens
 */
final class Tokens {

	/**
	 * Base design tokens (components must use CSS vars generated from these).
	 *
	 * @return array<string, string>
	 */
	public static function base(): array {
		$tokens = array(
			'--kutby-color-primary'     => '#0f766e',
			'--kutby-color-secondary'   => '#134e4a',
			'--kutby-color-accent'      => '#f59e0b',
			'--kutby-color-bg'          => '#ffffff',
			'--kutby-color-surface'     => '#f8fafc',
			'--kutby-color-card'        => '#ffffff',
			'--kutby-color-border'      => '#e2e8f0',
			'--kutby-color-text'        => '#0f172a',
			'--kutby-color-muted'       => '#64748b',
			'--kutby-color-success'     => '#16a34a',
			'--kutby-color-warning'     => '#d97706',
			'--kutby-color-danger'      => '#dc2626',
			'--kutby-color-link'        => '#0f766e',
			'--kutby-color-hover'       => '#0d9488',
			'--kutby-font-family'       => '"Tajawal", Tahoma, sans-serif',
			'--kutby-font-size-body'    => '16px',
			'--kutby-font-size-sm'      => '0.875rem',
			'--kutby-font-size-lg'      => '1.125rem',
			'--kutby-font-size-xl'      => '1.25rem',
			'--kutby-font-size-2xl'     => '1.5rem',
			'--kutby-line-height'       => '1.7',
			'--kutby-line-height-tight' => '1.35',
			'--kutby-space-1'           => '0.25rem',
			'--kutby-space-2'           => '0.5rem',
			'--kutby-space-3'           => '0.75rem',
			'--kutby-space-4'           => '1rem',
			'--kutby-space-5'           => '1.5rem',
			'--kutby-space-6'           => '2rem',
			'--kutby-space-8'           => '3rem',
			'--kutby-radius-sm'         => '6px',
			'--kutby-radius-md'         => '10px',
			'--kutby-radius-lg'         => '16px',
			'--kutby-radius-full'       => '999px',
			'--kutby-border-width'      => '1px',
			'--kutby-shadow-sm'         => '0 1px 2px rgba(15, 23, 42, 0.06)',
			'--kutby-shadow-md'         => '0 8px 24px rgba(15, 23, 42, 0.08)',
			'--kutby-shadow-lg'         => '0 16px 40px rgba(15, 23, 42, 0.12)',
			'--kutby-container-width'   => '1200px',
			'--kutby-site-width'        => '1400px',
			'--kutby-header-height'     => '64px',
			'--kutby-card-radius'       => '12px',
			'--kutby-card-padding'      => '20px',
			'--kutby-card-shadow'       => '0 1px 2px rgba(15, 23, 42, 0.06)',
			'--kutby-transition'        => '150ms ease',
			'--kutby-transition-slow'   => '250ms ease',
			'--kutby-animation-spin'    => 'kutby-spin 0.7s linear infinite',
			'--kutby-opacity-disabled'  => '0.5',
			'--kutby-opacity-muted'     => '0.7',
			'--kutby-z-dropdown'        => '100',
			'--kutby-z-sticky'          => '200',
			'--kutby-z-modal'           => '1000',
			'--kutby-z-toast'           => '1100',
			'--kutby-overlay'           => 'rgba(15, 23, 42, 0.45)',
			'--kutby-color-on-inverse'  => '#ffffff',
			'--kutby-notice-success-bg' => '#ecfdf5',
			'--kutby-notice-success-fg' => '#065f46',
			'--kutby-notice-success-bd' => '#a7f3d0',
			'--kutby-notice-error-bg'   => '#fef2f2',
			'--kutby-notice-error-fg'   => '#991b1b',
			'--kutby-notice-error-bd'   => '#fecaca',
			'--kutby-notice-warning-bg' => '#fffbeb',
			'--kutby-notice-warning-fg' => '#92400e',
			'--kutby-notice-warning-bd' => '#fde68a',
			'--kutby-notice-info-bg'    => '#eff6ff',
			'--kutby-notice-info-fg'    => '#1e40af',
			'--kutby-notice-info-bd'    => '#bfdbfe',
			'--kutby-bp-sm'             => '480px',
			'--kutby-bp-md'             => '768px',
			'--kutby-bp-lg'             => '1024px',
			'--kutby-bp-xl'             => '1280px',
			'--kutby-focus-ring'        => '0 0 0 3px rgba(20, 184, 166, 0.35)',
		);

		/**
		 * Filter base design tokens.
		 *
		 * @since 2.5.0
		 *
		 * @param array<string, string> $tokens Tokens.
		 */
		return apply_filters( 'kutby_design_tokens', $tokens );
	}

	/**
	 * Merge Theme Options overrides into tokens.
	 *
	 * @return array<string, string>
	 */
	public static function resolved(): array {
		$tokens = self::base();
		$colors = Manager::get_group( 'colors', array() );
		$typo   = Manager::get_group( 'typography', array() );
		$layout = Manager::get_group( 'general', array() );

		$map = array(
			'--kutby-color-primary'   => $colors['primary'] ?? null,
			'--kutby-color-secondary' => $colors['secondary'] ?? null,
			'--kutby-color-accent'    => $colors['accent'] ?? null,
			'--kutby-color-bg'        => $colors['background'] ?? null,
			'--kutby-color-surface'   => $colors['surface'] ?? null,
			'--kutby-color-card'      => $colors['card'] ?? null,
			'--kutby-color-border'    => $colors['border'] ?? null,
			'--kutby-color-text'      => $colors['text'] ?? null,
			'--kutby-color-muted'     => $colors['muted'] ?? null,
			'--kutby-color-success'   => $colors['success'] ?? null,
			'--kutby-color-warning'   => $colors['warning'] ?? null,
			'--kutby-color-danger'    => $colors['danger'] ?? null,
			'--kutby-color-link'      => $colors['link'] ?? null,
			'--kutby-color-hover'     => $colors['hover'] ?? null,
			'--kutby-font-family'     => '"Tajawal", Tahoma, sans-serif',
			'--kutby-font-size-body'  => isset( $typo['body_size'] ) ? ( (string) $typo['body_size'] ) . 'px' : null,
			'--kutby-line-height'     => isset( $typo['line_height'] ) ? (string) $typo['line_height'] : null,
			'--kutby-container-width' => isset( $layout['container_width'] ) ? ( (string) $layout['container_width'] ) . 'px' : null,
			'--kutby-site-width'      => isset( $layout['site_width'] ) ? ( (string) $layout['site_width'] ) . 'px' : null,
		);

		foreach ( $map as $prop => $value ) {
			if ( null !== $value && '' !== $value ) {
				$tokens[ $prop ] = (string) $value;
			}
		}

		/**
		 * Filter resolved CSS variables (BC with v1 filter name).
		 *
		 * @since 1.0.0
		 *
		 * @param array<string, string> $tokens Tokens.
		 */
		return apply_filters( 'kutby_css_variables', $tokens );
	}

	/**
	 * Build :root CSS block.
	 *
	 * @return string
	 */
	public static function to_css(): string {
		$rules = array();
		foreach ( self::resolved() as $prop => $value ) {
			$safe_prop  = self::sanitize_property( (string) $prop );
			$safe_value = self::sanitize_value( (string) $value );
			if ( '' === $safe_prop || '' === $safe_value ) {
				continue;
			}
			$rules[] = $safe_prop . ':' . $safe_value . ';';
		}

		return ':root{' . implode( '', $rules ) . '}';
	}

	/**
	 * Allow only CSS custom property names.
	 *
	 * @param string $prop Property.
	 * @return string
	 */
	private static function sanitize_property( string $prop ): string {
		$prop = strtolower( trim( $prop ) );
		if ( ! preg_match( '/^--[a-z0-9-]+$/', $prop ) ) {
			return '';
		}
		return $prop;
	}

	/**
	 * Sanitize a CSS value without HTML-encoding quotes (needed for font stacks).
	 *
	 * @param string $value Value.
	 * @return string
	 */
	private static function sanitize_value( string $value ): string {
		$value = wp_strip_all_tags( $value );
		$value = str_replace( array( '<', '>', '{', '}', ';' ), '', $value );
		return trim( $value );
	}
}
