<?php

namespace Formatrica\Frontend;

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

/**
 * Resolves the appearance-theme block to the markup a form wrapper needs:
 * a preset modifier class, mode/preset data attributes, and the brand-colour
 * custom properties.
 *
 * Lives in CORE and is capability-blind: a form authored with a Pro preset (P17)
 * keeps rendering that preset after a licence lapse — only authoring is gated.
 * The brand colour is wired to --fmt-accent, which the stylesheet uses purely as
 * a state cue (focus ring, selected controls, primary CTA); semantic
 * error/warning/success colours use their own vars and are never overridden.
 */
final class Theme_Overlay_Resolver
{
    private const KNOWN_PRESETS = ['classic', 'material', 'clean', 'card', 'underline'];
    private const KNOWN_MODES   = ['inherit', 'light', 'dark', 'auto'];

    /**
     * Extra class for the form wrapper. Classic is the no-overlay default, so it
     * adds nothing; the Pro presets add a modifier the theme stylesheet targets.
     *
     * @param array<string, mixed> $theme
     */
    public function modifier_class(array $theme): string
    {
        // Preset overlays are Pro (forms.themes): the modifier class the
        // preset stylesheet targets is contributed by the Pro package via
        // this filter (Phase-5 completion). Free adds none - and since the
        // preset stylesheet also ships only in Pro, a preserved preset
        // degrades to the classic look on a Free install.
        return (string) apply_filters('formatrica_theme_preset_class', '', $this->preset($theme));
    }

    /**
     * Wrapper attributes: data-fmt-theme / data-fmt-mode, plus brand-colour
     * custom properties when a brand colour is set. Returns a leading-space
     * string ready to splice into the <form> tag, already escaped.
     *
     * @param array<string, mixed> $theme
     */
    public function inline_attributes(array $theme): string
    {
        $attrs = sprintf(
            ' data-fmt-theme="%s" data-fmt-mode="%s"',
            esc_attr($this->preset($theme)),
            esc_attr($this->mode($theme))
        );

        $brand = $this->brand_color($theme);
        if ($brand !== '') {
            // Only state-cue custom properties. Semantic colours are untouched.
            $style = sprintf(
                '--fmt-accent:%1$s;--fmt-focus-ring:color-mix(in srgb, %1$s 22%%, transparent);',
                $brand
            );
            $attrs .= ' style="' . esc_attr($style) . '"';
        }

        return $attrs;
    }

    /**
     * @param array<string, mixed> $theme
     */
    private function preset(array $theme): string
    {
        $preset = isset($theme['preset']) && is_string($theme['preset']) ? $theme['preset'] : 'classic';
        return in_array($preset, self::KNOWN_PRESETS, true) ? $preset : 'classic';
    }

    /**
     * @param array<string, mixed> $theme
     */
    private function mode(array $theme): string
    {
        $mode = isset($theme['mode']) && is_string($theme['mode']) ? $theme['mode'] : 'inherit';
        return in_array($mode, self::KNOWN_MODES, true) ? $mode : 'inherit';
    }

    /**
     * @param array<string, mixed> $theme
     */
    private function brand_color(array $theme): string
    {
        $brand = isset($theme['brand_color']) && is_string($theme['brand_color']) ? strtolower(trim($theme['brand_color'])) : '';
        return preg_match('/^#[0-9a-f]{6}$/', $brand) === 1 ? $brand : '';
    }
}
