import { Button } from '@/components/ui/button';
import {
    Command,
    CommandEmpty,
    CommandGroup,
    CommandInput,
    CommandItem,
    CommandList,
} from '@/components/ui/command';
import {
    Popover,
    PopoverContent,
    PopoverTrigger,
} from '@/components/ui/popover';
import membersRoutes from '@/routes/members/index';
import { Check, ChevronsUpDown, Loader2 } from 'lucide-react';
import { useCallback, useEffect, useState } from 'react';
import { toast } from 'sonner';

export interface MemberSearchResult {
    id: number;
    id_number: string | null;
    branch_id: number;
    name: string;
    phone: string | null;
    branch: string | null;
    collectibility_score?: number;
    active_financings_count: number;
}

interface MemberSelectorProps {
    value: number | null;
    onChange: (
        memberId: number | null,
        memberData?: MemberSearchResult,
    ) => void;
    disabled?: boolean;
    error?: string;
}

export function MemberSelector({
    value,
    onChange,
    disabled = false,
    error,
}: MemberSelectorProps) {
    const [open, setOpen] = useState(false);
    const [searchQuery, setSearchQuery] = useState('');
    const [debouncedQuery, setDebouncedQuery] = useState('');
    const [members, setMembers] = useState<MemberSearchResult[]>([]);
    const [loading, setLoading] = useState(false);

    // Debounce search query (300ms delay)
    useEffect(() => {
        const timer = setTimeout(() => {
            setDebouncedQuery(searchQuery);
        }, 300);

        return () => clearTimeout(timer);
    }, [searchQuery]);

    // Fetch members when debounced query changes
    useEffect(() => {
        const searchMembers = async () => {
            if (debouncedQuery.length < 2) {
                setMembers([]);
                return;
            }

            setLoading(true);
            try {
                const response = await fetch(
                    membersRoutes.search().url +
                        `?search=${encodeURIComponent(debouncedQuery)}&limit=20`,
                );

                if (!response.ok) {
                    throw new Error('Failed to search members');
                }

                const data = await response.json();

                setMembers(data);
            } catch (error) {
                console.error('Search error:', error);
                toast.error('Gagal mencari anggota. Silakan coba lagi.');
                setMembers([]);
            } finally {
                setLoading(false);
            }
        };

        searchMembers();
    }, [debouncedQuery]);

    const selectedMember =
        members.find((m) => m.id === value) ||
        (value
            ? {
                  id: value,
                  name: 'Loading...',
                  id_number: null,
                  phone: null,
                  branch_id: null,
                  branch: null,
                  active_financings_count: 0,
              }
            : null);

    const handleSelect = useCallback(
        (memberId: number) => {
            const member = members.find((m) => m.id === memberId);
            onChange(memberId, member);
            setOpen(false);
            setSearchQuery('');
            setMembers([]);
        },
        [onChange, members],
    );

    const handleClear = useCallback(() => {
        onChange(null);
        setSearchQuery('');
        setMembers([]);
    }, [onChange]);

    return (
        <div className="space-y-2">
            <Popover open={open} onOpenChange={setOpen}>
                <PopoverTrigger asChild>
                    <Button
                        variant="outline"
                        role="combobox"
                        aria-expanded={open}
                        disabled={disabled}
                        className="w-full justify-between"
                    >
                        {value ? (
                            <span className="truncate">
                                {selectedMember?.name} (
                                {selectedMember?.id_number})
                            </span>
                        ) : (
                            <span>Cari anggota...</span>
                        )}
                        {value && (
                            <button
                                onClick={(e) => {
                                    e.stopPropagation();
                                    handleClear();
                                }}
                                className="ml-2 hover:text-destructive"
                                type="button"
                            >
                                ×
                            </button>
                        )}
                        <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                    </Button>
                </PopoverTrigger>
                <PopoverContent className="w-[400px] p-0">
                    <Command>
                        <CommandInput
                            placeholder="Cari nama atau NIK..."
                            value={searchQuery}
                            onValueChange={setSearchQuery}
                            className="h-9"
                        />
                        <CommandList>
                            <CommandEmpty>
                                {loading ? (
                                    <div className="flex items-center justify-center py-4">
                                        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                                        Mencari...
                                    </div>
                                ) : searchQuery.length < 2 ? (
                                    'Ketik minimal 2 karakter untuk mencari'
                                ) : (
                                    'Tidak ada anggota ditemukan'
                                )}
                            </CommandEmpty>
                            <CommandGroup>
                                {members.map((member) => (
                                    <CommandItem
                                        key={member.id}
                                        value={member.name}
                                        onSelect={() => handleSelect(member.id)}
                                    >
                                        <div className="flex flex-1 flex-col">
                                            <span className="font-medium">
                                                {member.name}
                                            </span>
                                            <span className="text-sm text-muted-foreground">
                                                {member.id_number || 'No NIK'} •{' '}
                                                {member.branch || 'No Cabang'}
                                            </span>
                                        </div>
                                        {member.active_financings_count > 0 && (
                                            <span className="rounded bg-amber-50 px-2 py-1 text-xs text-amber-600">
                                                {member.active_financings_count}{' '}
                                                Aktif
                                            </span>
                                        )}
                                        <Check
                                            className={`ml-2 h-4 w-4 ${
                                                value === member.id
                                                    ? 'opacity-100'
                                                    : 'opacity-0'
                                            }`}
                                        />
                                    </CommandItem>
                                ))}
                            </CommandGroup>
                        </CommandList>
                    </Command>
                </PopoverContent>
            </Popover>
            {error && <p className="text-sm text-destructive">{error}</p>}
        </div>
    );
}
