<?php
// components/Form/BaseField.php
namespace Components\Form;

abstract class BaseField extends \Components\Base {
    protected static function helpHtml(?string $help): string {
        if (!$help || trim($help) === '') { return ''; }
        // Delegate to Base::h with limited HTML allowance so this behavior is shared across all outputs
        $allowedTags = '<br><br/><b><strong><i><em><u><a>';
        $safe = \Components\Base::h($help, ['allow_html' => true, 'allowed_tags' => $allowedTags]);
        return <<<HTML
<p class="mt-1 text-sm text-secondary/70 dark:text-secondary">{$safe}</p>
HTML;
    }

    protected static function errorsHtml(array $errors): string {
        if (empty($errors)) return '';
        $errEsc = self::h(implode(' ', $errors));
        return <<<HTML
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{$errEsc}</p>
HTML;
    }

    protected static function clientErrorHtml(string $name): string
    {
        $nameEsc = self::h($name);
        return <<<HTML
<p class="mt-1 text-sm/6 text-red-600 dark:text-red-400" x-show="typeof clientErrors !== 'undefined' && clientErrors && clientErrors['{$nameEsc}'] && clientErrors['{$nameEsc}'].length" x-text="(typeof clientErrors !== 'undefined' && clientErrors && clientErrors['{$nameEsc}'] && clientErrors['{$nameEsc}'].length) ? clientErrors['{$nameEsc}'][0] : ''"></p>
HTML;
    }

    protected static function fieldBaseClass(bool $hasError): string {
        // Legacy helper retained for components that still use it
        return 'mt-1 block w-full rounded border ' . ($hasError ? 'border-red-300 focus:border-red-500' : 'border-gray-300 focus:border-brand');
    }

    protected static function labelClass(): string {
        return 'block text-sm/6 font-medium text-gray-900 dark:text-white';
    }

    protected static function inputClass(bool $hasError = false): string {
        $base = 'block w-full rounded-md bg-white py-1.5 text-base text-gray-900 outline-1 __-outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 sm:text-sm/6 dark:bg-white/5 dark:text-white dark:outline-white/10 dark:placeholder:text-gray-500';
        $error = $hasError ? ' outline-red-300 focus:outline-red-600 dark:outline-red-500/40 dark:focus:outline-red-500' : ' focus:outline-brand dark:focus:outline-brand';
        return $base . $error;
    }

    protected static function groupClass(bool $hasError = false): string {
        $base = 'flex min-w-0 items-center rounded-md bg-white px-3 outline outline-1 -outline-offset-1 outline-gray-300 focus-within:outline-2 focus-within:-outline-offset-2 dark:bg-white/5 dark:outline-white/10';
        $error = $hasError ? ' outline-red-300 focus-within:outline-red-600 dark:outline-red-500/40 dark:focus-within:outline-red-500' : ' focus-within:outline-brand dark:focus-within:outline-brand-500';
        return $base . $error;
    }

    /**
     * Map a language code (e.g. en, en_US) to a flag-icons country code (e.g. gb, us)
     */
    protected static function flagCountryFromLang(string $code): ?string {
        $c = strtolower(trim($code));
        if ($c === '') return null;
        // If code contains region (en_US, pt-BR), prefer region part as the country code
        if (strpos($c, '-') !== false || strpos($c, '_') !== false) {
            $parts = preg_split('/[-_]/', $c);
            $region = end($parts);
            if ($region && preg_match('/^[a-z]{2}$/', $region)) return $region;
        }
        // Common language -> country fallbacks
        $map = [
            'en' => 'gb', // default to GB for generic English
            'english' => 'gb',
            'de' => 'de',
            'german' => 'de',
            'fr' => 'fr',
            'french' => 'fr',
            'es' => 'es',
            'spanish' => 'es',
            'it' => 'it',
            'italian' => 'it',
            'pt' => 'pt',
            'portuguese' => 'pt',
            'nl' => 'nl',
            'dutch' => 'nl',
            'da' => 'dk',
            'sv' => 'se',
            'fi' => 'fi',
            'no' => 'no',
            'nn' => 'no',
            'nb' => 'no',
            'pl' => 'pl',
            'cs' => 'cz',
            'sk' => 'sk',
            'ro' => 'ro',
            'hu' => 'hu',
            'ru' => 'ru',
            'uk' => 'ua',
            'tr' => 'tr',
            'el' => 'gr',
            'zh' => 'cn',
            'ja' => 'jp',
            'ko' => 'kr',
            'ar' => 'sa',
            'he' => 'il',
            'th' => 'th',
            'vi' => 'vn',
            'id' => 'id',
            'ms' => 'my', // Malay -> Malaysia
        ];
        if (isset($map[$c])) return $map[$c];
        // If code itself is a valid-looking 2-letter country, use it
        if (preg_match('/^[a-z]{2}$/', $c)) return $c;
        return null;
    }

    /**
     * Return span HTML for a flag icon given a language code. Returns empty string if not resolvable.
     *
     * @param string|null $langCode
     * @param string $extraClasses
     * @param string $type 'default' (3x4) or 'circle' (1x1 square)
     * @return string
     */
    public static function flagIconHtml(?string $langCode, string $extraClasses = '', string $type = 'default'): string {
        $cc = $langCode ? self::flagCountryFromLang($langCode) : null;
        if (!$cc) return '';

        $isCircle = $type === 'circle';
        // Always use fi and fi-<cc> as base. If circle, add fis modifier for 1x1 square
        $cls = 'fi fi-' . self::h($cc) . ($isCircle ? ' fis' : '') . ($extraClasses ? (' ' . trim($extraClasses)) : '');
        $rounding = $isCircle ? 'rounded-full' : 'rounded-xs';

        // Check if size or alignment are already provided in extraClasses
        $hasSize = preg_match('/\b(text|size)-/', $extraClasses);
        $hasAlign = preg_match('/\balign-/', $extraClasses);

        $defaultSize = $hasSize ? '' : ' text-sm';
        $defaultAlign = $hasAlign ? '' : ' align-[-0.125em]';

        // flag-icons scales with font-size; tailwind text-sm gives a nice size and align a bit with text
        return <<<HTML
<span class="{$cls}{$defaultSize}{$defaultAlign} {$rounding}"></span>
HTML;
    }
}
