import type { InputHTMLAttributes, ReactNode, TextareaHTMLAttributes } from 'react';

interface BaseProps {
  label: string;
  htmlFor: string;
  error?: string | null;
  hint?: string;
  required?: boolean;
  children: ReactNode;
}

export function FormField({ label, htmlFor, error, hint, required, children }: BaseProps): JSX.Element {
  return (
    <div className="flex flex-col gap-xs">
      <label htmlFor={htmlFor} className="text-[14px] font-medium text-ink">
        {label}
        {required ? <span className="text-bloom-deep ml-1">*</span> : null}
      </label>
      {children}
      {error ? (
        <span role="alert" className="text-[12px] text-bloom-deep">
          {error}
        </span>
      ) : hint ? (
        <span className="text-[12px] text-graphite">{hint}</span>
      ) : null}
    </div>
  );
}

export function TextInput(props: InputHTMLAttributes<HTMLInputElement>): JSX.Element {
  return <input {...props} className={`text-input ${props.className ?? ''}`} />;
}

export function TextArea(props: TextareaHTMLAttributes<HTMLTextAreaElement>): JSX.Element {
  return (
    <textarea
      {...props}
      className={`text-input min-h-[112px] py-sm ${props.className ?? ''}`}
    />
  );
}

interface SelectOption {
  value: string;
  label: string;
}

interface SelectProps extends Omit<InputHTMLAttributes<HTMLSelectElement>, 'children'> {
  options: SelectOption[];
}

export function Select({ options, className, ...rest }: SelectProps): JSX.Element {
  return (
    <select {...rest} className={`text-input ${className ?? ''}`}>
      {options.map((o) => (
        <option key={o.value} value={o.value}>
          {o.label}
        </option>
      ))}
    </select>
  );
}
