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 { Lang } from '@/lang/Lang';

import { Button } from '@/components/ui/button';
import { SystemWindowDialog } from '@/components/ui/system-window-dialog';
import { Input } from '@/components/ui/input';
import {
    Item,
    ItemContent,
    ItemDescription,
    ItemTitle,
} from '@/components/ui/item';
import {
    MobileLink,
    MobileList,
    MobileListItem,
    MobileNavbar,
    MobilePage,
    MobilePopup,
    MobileSearchbar,
} from '@/components/ui/mobile';
import { ScrollArea } from '@/components/ui/scroll-area';
import useAppConfigStore, { useAppConfig } from '@/stores/appConfig';

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 } = useAppConfigStore();
    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 (
        <SystemWindowDialog
            open={open}
            onOpenChange={setOpen}
            title={Lang.key('search_address')}
            width={560}
            height="min(70vh, 600px)"
        >
            <div className='flex flex-row gap-2 mb-3'>
                <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"
                    tooltip={Lang.key('close')}
                    aria-label={Lang.key('close')}
                >
                    <IoClose />
                </Button>
            </div>
            <ScrollArea style={{ height: window.innerHeight * 0.5 }}>
                {byStringData.map((item, index) => (
                    <Item
                        key={`${item.name}-${index}`}
                        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>
        </SystemWindowDialog>
    )
});
