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

abstract class RadioBase extends BaseField
{
    protected static function buildRadioFieldContext(string $name, string $label, array $opts): array
    {
        $validate = $opts['validate'] ?? [];
        $errors = $opts['errors'] ?? [];
        $help = $opts['help'] ?? '';

        $hasError = !empty($errors);

        return [
            'name' => $name,
            'name_esc' => self::h($name),
            'label_esc' => self::h(self::lng($label)),
            'required_attr' => !empty($validate['required']) ? ' required' : '',
            'group_error_class' => $hasError ? ' ring-1 ring-red-500/50 rounded-md p-1' : '',
            'container_class' => (string)($opts['container_class'] ?? ''),
            'help_html' => self::helpHtml($help),
            'error_html' => self::errorsHtml($errors),
            'client_err_html' => self::clientErrorHtml($name),
            'badge_html' => (string)($opts['label_badge_html'] ?? ''),
            'extra_attrs' => (string)($opts['input_attrs'] ?? ''),
        ];
    }

    protected static function normalizeOptions(array $options, $value = ''): array
    {
        $items = [];
        $current = (string)$value;

        foreach ($options as $val => $opt) {
            $valStr = (string)$val;
            $isArray = is_array($opt);

            $optLabelRaw = $isArray ? (string)($opt['label'] ?? $valStr) : (string)$opt;
            $optDescRaw = $isArray ? (string)($opt['description'] ?? '') : '';
            $optMetaRaw = $isArray ? (string)($opt['meta'] ?? '') : '';
            $optIconHtml = $isArray ? (string)($opt['icon'] ?? '') : '';
            $optToken = $isArray ? (string)($opt['token'] ?? ($opt['color'] ?? '')) : '';
            $ariaLabelRaw = $isArray ? (string)($opt['aria_label'] ?? $optLabelRaw) : $optLabelRaw;
            $ariaDescRaw = $isArray ? (string)($opt['aria_description'] ?? $optDescRaw) : $optDescRaw;

            $disabled = false;
            if ($isArray && array_key_exists('disabled', $opt)) {
                $disabledRaw = $opt['disabled'];
                if (is_bool($disabledRaw)) {
                    $disabled = $disabledRaw;
                } elseif (is_numeric($disabledRaw)) {
                    $disabled = ((int)$disabledRaw) !== 0;
                } elseif (is_string($disabledRaw)) {
                    $disabled = in_array(strtolower(trim($disabledRaw)), ['1', 'true', 'yes', 'on'], true);
                }
            }

            // For scalar lists like ['all','shop'], use the scalar as value instead of numeric key.
            if (!$isArray && (is_int($val) || (is_string($val) && ctype_digit($val)))) {
                $valStr = (string)$optLabelRaw;
            }

            $optLabel = self::lng($optLabelRaw);
            $optDesc = self::lng($optDescRaw);
            $optMeta = self::lng($optMetaRaw);
            $ariaLabel = self::lng($ariaLabelRaw);
            $ariaDesc = self::lng($ariaDescRaw);

            $checked = self::isSelectedOption($current, $valStr);
            $applicability = $isArray ? ($opt['applicability'] ?? null) : null;

            $items[] = [
                'value' => $valStr,
                'label' => $optLabel,
                'description' => $optDesc,
                'meta' => $optMeta,
                'icon' => $optIconHtml,
                'token' => $optToken,
                'aria_label' => $ariaLabel,
                'aria_description' => $ariaDesc,
                'disabled' => $disabled,
                'disabled_attr' => $disabled ? ' disabled' : '',
                'checked' => $checked,
                'checked_attr' => $checked ? ' checked' : '',
                'applicability' => $applicability,
            ];
        }

        return $items;
    }

    protected static function normalizeGroupedOption(array $item, string $current = ''): ?array
    {
        $valStr = (string)($item['id'] ?? $item['value'] ?? $item['key'] ?? '');
        if ($valStr === '') {
            return null;
        }

        $label = self::lng((string)($item['text'] ?? $item['label'] ?? $item['name'] ?? $valStr));
        $description = self::lng((string)($item['description'] ?? $item['desc'] ?? ''));
        $meta = self::lng((string)($item['meta'] ?? ''));
        $icon = (string)($item['icon'] ?? '');
        $token = (string)($item['token'] ?? ($item['color'] ?? ''));

        $checked = self::isSelectedOption($current, $valStr);
        $applicability = $item['applicability'] ?? null;

        return [
            'value' => $valStr,
            'label' => $label,
            'description' => $description,
            'meta' => $meta,
            'icon' => $icon,
            'token' => $token,
            'checked' => $checked,
            'checked_attr' => $checked ? ' checked' : '',
            'applicability' => $applicability,
        ];
    }

    protected static function renderOptionIcon(
        string $iconHtml,
        string $token = '',
        string $wrapperBase = 'mr-2 shrink-0 inline-flex size-10 items-center justify-center rounded-md text-white',
        string $innerClass = '[&_svg]:size-6'
    ): string {
        if ($iconHtml === '') {
            return '';
        }

        try {
            $bg = \Components\Support\Palette::dotBg($token !== '' ? $token : 'indigo', 'indigo');
        } catch (\Throwable $e) {
            $bg = 'bg-indigo-500';
        }

        $wrapClass = trim($wrapperBase . ' ' . $bg);
        return '<span class="' . $wrapClass . '"><span class="' . $innerClass . '">' . $iconHtml . '</span></span>';
    }

    protected static function buildGridClasses(array $gridCfg, int $defaultBase = 1, int $defaultSm = 3): string
    {
        $baseCols = (int)($gridCfg['base'] ?? $defaultBase);
        $smCols = (int)($gridCfg['sm'] ?? ($gridCfg['cols'] ?? $defaultSm));
        $mdCols = (int)($gridCfg['md'] ?? 0);
        $lgCols = (int)($gridCfg['lg'] ?? 0);
        $xlCols = (int)($gridCfg['xl'] ?? 0);

        $gridClasses = 'grid grid-cols-' . max(1, $baseCols) . ' gap-y-3';
        $gridClasses .= ' sm:gap-x-4';
        if ($smCols > 0) { $gridClasses .= ' sm:grid-cols-' . $smCols; }
        if ($mdCols > 0) { $gridClasses .= ' md:grid-cols-' . $mdCols; }
        if ($lgCols > 0) { $gridClasses .= ' lg:grid-cols-' . $lgCols; }
        if ($xlCols > 0) { $gridClasses .= ' xl:grid-cols-' . $xlCols; }

        return $gridClasses;
    }

    protected static function isSelectedOption(string $current, string $candidate): bool
    {
        $current = trim($current);
        $candidate = trim($candidate);

        if ($current === '' || $candidate === '') {
            return false;
        }

        if ($current === $candidate) {
            return true;
        }

        return strcasecmp($current, $candidate) === 0;
    }

    protected static function slugify(string $value): string
    {
        $slug = strtolower((string)preg_replace('/[^a-z0-9]+/i', '-', $value));
        $slug = trim($slug, '-');
        return $slug !== '' ? $slug : 'radio';
    }
}
