import { cn } from '@/lib/cn';
import { Check, Minus } from 'lucide-react';
import { forwardRef, type InputHTMLAttributes } from 'react';

type CheckboxProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> & {
    /** Classes for the wrapper (layout slot: `mt-0.5`, `mt-1`, …). The box
     *  itself stays 16px — size via `className` only if a surface truly
     *  needs it. */
    wrapperClassName?: string;
};

/**
 * Styled checkbox — replaces the browser-native `accent-accent` box with a
 * token-driven one (same border / radius / focus ring as `Input`). Checked
 * and indeterminate states fill with `accent` + draw a `Check` / `Minus`
 * glyph via peer variants, so `el.indeterminate = …` ref wiring keeps
 * working unchanged. Drop-in for raw `<input type="checkbox">`.
 */
export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
    ({ className, wrapperClassName, ...props }, ref) => (
        // h-fit pins the wrapper to the box's own height so the glyph
        // overlays stay centered when a grid/flex parent would stretch it.
        <span className={cn('relative inline-flex h-fit shrink-0', wrapperClassName)}>
            <input
                ref={ref}
                type="checkbox"
                className={cn(
                    'peer h-4 w-4 cursor-pointer appearance-none rounded border border-border bg-card shadow-sm transition-colors',
                    'checked:border-accent checked:bg-accent indeterminate:border-accent indeterminate:bg-accent',
                    'focus:outline-none focus-visible:ring-2 focus-visible:ring-accent/30',
                    'disabled:cursor-not-allowed disabled:bg-muted disabled:checked:border-accent/50 disabled:checked:bg-accent/50 disabled:indeterminate:border-accent/50 disabled:indeterminate:bg-accent/50',
                    className,
                )}
                {...props}
            />
            <Check
                className="animate-glyph-in pointer-events-none absolute inset-0 m-auto hidden h-3 w-3 text-accent-foreground peer-checked:block peer-indeterminate:!hidden"
                strokeWidth={3}
                aria-hidden="true"
            />
            <Minus
                className="animate-glyph-in pointer-events-none absolute inset-0 m-auto hidden h-3 w-3 text-accent-foreground peer-indeterminate:block"
                strokeWidth={3}
                aria-hidden="true"
            />
        </span>
    ),
);

Checkbox.displayName = 'Checkbox';
