import { useId, type InputHTMLAttributes, type ReactNode, type TextareaHTMLAttributes } from "react";
import { cn } from "./cn.js";

export interface FieldFrameProps {
  label: string;
  hint?: string;
  description?: string;
  htmlFor?: string;
  children: ReactNode;
  className?: string;
}

export function FieldFrame({ label, hint, description, htmlFor, children, className }: FieldFrameProps) {
  return (
    <label className={cn("nodedc-field", className)} htmlFor={htmlFor}>
      <span className="nodedc-field__label-row">
        <span className="nodedc-field__label">{label}</span>
        {hint ? <span className="nodedc-field__hint">{hint}</span> : null}
      </span>
      {children}
      {description ? <span className="nodedc-field__description">{description}</span> : null}
    </label>
  );
}

export interface TextFieldProps extends InputHTMLAttributes<HTMLInputElement> {
  label: string;
  hint?: string;
  description?: string;
  fieldClassName?: string;
}

export function TextField({
  label,
  hint,
  description,
  fieldClassName,
  className,
  id,
  ...props
}: TextFieldProps) {
  const generatedId = useId();
  const controlId = id ?? generatedId;
  return (
    <FieldFrame label={label} hint={hint} description={description} htmlFor={controlId} className={fieldClassName}>
      <input id={controlId} className={cn("nodedc-field__control", className)} {...props} />
    </FieldFrame>
  );
}

export interface TextAreaFieldProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
  label: string;
  hint?: string;
  description?: string;
  fieldClassName?: string;
}

export function TextAreaField({
  label,
  hint,
  description,
  fieldClassName,
  className,
  id,
  ...props
}: TextAreaFieldProps) {
  const generatedId = useId();
  const controlId = id ?? generatedId;
  return (
    <FieldFrame label={label} hint={hint} description={description} htmlFor={controlId} className={fieldClassName}>
      <textarea id={controlId} className={cn("nodedc-field__control", className)} {...props} />
    </FieldFrame>
  );
}

