import { EyeIcon, EyeSlashIcon } from '@heroicons/react/24/solid';
import { useState } from 'react';
import type { ChangeEventHandler, FocusEventHandler, ReactNode, Ref } from 'react';
import type { ComponentSize } from './types';
import { Button } from './Button';

type InputKind = 'text' | 'password' | 'email';
type Layout = 'stacked' | 'inline';

type InputFieldProps = {
    label?: string;
    placeholder?: string;
    type: InputKind;
    size?: ComponentSize;
    width?: ComponentSize;
    layout?: Layout;
    value: string;
    name?: string;
    onChange?: ChangeEventHandler<HTMLInputElement>;
    onBlur?: FocusEventHandler<HTMLInputElement>;
    inputRef?: Ref<HTMLInputElement>;
    disabled?: boolean;
    required?: boolean;
    error?: string;
    rightIcon?: ReactNode;
    className?: string;
    inputClassName?: string;
};

export function InputField({
    label,
    placeholder = '',
    type,
    size = 'md',
    width = 'md',
    layout = 'stacked',
    value,
    name,
    onChange,
    onBlur,
    inputRef,
    disabled = false,
    required = false,
    error,
    rightIcon,
    className = '',
    inputClassName = '',
}: Readonly<InputFieldProps>) {
    const [showPassword, setShowPassword] = useState(false);
    const containerWidthClass = {
        sm: 'max-w-xs',
        md: 'max-w-sm',
        lg: 'max-w-md',
        full: 'max-w-none',
    }[width];

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

    const wrapperClass =
        layout === 'inline' ? 'inline-flex w-auto items-center gap-2' : 'block w-full gap-1';
    const labelClass = layout === 'inline' ? 'text-xs ui-body-secondary' : '';
    const isPasswordType = type === 'password';
    const resolvedType: InputKind = isPasswordType && showPassword ? 'text' : type;
    const hasTrailingIcon = isPasswordType || Boolean(rightIcon);
    const inputWrapperClass = layout === 'inline' ? 'relative' : 'relative mt-1';

    return (
        <label
            className={`${wrapperClass} text-sm font-medium ${disabled ? 'ui-label-disabled' : 'ui-label'} ${containerWidthClass} ${className}`.trim()}
        >
            {label ? <span className={labelClass}>{label}</span> : null}
            <div className={inputWrapperClass}>
                <input
                    type={resolvedType}
                    value={value}
                    name={name}
                    onChange={onChange}
                    onBlur={onBlur}
                    ref={inputRef}
                    placeholder={placeholder}
                    disabled={disabled}
                    required={required}
                    className={`field w-full ${hasTrailingIcon ? 'pr-10' : ''} ${inputSizeClass} ${error ? 'border-red-400/70 focus:border-red-400 focus:ring-red-400/30' : ''} ${inputClassName}`.trim()}
                />
                {isPasswordType ? (
                    <Button
                        type="noborder"
                        size="sm"
                        icon={showPassword ? EyeSlashIcon : EyeIcon}
                        onClick={() => setShowPassword((prev) => !prev)}
                        disabled={disabled}
                        className="absolute inset-y-0 right-2 my-auto !h-6 !w-6 !rounded-md !p-0 ui-body-secondary transition hover:opacity-80 disabled:cursor-not-allowed disabled:opacity-60"
                        ariaLabel={showPassword ? 'Hide password' : 'Show password'}
                    />
                ) : rightIcon ? (
                    <span className="pointer-events-none absolute inset-y-0 right-2 inline-flex items-center justify-center px-1">
                        {rightIcon}
                    </span>
                ) : null}
            </div>
            {error ? (
                <span className="mt-1 block text-xs" style={{ color: 'var(--error-text)' }}>
                    {error}
                </span>
            ) : null}
        </label>
    );
}
