import { Search } from "@kobalte/core/search";
import { useNavigate } from "@solidjs/router";
import { IconRefresh, IconSearch } from "@tabler/icons-solidjs";
import clsx from "clsx";
import Fuse from "fuse.js";
import { createEffect, createResource, createSignal } from "solid-js";
import { getUserImages } from "./network";

type UserImages = Awaited<ReturnType<typeof getUserImages>>;

function App() {
    const [searchResults, setSearchResults] = createSignal<
        UserImages[number]["Text"]
    >([]);

    const [images] = createResource(getUserImages);

    const nav = useNavigate();

    let fuze = new Fuse<NonNullable<UserImages[number]["Text"]>[number]>([], {
        keys: ["ImageText"],
    });

    // TODO: there's probably a better way?
    createEffect(() => {
        const userImages = images();

        if (userImages == null) {
            return;
        }

        const imageText = userImages.flatMap((i) => i.Text ?? []);

        fuze = new Fuse(imageText, {
            keys: ["ImageText"],
            threshold: 0.3,
        });
    });

    const onInputChange = (query: string) => {
        // TODO: we can migrate this searching to Rust, so we don't abuse the main thread.
        // But, it's not too bad as is.
        setSearchResults(fuze.search(query).flatMap((s) => s.item));
    };

    return (
        <main class="container pt-2">
            <Search
                triggerMode="focus"
                options={searchResults() ?? []}
                onInputChange={onInputChange}
                onChange={(item) => {
                    if (item?.ImageID == null) {
                        console.error("ImageID was null");
                        return;
                    }

                    nav(`/image/${item.ImageID}`);
                }}
                optionValue="ID"
                optionLabel="ImageText"
                placeholder="Search for stuff..."
                itemComponent={(props) => (
                    <Search.Item
                        item={props.item}
                        class="col-span-3 row-span-3 bg-red-200 rounded-xl"
                    >
                        <Search.ItemLabel class="mx-[-100px]">
                            {props.item.rawValue.ImageText ?? ""}
                        </Search.ItemLabel>
                    </Search.Item>
                )}
            >
                <div class="px-4">
                    <Search.Control class="inline-flex justify-between w-full rounded-xl text-base leading-none outline-none bg-white border border-gray-200 text-gray-900 transition-colors duration-250 ui-invalid:border-red-500 ui-invalid:text-red-500">
                        <Search.Indicator
                            class="appearance-none inline-flex justify-center items-center w-auto outline-none rounded-l-md px-2.5 text-gray-900 text-base leading-none transition-colors duration-250"
                            loadingComponent={
                                <Search.Icon class="h-5 w-5 grid justify-items-center flex-none">
                                    <IconRefresh
                                        size={20}
                                        class="m-auto animate-spin"
                                    />
                                </Search.Icon>
                            }
                        >
                            <Search.Icon class="h-5 w-5 grid justify-items-center flex-none">
                                <IconSearch class="m-auto size-5 text-gray-600" />
                            </Search.Icon>
                        </Search.Indicator>
                        <Search.Input class="appearance-none inline-flex w-full min-h-[40px] text-base bg-transparent rounded-l-md outline-none placeholder:text-gray-600" />
                    </Search.Control>
                </div>

                <div class="h-[254px] mt-4 overflow-scroll scrollbar-hide">
                    <Search.Listbox class="w-full grid grid-cols-9 grid-rows-9 gap-2 h-[480px] grid-flow-row-dense py-4" />
                    {/* <Search.NoResult class="text-center p-2 pb-6 m-auto text-gray-600">
                        No results found
                    </Search.NoResult> */}
                </div>
            </Search>
            {/* <div class="px-4 mt-4 bg-white rounded-t-2xl">
                <div class="col-span-3 row-span-3 bg-red-200 rounded-xl" />
                <div class="col-span-3 row-span-3 bg-green-200 rounded-xl" />
                <div class="col-span-6 row-span-3 bg-yellow-200 rounded-xl" />
                <div class="col-span-3 row-span-3 bg-green-200 rounded-xl" />
                <div class="col-span-3 row-span-3 bg-blue-200 rounded-xl" />
                <div class="col-span-3 row-span-3 bg-green-200 rounded-xl" />
                <div class="col-span-6 row-span-3 bg-yellow-200 rounded-xl" />

                <For each={images()}>
                    {(image) => (
                        <A href={`/image/${image.ID}`}>
                            <img
                                src={`http://localhost:3040/image/${image.ID}`}
                                class="col-span-3 row-span-3 rounded-xl"
                                alt=""
                            />
                        </A>
                    )}
                </For>
            </div> */}
            <div class="w-full border-t h-10 bg-white px-4 flex items-center border-neutral-100">
                footer
            </div>
        </main>
    );
}

export default App;
