import { cn } from '@/lib/utils';
import { Eye, EyeOff } from 'lucide-react';
import { InputHTMLAttributes, useState } from 'react';

interface FieldProps extends Omit<
    InputHTMLAttributes<HTMLInputElement>,
    'id' | 'name'
> {
    label: string;
    id: string;
    name: string;
    icon: React.ComponentType<{ className?: string }>;
    error?: string;
    labelAction?: React.ReactNode;
}

export default function Field({
    label,
    id,
    name,
    type = 'text',
    icon: Icon,
    error,
    className,
    labelAction,
    ...props
}: FieldProps) {
    const [showPw, setShowPw] = useState(false);
    const isPassword = type === 'password';

    return (
        <div className="space-y-1.5">
            <div className="flex items-center justify-between gap-2">
                <label
                    htmlFor={id}
                    className="text-muted-foreground block text-xs font-semibold tracking-wide uppercase"
                >
                    {label}
                </label>
                {labelAction}
            </div>
            <div className="relative">
                <span className="pointer-events-none absolute inset-y-0 left-3.5 flex items-center">
                    <Icon className="text-muted-foreground/50 h-4 w-4" />
                </span>
                <input
                    {...props}
                    id={id}
                    name={name}
                    type={isPassword && showPw ? 'text' : type}
                    aria-describedby={error ? `${id}-error` : undefined}
                    aria-invalid={error ? true : undefined}
                    className={cn(
                        'w-full rounded-xl border py-3 pl-10 text-sm transition-all outline-none',
                        isPassword ? 'pr-10' : 'pr-4',
                        'bg-secondary/30 text-foreground placeholder:text-muted-foreground/40',
                        'hover:border-primary/30',
                        'focus:border-primary/50 focus:bg-card focus:ring-primary/10 focus:ring-2',
                        error
                            ? 'border-destructive/60 focus:border-destructive focus:ring-destructive/10'
                            : 'border-border',
                        className,
                    )}
                />
                {isPassword && (
                    <button
                        type="button"
                        onClick={() => setShowPw((v) => !v)}
                        aria-label={showPw ? 'Hide password' : 'Show password'}
                        className="text-muted-foreground/50 hover:text-muted-foreground absolute inset-y-0 right-3 flex items-center transition-colors"
                    >
                        {showPw ? (
                            <EyeOff className="h-4 w-4" />
                        ) : (
                            <Eye className="h-4 w-4" />
                        )}
                    </button>
                )}
            </div>
            {error && (
                <p
                    id={`${id}-error`}
                    role="alert"
                    className="text-destructive text-xs"
                >
                    {error}
                </p>
            )}
        </div>
    );
}
