import React, { useState, useCallback } from "react";
import { FormFieldProps, useFormGroupName } from "react-compose-form";
import { FormFieldContext, FormControl, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from "@/components/ui/field/select";
import { api } from "@/lib/trpc/client";

export type TagFieldProps = FormFieldProps<{
    label?: string;
    placeholder?: string;
}>;

export const TagField: React.FC<TagFieldProps> = (props) => {
    const {
        label,
        placeholder,
        name,
        value,
        onChange
    } = props;

    const fullName = useFormGroupName(name!);
    const [search, setSearch] = useState<string>();

    const {
        data: selectedTag,
        isLoading
    } = api.tags.get.useQuery({
        id: value
    }, {
        enabled: !!value
    });

    const {
        data: { pages = [] } = {},
        isFetching,
        fetchNextPage,
        hasNextPage
    } = api.tags.paginate.useInfiniteQuery({
        search,
        limit: 10
    }, {
        getNextPageParam: (lastPage) => lastPage.nextCursor,
        placeholderData: (old) => old
    });

    const handleScroll = useCallback(() => {
        if(!hasNextPage || isFetching) {
            return;
        }

        return fetchNextPage();
    }, [hasNextPage, isFetching, fetchNextPage]);

    return (
        <FormFieldContext value={{ name: fullName }}>
            <FormControl>
                <FormItem className="">
                    {label && (
                        <FormLabel>{label}</FormLabel>
                    )}

                    <Select
                      name={fullName}
                      value={value}
                      onValueChange={onChange}>
                        <SelectTrigger className="w-full">
                            <SelectValue clickToRemove placeholder={placeholder} />
                        </SelectTrigger>

                        <SelectContent
                          searchable
                          loading={isLoading || isFetching}
                          search={search}
                          onSearch={setSearch}
                          onScrollReachBottom={handleScroll}>
                            {selectedTag && (
                                <SelectItem value={selectedTag.id}>
                                    {selectedTag.name}
                                </SelectItem>
                            )}

                            {pages.map((page, index) => {
                                return (
                                    <React.Fragment key={index}>
                                        {page.items.map((tag) => {
                                            if(selectedTag && tag.id === selectedTag.id){
                                                return;
                                            }

                                            return (
                                                <SelectItem key={tag.id} value={tag.id}>
                                                    {tag.name}
                                                </SelectItem>
                                            );
                                        })}
                                    </React.Fragment>
                                );
                            })}
                        </SelectContent>
                    </Select>

                    <FormMessage />
                </FormItem>
            </FormControl>
        </FormFieldContext>
    );
};
