import { useState, type InputHTMLAttributes } from "react";
import { AppIcon } from "./AppIcons";

type Props = InputHTMLAttributes<HTMLInputElement> & {
  label?: string;
  hint?: string;
  /** 欄位旁錯誤（比頁首 banner 更直覺） */
  error?: string;
  /** 密碼欄右側顯示／隱藏切換 */
  revealPassword?: boolean;
  revealShowLabel?: string;
  revealHideLabel?: string;
};

export function Input({
  label,
  hint,
  error,
  id,
  className = "",
  required,
  type,
  revealPassword = false,
  revealShowLabel = "Show password",
  revealHideLabel = "Hide password",
  ...rest
}: Props) {
  const [visible, setVisible] = useState(false);
  const inputId = id || rest.name;
  const errId = error && inputId ? `${inputId}-error` : undefined;
  const resolvedType = revealPassword && type === "password" && visible ? "text" : type;
  return (
    <label className={`hb-field${error ? " is-invalid" : ""}`} htmlFor={inputId}>
      {label ? (
        <span className="hb-field__label">
          {label}
          {required ? <span className="hb-field__required" aria-hidden="true">*</span> : null}
        </span>
      ) : null}
      <span className={`hb-input-shell${revealPassword ? " has-reveal" : ""}`}>
        <input
          id={inputId}
          type={resolvedType}
          className={`hb-input ${className}`.trim()}
          required={required}
          aria-invalid={error ? true : undefined}
          aria-describedby={errId}
          {...rest}
        />
        {revealPassword ? (
          <button
            type="button"
            className="hb-password-toggle"
            aria-label={visible ? revealHideLabel : revealShowLabel}
            aria-pressed={visible}
            onClick={() => setVisible((v) => !v)}
          >
            <AppIcon name="visibility" size={20} play="click" />
          </button>
        ) : null}
      </span>
      {error ? (
        <span className="hb-field__error" id={errId} role="alert">
          {error}
        </span>
      ) : hint ? (
        <span className="hb-field__hint">{hint}</span>
      ) : null}
    </label>
  );
}
