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

class Input extends BaseField {
    public static function render(string $name, string $label, $value = '', array $opts = []): string {
        $validate = $opts['validate'] ?? [];
        $errors = $opts['errors'] ?? [];
        $help = $opts['help'] ?? '';
        $extra = $opts['input_attrs'] ?? '';

        $hasError = !empty($errors);
        $nameEsc = self::h($name);
        $labelEsc = self::h($label);
        $valEsc = self::h((string)$value);

        $vType = strtolower((string)($validate['type'] ?? 'string'));
        // Allow explicit HTML input type override via opts (e.g. date, datetime-local)
        $inputType = (string)($opts['input_type'] ?? '');
        if ($inputType === '') {
            $inputType = 'text';
            if ($vType === 'integer' || $vType === 'number' || $vType === 'float') $inputType = 'number';
            if ($vType === 'boolean') $inputType = 'checkbox';
            if ($vType === 'email') $inputType = 'email';
        }

        // Only include step for numeric inputs
        $stepAttr = '';
        if ($inputType === 'number') {
            $stepAttr = ' step="' . (($vType === 'integer') ? '1' : 'any') . '"';
        }
        $minAttr = isset($validate['min']) && $validate['min'] !== '' ? ' min="' . self::h((string)$validate['min']) . '"' : '';
        $maxAttr = isset($validate['max']) && $validate['max'] !== '' ? ' max="' . self::h((string)$validate['max']) . '"' : '';
        $requiredAttr = !empty($validate['required']) ? ' required' : '';

        $helpHtml = self::helpHtml($help);
        $errorHtml = self::errorsHtml($errors);
        $badge = $opts['label_badge_html'] ?? '';
        $clientErr = '<p class="mt-1 text-sm/6 text-red-600 dark:text-red-400" x-show="clientErrors && clientErrors[\'' . $nameEsc . '\'] && clientErrors[\'' . $nameEsc . '\'].length" x-text="(clientErrors && clientErrors[\'' . $nameEsc . '\'] && clientErrors[\'' . $nameEsc . '\'].length) ? clientErrors[\'' . $nameEsc . '\'][0] : \'\'"></p>';

        // Build an ID for label association
        $idBase = preg_replace('/[^a-zA-Z0-9_-]+/', '-', $name);
        $idBase = trim($idBase ?? '', '-');
        if ($idBase === '') { $idBase = 'input'; }
        $id = self::h($idBase);

        // Tailwind Plus input base classes
        $base = 'block w-full rounded-md bg-white px-3 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 focus:outline-brand sm:text-sm/6 dark:bg-white/5 dark:text-white dark:outline-white/10 dark:placeholder:text-gray-500 dark:outline-brand';
        $errorCls = $hasError ? ' outline-red-300 focus:outline-red-600 dark:outline-red-500/40 dark:focus:outline-red-500' : '';
        $inputClass = $base . $errorCls;

        // Optional addons (prefix/suffix) for input group, e.g., 'days'
        $addonPrefixRaw = (string)($opts['addon_prefix'] ?? '');
        $addonSuffixRaw = (string)($opts['addon_suffix'] ?? '');
        $addonPrefix = trim($addonPrefixRaw);
        $addonSuffix = trim($addonSuffixRaw);
        $hasAddon = ($addonPrefix !== '' || $addonSuffix !== '');

        // Group wrapper classes (mirrors Assistant input group styling)
        $groupBase = '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 focus-within:outline-brand dark:bg-white/5 dark:outline-white/10 dark:focus-within:outline-brand-500';
        $groupErr = $hasError ? ' outline-red-300 focus-within:outline-red-600 dark:outline-red-500/40 dark:focus-within:outline-red-500' : '';
        $groupClass = $groupBase . $groupErr;
        $groupInputClass = 'block min-w-0 grow bg-white py-1.5 pr-3 pl-1 text-base text-gray-900 placeholder:text-gray-400 focus:outline-none sm:text-sm/6 dark:bg-transparent dark:text-white dark:placeholder:text-gray-500';

        // Build a per-field client validation rule for fallback (data-validate)
        $clientRule = ['type' => $vType];
        if (!empty($validate['required'])) { $clientRule['required'] = true; }
        if (isset($validate['min']) && $validate['min'] !== '') { $clientRule['min'] = is_numeric($validate['min']) ? 0 + $validate['min'] : (string)$validate['min']; }
        if (isset($validate['max']) && $validate['max'] !== '') { $clientRule['max'] = is_numeric($validate['max']) ? 0 + $validate['max'] : (string)$validate['max']; }
        if (!empty($validate['compare'])) {
            $cmp = (array)$validate['compare'];
            $list = (isset($cmp['field']) && is_string($cmp['field'])) ? [$cmp] : array_values($cmp);
            $outCmp = [];
            foreach ($list as $c) {
                if (!is_array($c)) continue;
                $cf = (string)($c['field'] ?? ''); if ($cf === '') continue;
                $op = strtolower((string)($c['op'] ?? 'gte'));
                $item = ['field' => $cf, 'op' => $op];
                if (array_key_exists('offset', $c)) { $item['offset'] = $c['offset']; }
                if (!empty($c['message'])) { $item['message'] = (string)$c['message']; }
                $outCmp[] = $item;
            }
            if (!empty($outCmp)) { $clientRule['compare'] = $outCmp; }
        }
        $clientRuleAttr = " data-validate='" . htmlspecialchars(json_encode($clientRule), ENT_QUOTES) . "'";

        // Build inner control
        if ($hasAddon) {
            $prefixHtml = $addonPrefix !== '' ? '<div class="shrink-0 text-base text-gray-500 select-none sm:text-sm/6 dark:text-gray-400">' . self::h($addonPrefix) . '</div>' : '';
            $suffixHtml = $addonSuffix !== '' ? '<div class="shrink-0 text-base text-gray-500 select-none sm:text-sm/6 dark:text-gray-400">' . self::h($addonSuffix) . '</div>' : '';
            $inputInner = '<div class="' . $groupClass . '">'
                        . $prefixHtml
                        . '<input id="' . $id . '" name="' . $nameEsc . '" type="' . $inputType . '" value="' . $valEsc . '" class="' . $groupInputClass . '"' . $stepAttr . $minAttr . $maxAttr . $requiredAttr . $clientRuleAttr . ' ' . $extra . '/>'
                        . $suffixHtml
                        . '</div>';
        } else {
            $inputInner = '<input id="' . $id . '" name="' . $nameEsc . '" type="' . $inputType . '" value="' . $valEsc . '" class="' . $inputClass . '"' . $stepAttr . $minAttr . $maxAttr . $requiredAttr . $clientRuleAttr . ' ' . $extra . '/>';
        }

        return <<<HTML
<div>
<label for="{$id}" class="block text-sm/6 font-medium text-gray-900 dark:text-white">{$labelEsc}{$badge}</label>
<div class="mt-2">
  {$inputInner}
</div>
{$helpHtml}
{$errorHtml}
{$clientErr}
</div>
HTML;
    }
}
