import type { ChangeEventHandler } from 'react';
import { ChevronDownIcon } from '@heroicons/react/24/solid';
import type { ComponentSize } from './types';

type DropdownLayout = 'stacked' | 'inline';

type DropdownChoice = {
  label: string;
  id: string;
};

type DropdownProps = {
  label?: string;
  value: string;
  choices: DropdownChoice[];
  size?: ComponentSize;
  layout?: DropdownLayout;
  disabled?: boolean;
  required?: boolean;
  onChange?: (value: string) => void;
  error?: string;
  className?: string;
  selectClassName?: string;
};

export function Dropdown({
  label,
  value,
  choices,
  size = 'md',
  layout = 'stacked',
  disabled = false,
  required = false,
  onChange,
  error,
  className = '',
  selectClassName = ''
}: Readonly<DropdownProps>) {
  const containerSizeClass = {
    sm: 'max-w-xs',
    md: 'max-w-sm',
    lg: 'max-w-md',
    full: 'max-w-none'
  }[size];

  const selectSizeClass = {
    sm: 'h-8 !text-xs',
    md: 'h-10 text-sm',
    lg: 'h-12 text-sm',
    full: 'h-10 text-sm'
  }[size];

  const handleChange: ChangeEventHandler<HTMLSelectElement> = (event) => {
    onChange?.(event.target.value);
  };

  const wrapperClass = layout === 'inline'
    ? 'inline-flex w-auto items-center gap-2'
    : 'block w-full gap-1';

  const selectWrapperClass = layout === 'inline' ? 'relative' : 'relative mt-1';
  const labelClass = layout === 'inline' ? 'text-xs ui-body-secondary' : '';

  return (
    <label className={`${wrapperClass} text-sm font-medium ${disabled ? 'ui-label-disabled' : 'ui-label'} ${containerSizeClass} ${className}`.trim()}>
      {label ? <span className={labelClass}>{label}</span> : null}
      <div className={selectWrapperClass}>
        <select
          value={value}
          onChange={handleChange}
          disabled={disabled}
          required={required}
          className={`field w-full appearance-none pr-9 disabled:opacity-100 ${selectSizeClass} ${error ? 'border-red-400/70 focus:border-red-400 focus:ring-red-400/30' : ''} ${selectClassName}`.trim()}
        >
          {choices.map((choice) => (
            <option key={choice.id} value={choice.id}>
              {choice.label}
            </option>
          ))}
        </select>
        <span className={`pointer-events-none absolute inset-y-0 right-3 flex items-center ${disabled ? 'ui-label-disabled' : 'ui-body-secondary'}`}>
          <ChevronDownIcon className="h-4 w-4" aria-hidden="true" />
        </span>
      </div>
      {error ? <span className="mt-1 block text-xs" style={{ color: 'var(--error-text)' }}>{error}</span> : null}
    </label>
  );
}
