import { useCallback, useMemo, useState } from "react";
import { Link, createFileRoute } from "@tanstack/react-router";
import { useSuspenseQuery } from "@tanstack/react-query";
import { ArrowLeft, Moon, Plus, Sun } from "lucide-react";
import type { FlutterEvent, FlutterTimelineState } from "@/lib/flutter-bridge";
import { timelineQueryOptions } from "@/functions/get-timeline";
import { FlutterView } from "@/components/flutter-view";
import { Button } from "@/components/ui/button";
import UserMenu from "@/components/user-menu";
import ItemFormDrawer from "@/components/item-form-drawer";
import { useEntryMovedMutation } from "@/hooks/use-entry-moved-mutation";
import { useEntryResizedMutation } from "@/hooks/use-entry-resized-mutation";
import { useTheme } from "@/lib/theme";

export const Route = createFileRoute("/timeline/$timelineId")({
  loader: async ({ context, params }) => {
    await context.queryClient.ensureQueryData(
      timelineQueryOptions(params.timelineId)
    );
  },
  component: RouteComponent,
});

function RouteComponent() {
  const { timelineId } = Route.useParams();
  const { data: timeline } = useSuspenseQuery(timelineQueryOptions(timelineId));
  const [selectedItemId, setSelectedItemId] = useState<string | null>(null);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [flutterHeight, setFlutterHeight] = useState<number | undefined>();
  const entryMoved = useEntryMovedMutation(timelineId);
  const entryResized = useEntryResizedMutation(timelineId);
  const { theme, toggleTheme } = useTheme();

  const editItem = selectedItemId
    ? (timeline.items[selectedItemId] ?? null)
    : null;

  const flutterState: FlutterTimelineState = useMemo(
    () => ({
      timeline: { id: timeline.id, title: timeline.title },
      groups: timeline.groups,
      items: Object.fromEntries(
        Object.entries(timeline.items).map(([id, item]) => [
          id,
          {
            id: item.id,
            groupId: item.groupId,
            title: item.title,
            description: item.description,
            start: item.start.toISOString(),
            end: item.end?.toISOString() ?? null,
            lane: item.lane,
          },
        ])
      ),
      groupOrder: timeline.groupOrder,
      selectedItemId,
      darkMode: theme === "dark",
    }),
    [timeline, selectedItemId, theme]
  );

  const handleEvent = useCallback(
    (event: FlutterEvent) => {
      switch (event.type) {
        case "content_height":
          setFlutterHeight(event.payload.height);
          break;
        case "item_selected":
          setSelectedItemId(event.payload.itemId);
          setDrawerOpen(true);
          break;
        case "item_deselected":
          setSelectedItemId(null);
          setDrawerOpen(false);
          break;
        case "entry_moved":
          entryMoved.mutate(event.payload);
          break;
        case "entry_resized":
          entryResized.mutate(event.payload);
          break;
      }
    },
    [entryMoved, entryResized]
  );

  const handleDrawerOpenChange = useCallback((open: boolean) => {
    setDrawerOpen(open);
    if (!open) {
      setSelectedItemId(null);
    }
  }, []);

  const handleAddItem = useCallback(() => {
    setSelectedItemId(null);
    setDrawerOpen(true);
  }, []);

  return (
    <div className="flex flex-col">
      <div className="flex flex-row items-center justify-between px-2 py-1">
        <div className="flex items-center gap-2">
          <Link
            to="/timelines"
            className="text-muted-foreground hover:text-foreground inline-flex size-8 items-center justify-center rounded-md transition-colors"
            aria-label="Back to timelines"
          >
            <ArrowLeft className="size-4" />
          </Link>
          <h1 className="text-lg font-serif font-bold">{timeline.title}</h1>
        </div>
        <div className="flex items-center gap-2">
          <Button variant="outline" size="sm" onClick={handleAddItem}>
            <Plus className="size-4" />
            Add Item
          </Button>
          <button
            type="button"
            onClick={toggleTheme}
            className="text-muted-foreground hover:text-foreground inline-flex size-8 items-center justify-center rounded-md transition-colors"
            aria-label={
              theme === "dark" ? "Switch to light mode" : "Switch to dark mode"
            }
          >
            {theme === "dark" ? (
              <Sun className="size-4" />
            ) : (
              <Moon className="size-4" />
            )}
          </button>
          <UserMenu />
        </div>
      </div>
      <hr />

      <FlutterView
        state={flutterState}
        onEvent={handleEvent}
        className="overflow-hidden"
        height={flutterHeight}
      />

      <ItemFormDrawer
        open={drawerOpen}
        onOpenChange={handleDrawerOpenChange}
        timelineId={timelineId}
        groups={timeline.groups}
        groupOrder={timeline.groupOrder}
        editItem={editItem}
      />
    </div>
  );
}
