// components/ui/Input.tsx
// Labeled, accessible text input. Server-safe.
//
// Accessibility (WCAG 2.1 AA):
//   - Every input has an associated <label> (htmlFor/id).
//   - Errors are TEXT, not color-only, and wired via aria-describedby +
//     aria-invalid so screen readers announce them.
//   - Min 44px tap target height.
//   - inputMode passthrough for mobile keyboards (tel / email / numeric).

import * as React from "react";

export interface InputProps
  extends React.InputHTMLAttributes<HTMLInputElement> {
  /** Visible label text (required for accessibility). */
  label: string;
  /** Field id; auto-generated from name if omitted. */
  id?: string;
  /** Error message (text, announced to screen readers). */
  error?: string;
  /** Helper/hint text shown below the field. */
  hint?: string;
}

export const Input = React.forwardRef<HTMLInputElement, InputProps>(
  function Input(
    { label, id, name, error, hint, className = "", required, ...rest },
    ref,
  ) {
    const fieldId = id ?? (name ? `field-${name}` : undefined);
    const errorId = fieldId ? `${fieldId}-error` : undefined;
    const hintId = fieldId ? `${fieldId}-hint` : undefined;
    const describedBy =
      [error ? errorId : null, hint ? hintId : null]
        .filter(Boolean)
        .join(" ") || undefined;

    const inputCls = [
      "w-full min-h-[44px] rounded-md border px-4 py-2.5",
      "font-body text-body-lg text-ink-strong bg-canvas",
      "placeholder:text-muted",
      "focus-visible:outline focus-visible:outline-[3px] focus-visible:outline-offset-1",
      "focus-visible:outline-steelblue",
      error ? "border-primary" : "border-track",
      className,
    ]
      .filter(Boolean)
      .join(" ");

    return (
      <div className="flex flex-col gap-1.5">
        <label
          htmlFor={fieldId}
          className="font-body text-body-md font-medium text-ink-strong"
        >
          {label}
          {required ? (
            <span className="text-primary" aria-hidden="true">
              {" "}
              *
            </span>
          ) : null}
        </label>
        <input
          ref={ref}
          id={fieldId}
          name={name}
          required={required}
          aria-invalid={error ? true : undefined}
          aria-describedby={describedBy}
          className={inputCls}
          {...rest}
        />
        {hint && !error ? (
          <p id={hintId} className="font-body text-caption text-muted">
            {hint}
          </p>
        ) : null}
        {error ? (
          <p
            id={errorId}
            role="alert"
            className="font-body text-caption text-primary"
          >
            {error}
          </p>
        ) : null}
      </div>
    );
  },
);
