import {
  useCallback,
  useId,
  type InputHTMLAttributes,
  type SelectHTMLAttributes,
  type TextareaHTMLAttributes,
} from "react";
import { cn } from "@/lib/utils";
import { preventNumberInputWheel } from "@/lib/number-input";
export function Field({
  label,
  className,
  ...props
}: InputHTMLAttributes<HTMLInputElement> & {
  label: string;
}) {
  const id = useId();
  const isNumberInput = props.type === "number";
  const inputRef = useCallback(
    (node: HTMLInputElement | null) => {
      if (!node || !isNumberInput) return;
      return preventNumberInputWheel(node);
    },
    [isNumberInput],
  );
  return (
    <label className="block text-sm" htmlFor={id}>
      <span className="field-label">
        {label}
        {props.required ? " *" : ""}
      </span>
      <input
        id={id}
        ref={inputRef}
        className={cn(
          "form-input",
          isNumberInput &&
            "[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none",
          className,
        )}
        {...props}
      />
    </label>
  );
}
export function SelectField({
  label,
  options,
  ...props
}: SelectHTMLAttributes<HTMLSelectElement> & {
  label: string;
  options: readonly (string | { value: string; label: string })[];
}) {
  const id = useId();
  return (
    <label className="block text-sm" htmlFor={id}>
      <span className="field-label">{label}</span>
      <select id={id} className="form-input" {...props}>
        {options.map((o) => {
          const v = typeof o === "string" ? o : o.value;
          return (
            <option key={v} value={v}>
              {typeof o === "string" ? o : o.label}
            </option>
          );
        })}
      </select>
    </label>
  );
}
export function TextareaField({
  label,
  ...props
}: TextareaHTMLAttributes<HTMLTextAreaElement> & { label: string }) {
  const id = useId();
  return (
    <label className="block text-sm" htmlFor={id}>
      <span className="field-label">{label}</span>
      <textarea id={id} className="form-input min-h-28" {...props} />
    </label>
  );
}
