import React, {
    forwardRef,
    useEffect,
    useImperativeHandle,
    useRef,
    useState,
} from 'react';

import { XIcon } from 'lucide-react';
import { IoClose } from 'react-icons/io5';

import { rpc } from '@/api/request';
import { GeopointType } from '@/api/types';
import { useAppConfig } from '@/contexts/AppConfigContext';
import { Lang } from '@/lang/Lang';

import { Button } from './ui/button';
import {
    Dialog,
    DialogContent,
    DialogHeader,
} from './ui/dialog';
import { Input } from './ui/input';
import {
    Item,
    ItemContent,
    ItemDescription,
    ItemTitle,
} from './ui/item';
import {
    MobileLink,
    MobileList,
    MobileListItem,
    MobileNavbar,
    MobilePage,
    MobilePopup,
    MobileSearchbar,
} from './ui/mobile';
import { ScrollArea } from './ui/scroll-area';

export const geoSearchCommandRef = React.createRef<GeoSearchCommandRefProps>();

type GeoSearchCommandRefProps = {
    open: (onSelect: (item: GeopointType) => void, initSearch?: string) => void;
    close: () => void;
}

export const GeoSearchCommand = forwardRef<GeoSearchCommandRefProps, {}>((_, ref) => {


    const [open, setOpen] = useState(false);

    const { isMobile } = useAppConfig();
    const [search, setSearch] = useState<string>('');

    const timeout = useRef<any>(null);

    const [byStringData, setByStringData] = useState<GeopointType[]>([]);

    const onSelectRef = useRef<((item: GeopointType) => void) | null>(null);
    useImperativeHandle(ref, () => ({
        open: (onSelect: (item: GeopointType) => void, initSearch?: string) => {
            setSearch(initSearch ?? '');
            setOpen(true);
            onSelectRef.current = onSelect;
        },
        close: () => {
            setOpen(false);
        }
    }));

    const [loading, setLoading] = useState<boolean>(false);
    const handleSearch = (newValue: string) => {
        clearTimeout(timeout.current);

        if (!open) {
            return;
        }
        timeout.current = setTimeout(() => {
            setLoading(true);
            rpc.geocode({
                byString: {
                    string: newValue,
                },
            }).then((res) => {
                if (res?.result && res.result.length > 0) {
                    setByStringData(res.result ?? []);
                }
            })
                .finally(() => {
                    setLoading(false);
                });
        }, 1000);
    };

    useEffect(() => {
        if (search) {
            handleSearch(search);
        }
    }, [search]);

    if (isMobile) {
        return <MobilePopup opened={open} onBackdropClick={() => setOpen(false)} >
            <MobilePage className="flex flex-col">
                <MobileNavbar
                    title={Lang.key('search_address')}
                    right={<MobileLink onClick={() => setOpen(false)}><XIcon /></MobileLink>}

                    subnavbar={
                        <MobileSearchbar
                            value={search}
                            onClear={() => setSearch('')}
                            onChange={(e) => setSearch(e.target.value)}
                            placeholder={Lang.key('search_address_placeholder')}
                        />
                    }

                />

                <MobileList outline dividers>
                    {byStringData.map((item) => (
                        <MobileListItem
                            title={item.name}
                            footer={item?.context ?? ""}
                            onClick={() => {
                                if (onSelectRef.current) {
                                    onSelectRef.current(item);
                                }
                                setOpen(false);
                                setSearch('');
                                setByStringData([]);
                            }}
                        >
                        </MobileListItem>


                    ))}
                </MobileList>
            </MobilePage>
        </MobilePopup>
    }


    return (
        <Dialog



            open={open} onOpenChange={setOpen}>

            <DialogContent showCloseButton={false}>
                <DialogHeader className='flex flex-row gap-0'>
                    <div className='flex-1'>
                        <Input
                            value={search}
                            onChange={(e) => setSearch(e.target.value)}
                            placeholder={Lang.key('search_address_placeholder')}
                        />
                    </div>
                    <Button
                        onClick={() => {
                            setOpen(false);
                            setSearch('');
                            setByStringData([]);
                        }}
                        variant="link" size="icon">
                        <IoClose />
                    </Button>
                </DialogHeader>
                <ScrollArea style={{
                    height: window.innerHeight * 0.5
                }}>
                    {byStringData.map((item) => (
                        <Item
                            onClick={() => {
                                if (onSelectRef.current) {
                                    onSelectRef.current(item);
                                }
                                setOpen(false);
                                setSearch('');
                                setByStringData([]);
                            }}
                            variant="outline">
                            <ItemContent>
                                <ItemTitle>{item.name}</ItemTitle>
                                <ItemDescription>
                                    {item?.context ?? ""}
                                </ItemDescription>
                            </ItemContent>

                        </Item>


                    ))}

                </ScrollArea>


            </DialogContent>

        </Dialog>

    )
});
