import { autoUpdate, offset, useFloating } from "@floating-ui/react-dom"
import { createFileRoute, useNavigate } from "@tanstack/react-router"
import { useCallback } from "react"
import { ActionBar } from "~/app/bookmarks/-action-bar"
import { useLogOut } from "~/auth"
import { useCollections } from "~/collection/api"
import { Button } from "~/components/button"
import { LoadingSpinner } from "~/components/loading-spinner"
import { useMnemonics } from "~/hooks/use-mnemonics"
import { CollectionList } from "./-collection-list"
import { AddCollectionDialog } from "./-dialogs/add-collection-dialog"
import { DeleteCollectionDialog } from "./-dialogs/delete-collection-dialog"
import { DialogKind, WindowKind, useCollectionPageStore } from "./-store"
import { SideNav } from "~/app/-side-nav"

export const Route = createFileRoute("/collections/")({
	component: CollectionsPage,
})

function ActiveDialog() {
	const dialog = useCollectionPageStore((state) => state.dialog)

	switch (dialog.kind) {
		case DialogKind.AddCollection:
			return <AddCollectionDialog />
		case DialogKind.DeleteCollection:
			return <DeleteCollectionDialog collection={dialog.collection} />
		default:
			return null
	}
}

function CollectionsPage() {
	return (
		<main className="w-full flex justify-center">
			<CollectionsPane />
			<CollectionsActionBar className="fixed left-0 right-0 bottom-0" />
			<ActiveDialog />
		</main>
	)
}

function CollectionsPane() {
	return (
		<div className="flex flex-col py-16 container max-w-3xl md:flex-row lg:py-32">
			<_SideNav />
			<div className="flex-1">
				<CollectionsContainer />
			</div>
		</div>
	)
}

function _SideNav() {
	const hasDialog = useCollectionPageStore((state) => state.dialog.kind !== DialogKind.None)
	return <SideNav enableMnemonics={!hasDialog} />
}

function CollectionsContainer() {
	const { data: collections, status } = useCollections()
	const handleCollectionListAction = useCollectionPageStore((state) => state.handleCollectionListAction)

	switch (status) {
		case "success":
			return collections.length === 0 ? (
				<p>You have not created any collections!</p>
			) : (
				<CollectionList collections={collections} onItemAction={handleCollectionListAction} />
			)

		case "pending":
			return (
				<p>
					Loading <LoadingSpinner />
				</p>
			)

		case "error":
			return <p>Error loading collections</p>
	}
}

function CollectionsActionBar({ className }: { className?: string }) {
	const activeWindow = useCollectionPageStore((state) => state.activeWindow)
	const { refs, floatingStyles } = useFloating({
		placement: "top",
		whileElementsMounted: autoUpdate,
		middleware: [offset(8)],
	})

	return (
		<>
			<ActionBar ref={refs.setReference} className={className}>
				<ActionButtons />
			</ActionBar>
			{activeWindow === WindowKind.AppMenu && <AppMenuWindow ref={refs.setFloating} style={floatingStyles} />}
		</>
	)
}

function ActionButtons() {
	const setActiveWindow = useCollectionPageStore((state) => state.setActiveWindow)
	const activeWindow = useCollectionPageStore((state) => state.activeWindow)
	const setActiveDialog = useCollectionPageStore((state) => state.setActiveDialog)

	useMnemonics(
		{
			a: addCollection,
		},
		{ ignore: useCallback(() => useCollectionPageStore.getState().dialog.kind !== DialogKind.None, []) },
	)

	function addCollection() {
		setActiveDialog({ kind: DialogKind.AddCollection })
	}

	function toggleAppMenu() {
		setActiveWindow(activeWindow === WindowKind.AppMenu ? WindowKind.None : WindowKind.AppMenu)
	}

	return (
		<div className="flex flex-row justify-center space-x-4">
			<Button onClick={addCollection}>
				<span className="underline">A</span>DD COLLECTION
			</Button>
			<Button onClick={toggleAppMenu}>⋯</Button>
		</div>
	)
}

function AppMenuWindow({ ref, style }: { ref: React.Ref<HTMLDivElement>; style: React.CSSProperties }) {
	return (
		<div ref={ref} style={style} className="border w-full md:w-100">
			<p className="bg-stone-900 dark:bg-stone-200 text-stone-300 dark:text-stone-800 text-center">MENU</p>
			<div className="p-4">
				<ul className="space-y-2">
					<li>
						<LogOutButton />
					</li>
				</ul>
			</div>
		</div>
	)
}

function LogOutButton() {
	const logOutMutation = useLogOut()
	const navigate = useNavigate()

	function logOut() {
		logOutMutation.mutate()
		navigate({ to: "/", replace: true })
	}

	return (
		<Button disabled={logOutMutation.isPending} onClick={logOut}>
			LOG OUT
		</Button>
	)
}
