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

class Password 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);

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

        // Group wrapper classes (mirrors Assistant input group styling from Input)
        $groupClass = self::groupClass($hasError);
        $groupInputClass = 'block min-w-0 grow 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';

        // Optional addons (prefix/suffix) for input group
        $addonPrefixRaw = (string)($opts['addon_prefix'] ?? '');
        $addonSuffixRaw = (string)($opts['addon_suffix'] ?? '');
        $addonPrefix = trim($addonPrefixRaw);
        $addonSuffix = trim($addonSuffixRaw);
        $prefixHtml = '';
        if ($addonPrefix !== '') {
            $prefixEsc = self::h($addonPrefix);
            $prefixHtml = <<<HTML
<div class="shrink-0 text-base text-gray-500 select-none sm:text-sm 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 dark:text-gray-400">{$suffixEsc}</div>
HTML;
        }

        // Required attribute and client-side rule (compatible with Input)
        $requiredAttr = !empty($validate['required']) ? ' required' : '';
        $vType = strtolower((string)($validate['type'] ?? 'string'));
        $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) . "'";

        $badge = $opts['label_badge_html'] ?? '';
        $helpHtml = self::helpHtml($help);
        $errorHtml = self::errorsHtml($errors);
        $clientErr = self::clientErrorHtml($name);
        $labelHtml = '';
        if (!($opts['no_label'] ?? false)) {
            $labelHtml = self::renderLabel($id, $label, $badge, $opts);
        }

        $inputWrapperClass = $opts['no_label'] ?? false ? '' : 'mt-2';
        $eyeSvg = self::SVG_EYE;
        $eyeSlashSvg = self::SVG_EYE_SLASH;

        // Build input + toggle button inside group with Alpine
        $inputInner = <<<HTML
<div class="$groupClass" x-data="{ show: false }">
  {$prefixHtml}
  <input id="{$id}" x-ref="pw" name="{$nameEsc}" type="password" :type="show ? 'text' : 'password'" value="{$valEsc}" class="{$groupInputClass}" autocomplete="current-password"{$requiredAttr}{$clientRuleAttr} {$extra}/>
  {$suffixHtml}
  <button type="button" class="ml-2 shrink-0 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 focus:outline-none" @click="show = !show" :aria-label="show ? 'Hide password' : 'Show password'">
    <span x-show="!show" x-cloak>{$eyeSvg}</span>
    <span x-show="show" x-cloak>{$eyeSlashSvg}</span>
  </button>
</div>
HTML;

        return self::renderContainer($labelHtml, $inputInner, $helpHtml, $errorHtml, $clientErr, $opts);
    }
}
