import { useEffect, useMemo, useRef, useState } from 'react';
import { RiCheckLine, RiCloseLine } from '@remixicon/react';
import {
    InputGroup,
    InputGroupAddon,
    InputGroupButton,
    InputGroupInput,
} from '@/components/ui/input-group';
import { cn } from '@/lib/utils';

export type CustomerSearchOption = {
    id: number;
    name: string;
    email: string;
    phone: string | null;
    office_suite: string | null;
    cell: string | null;
    vehicles: Array<{
        id: number;
        make: string;
        model: string;
        year: number;
        color: string | null;
        size: string;
        is_default: boolean;
        label: string;
    }>;
};

type CustomerSearchSelectProps = {
    customers: CustomerSearchOption[];
    selectedCustomer: CustomerSearchOption | null;
    onSelect: (customer: CustomerSearchOption | null) => void;
    inputId?: string;
    showClear?: boolean;
};

function customerLabel(customer: CustomerSearchOption): string {
    return `${customer.name} · ${customer.email}`;
}

const listItemClassName =
    'group/item relative flex w-full cursor-default rounded-sm py-1.5 pr-8 pl-2 text-left text-sm outline-hidden select-none hover:bg-accent hover:text-accent-foreground';

const customerMetaClassName =
    'truncate text-xs text-popover-foreground/75 transition-colors group-hover/item:text-accent-foreground/90';

const customerPhoneClassName =
    'shrink-0 font-medium tabular-nums text-popover-foreground/90 group-hover/item:text-accent-foreground';

export function CustomerSearchSelect({
    customers,
    selectedCustomer,
    onSelect,
    inputId = 'walkin-customer-search',
    showClear = true,
}: CustomerSearchSelectProps) {
    const containerRef = useRef<HTMLDivElement>(null);
    const [open, setOpen] = useState(false);
    const [query, setQuery] = useState('');

    useEffect(() => {
        if (!open) {
            return;
        }

        const handlePointerDown = (event: PointerEvent) => {
            if (containerRef.current?.contains(event.target as Node)) {
                return;
            }

            setOpen(false);
            setQuery('');
        };

        document.addEventListener('pointerdown', handlePointerDown);

        return () => {
            document.removeEventListener('pointerdown', handlePointerDown);
        };
    }, [open]);

    const filteredCustomers = useMemo(() => {
        const term = query.trim().toLowerCase();

        if (!term) {
            return customers.slice(0, 12);
        }

        return customers
            .filter((customer) => {
                const phoneDigits = customer.phone?.replace(/\D/g, '') ?? '';
                const queryDigits = term.replace(/\D/g, '');

                return (
                    customer.name.toLowerCase().includes(term) ||
                    customer.email.toLowerCase().includes(term) ||
                    (queryDigits !== '' && phoneDigits.includes(queryDigits))
                );
            })
            .slice(0, 12);
    }, [customers, query]);

    const inputValue = open
        ? query
        : selectedCustomer
          ? customerLabel(selectedCustomer)
          : '';

    const canClear =
        showClear &&
        (selectedCustomer !== null || (open && query.length > 0));

    const closePicker = () => {
        setOpen(false);
        setQuery('');
    };

    const selectCustomer = (customer: CustomerSearchOption | null) => {
        onSelect(customer);
        closePicker();
    };

    const handleClear = () => {
        setQuery('');

        if (selectedCustomer) {
            onSelect(null);
        }

        setOpen(false);
    };

    return (
        <div ref={containerRef} className="grid gap-2">
            <InputGroup>
                <InputGroupInput
                    id={inputId}
                    value={inputValue}
                    placeholder="Search by name, email, or phone..."
                    autoComplete="off"
                    onFocus={() => setOpen(true)}
                    onChange={(event) => {
                        setQuery(event.target.value);
                        setOpen(true);
                    }}
                />
                {canClear ? (
                    <InputGroupAddon align="inline-end">
                        <InputGroupButton
                            size="icon-xs"
                            variant="ghost"
                            aria-label="Clear customer search"
                            onMouseDown={(event) => event.preventDefault()}
                            onClick={handleClear}
                        >
                            <RiCloseLine className="pointer-events-none" />
                        </InputGroupButton>
                    </InputGroupAddon>
                ) : null}
            </InputGroup>

            {open ? (
                <div className="overflow-hidden rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10">
                    <div className="max-h-48 scroll-py-1 overflow-y-auto p-1">
                        <button
                            type="button"
                            className={cn(listItemClassName, 'items-center')}
                            onMouseDown={(event) => event.preventDefault()}
                            onClick={() => selectCustomer(null)}
                        >
                            <span className="font-medium">
                                New customer (manual entry)
                            </span>
                            {selectedCustomer === null ? (
                                <span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center">
                                    <RiCheckLine className="size-4" />
                                </span>
                            ) : null}
                        </button>

                        {filteredCustomers.length === 0 ? (
                            <p className="px-2 py-3 text-center text-sm text-muted-foreground">
                                No customers found.
                            </p>
                        ) : (
                            filteredCustomers.map((customer) => {
                                const isSelected =
                                    selectedCustomer?.id === customer.id;

                                return (
                                    <button
                                        key={customer.id}
                                        type="button"
                                        className={cn(
                                            listItemClassName,
                                            'flex-col items-start gap-0.5',
                                        )}
                                        onMouseDown={(event) =>
                                            event.preventDefault()
                                        }
                                        onClick={() =>
                                            selectCustomer(customer)
                                        }
                                    >
                                        <span className="truncate font-medium">
                                            {customer.name}
                                        </span>
                                        <span className="flex min-w-0 items-center gap-1.5">
                                            <span
                                                className={customerMetaClassName}
                                            >
                                                {customer.email}
                                            </span>
                                            {customer.phone ? (
                                                <>
                                                    <span
                                                        aria-hidden
                                                        className="text-popover-foreground/40 group-hover/item:text-accent-foreground/50"
                                                    >
                                                        ·
                                                    </span>
                                                    <span
                                                        className={
                                                            customerPhoneClassName
                                                        }
                                                    >
                                                        {customer.phone}
                                                    </span>
                                                </>
                                            ) : null}
                                        </span>
                                        {isSelected ? (
                                            <span className="pointer-events-none absolute top-2 right-2 flex size-4 items-center justify-center">
                                                <RiCheckLine className="size-4" />
                                            </span>
                                        ) : null}
                                    </button>
                                );
                            })
                        )}
                    </div>
                </div>
            ) : null}
        </div>
    );
}
