<?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 = self::clientErrorHtml($name);

        // 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);

        // Standardized icon support
        $prefixIconHtml = (string)($opts['prefix_icon_html'] ?? '');
        $suffixIconHtml = (string)($opts['suffix_icon_html'] ?? '');
        $showReset = !empty($opts['show_reset']);

        if ($showReset && $suffixIconHtml === '') {
            // Alpine.js reset logic
            $suffixIconHtml = '<button type="button" aria-label="Clear"
                x-show="($el.parentElement.parentElement.querySelector(\'input\').value || \'\') !== \'\'" 
                @click="$el.parentElement.parentElement.querySelector(\'input\').value = \'\'; $el.parentElement.parentElement.querySelector(\'input\').dispatchEvent(new Event(\'search\')); $el.parentElement.parentElement.querySelector(\'input\').dispatchEvent(new Event(\'input\'));" 
                class="flex items-center justify-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 focus:outline-none">' . self::SVG_X_MARK . '</button>';
        }

        $hasIcon = ($prefixIconHtml !== '' || $suffixIconHtml !== '');


        // Adjust padding if icons are present
        $paddingCls = ' px-3';
        if ($prefixIconHtml !== '') { $paddingCls = ' pl-10 pr-3'; }
        if ($suffixIconHtml !== '') {
            if ($prefixIconHtml !== '') { $paddingCls = ' pl-10 pr-10'; }
            else { $paddingCls = ' pl-3 pr-10'; }
        }

        $inputClass = self::inputClass($hasError) . $paddingCls;

        // 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)
        $groupClass = self::groupClass($hasError);
        $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];
                $offset = $c['offset'] ?? 0;
                if (array_key_exists('offset', $c)) { $item['offset'] = $offset; }
                if (!empty($c['message'])) {
                    $item['message'] = \Components\Form\Validation::translateCompareMessage((string)$c['message'], $offset, $cf, $opts['fields'] ?? []);
                }
                $outCmp[] = $item;
            }
            if (!empty($outCmp)) { $clientRule['compare'] = $outCmp; }
        }
        $clientRuleAttr = " data-validate='" . htmlspecialchars(json_encode($clientRule), ENT_QUOTES) . "'";

        // Build inner control
        if ($hasAddon) {
            $prefixHtml = '';
            if ($addonPrefix !== '') {
                $prefixEsc = self::h($addonPrefix);
                $prefixHtml = <<<HTML
<div class="shrink-0 text-base text-gray-500 select-none sm:text-sm/6 dark:text-gray-400">{$prefixEsc}</div>
HTML;
            }

            $suffixHtml = '';
            if ($addonSuffix !== '') {
                $suffixEsc = self::h($addonSuffix);
                $suffixHtml = <<<HTML
<div class="shrink-0 text-base text-gray-500 select-none sm:text-sm/6 dark:text-gray-400">{$suffixEsc}</div>
HTML;
            }

            $inputInner = <<<HTML
<div class="{$groupClass}">
    {$prefixHtml}
    <input id="{$id}" name="{$nameEsc}" type="{$inputType}" value="{$valEsc}" class="{$groupInputClass}"{$stepAttr}{$minAttr}{$maxAttr}{$requiredAttr}{$clientRuleAttr} {$extra}/>
    {$suffixHtml}
</div>
HTML;
        } elseif ($hasIcon) {
            $prefixIcon = '';
            if ($prefixIconHtml !== '') {
                $prefixIcon = <<<HTML
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3 text-gray-400 [&_svg]:size-4">
    {$prefixIconHtml}
</div>
HTML;
            }
            $suffixIcon = '';
            if ($suffixIconHtml !== '') {
                $suffixIcon = <<<HTML
<div class="absolute inset-y-0 right-0 flex items-center pr-3 [&_svg]:size-4">
    {$suffixIconHtml}
</div>
HTML;
            }

            $inputInner = <<<HTML
<div class="relative">
    {$prefixIcon}
    <input id="{$id}" name="{$nameEsc}" type="{$inputType}" value="{$valEsc}" class="{$inputClass}"{$stepAttr}{$minAttr}{$maxAttr}{$requiredAttr}{$clientRuleAttr} {$extra}/>
    {$suffixIcon}
</div>
HTML;
        } else {
            $inputInner = <<<HTML
<input id="{$id}" name="{$nameEsc}" type="{$inputType}" value="{$valEsc}" class="{$inputClass}"{$stepAttr}{$minAttr}{$maxAttr}{$requiredAttr}{$clientRuleAttr} {$extra}/>
HTML;
        }

        $labelHtml = '';
        if (!($opts['no_label'] ?? false)) {
            $labelCls = self::labelClass();
            $labelHtml = <<<HTML
<label for="{$id}" class="{$labelCls}">{$labelEsc}{$badge}</label>
HTML;
        }

        $inputWrapperClass = $opts['no_label'] ?? false ? '' : 'mt-2';
        $containerClass = (string)($opts['container_class'] ?? '');

        return <<<HTML
<div class="{$containerClass}">
{$labelHtml}
<div class="{$inputWrapperClass}">
  {$inputInner}
</div>
{$helpHtml}
{$errorHtml}
{$clientErr}
</div>
HTML;
    }
}
