import { type SelectHTMLAttributes } from 'react';

import {
    formControlClassName,
    formErrorClassName,
    formFieldClassName,
    formHelpClassName,
    formLabelClassName,
} from '@admin/components/ui/field-styles';
import { sortSelectOptionsAlphabetically, type SelectOption } from '@admin/lib/sort-select-options';
import { cn } from '@admin/lib/utils';

type FormSelectProps = {
    id?: string;
    label: string;
    value: string;
    options: SelectOption[];
    placeholder?: string;
    error?: string;
    helpText?: string;
    /** When false, options are rendered as provided. Default: true (alphabetical by label). */
    sortAlphabetically?: boolean;
    onChange: (value: string) => void;
    selectProps?: Omit<SelectHTMLAttributes<HTMLSelectElement>, 'value' | 'onChange'>;
};

export function FormSelect({
    id,
    label,
    value,
    options,
    placeholder = 'Select an option',
    error,
    helpText,
    sortAlphabetically = true,
    onChange,
    selectProps,
}: FormSelectProps) {
    const inputId = id ?? label.toLowerCase().replace(/\s+/g, '-');
    const invalidClass = error ? '!border-danger focus:border-danger focus:ring-danger' : '';
    const sortedOptions = sortAlphabetically ? sortSelectOptionsAlphabetically(options) : options;

    return (
        <div className={cn(formFieldClassName, 'mb-4')}>
            <label htmlFor={inputId} className={formLabelClassName}>
                {label}
            </label>
            <select
                id={inputId}
                className={cn('ti-form-select', formControlClassName, invalidClass, selectProps?.className)}
                value={value}
                aria-invalid={Boolean(error)}
                aria-describedby={error ? `${inputId}-error` : helpText ? `${inputId}-help` : undefined}
                onChange={(event) => onChange(event.target.value)}
                {...selectProps}
            >
                <option value="">{placeholder}</option>
                {sortedOptions.map((option) => (
                    <option key={option.value} value={option.value}>
                        {option.label}
                    </option>
                ))}
            </select>
            {error && (
                <span id={`${inputId}-error`} className={formErrorClassName}>
                    {error}
                </span>
            )}
            {helpText && !error && (
                <p id={`${inputId}-help`} className={formHelpClassName}>
                    {helpText}
                </p>
            )}
        </div>
    );
}
