"use client";

import { useState, useEffect, useCallback } from "react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";

import { api } from "~/lib/api/client";

import { EditorHeader } from "./EditorHeader";
import { EditorStatusBar } from "./EditorStatusBar";
import { DiagramCanvas } from "./DiagramCanvas";
import { RightPanel } from "./RightPanel";
import { useGraphStore } from "../../stores/useGraphStore";
import { graphToFlow } from "../../lib/graph-converter";

import type { DiagramResponse } from "../DiagramCard";
import type { GraphData, DiagramType } from "../../types/graph";

interface DiagramEditorProps {
  diagram: DiagramResponse;
}

export function DiagramEditor({ diagram }: DiagramEditorProps) {
  const [sidebarOpen, setSidebarOpen] = useState(false);
  const [rightPanelOpen, setRightPanelOpen] = useState(true);
  const queryClient = useQueryClient();
  const initializeFromGraphData = useGraphStore(
    (s) => s.initializeFromGraphData,
  );
  const setLayoutDirection = useGraphStore((s) => s.setLayoutDirection);
  const setEdgeRouting = useGraphStore((s) => s.setEdgeRouting);
  const resetStore = useGraphStore((s) => s.reset);

  // Initialize graph store from diagram data; reset on unmount
  useEffect(() => {
    const raw = diagram.graphData as Record<string, unknown> | null;
    const graphData: GraphData = {
      nodes: Array.isArray(raw?.nodes) ? (raw.nodes as GraphData["nodes"]) : [],
      edges: Array.isArray(raw?.edges) ? (raw.edges as GraphData["edges"]) : [],
      meta: raw?.meta as GraphData["meta"],
    };
    const { nodes, edges } = graphToFlow(graphData);
    initializeFromGraphData(nodes, edges);

    // Initialize layout settings from diagram metadata
    if (graphData.meta?.layoutDirection) {
      setLayoutDirection(graphData.meta.layoutDirection);
    }
    if (graphData.meta?.edgeRouting) {
      setEdgeRouting(graphData.meta.edgeRouting);
    }

    return () => resetStore();
  }, [diagram.id, diagram.graphData, initializeFromGraphData, setLayoutDirection, setEdgeRouting, resetStore]);

  // Keyboard shortcuts
  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if ((e.metaKey || e.ctrlKey) && e.key === "b") {
        e.preventDefault();
        setSidebarOpen((prev) => !prev);
      }
      if ((e.metaKey || e.ctrlKey) && e.key === "j") {
        e.preventDefault();
        setRightPanelOpen((prev) => !prev);
      }
    };
    window.addEventListener("keydown", handler);
    return () => window.removeEventListener("keydown", handler);
  }, []);

  // Rename mutation
  const renameMutation = useMutation({
    mutationFn: async (newTitle: string) => {
      const res = await api.diagrams[":id"].$patch({
        param: { id: diagram.id },
        json: { title: newTitle },
      });
      if (!res.ok) throw new Error("Failed to rename diagram");
      return res.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["diagram", diagram.id] });
      queryClient.invalidateQueries({ queryKey: ["diagrams"] });
      toast.success("Diagram renamed");
    },
    onError: () => {
      toast.error("Failed to rename diagram");
    },
  });

  const handleRename = useCallback(
    (newTitle: string) => {
      if (newTitle.trim() && newTitle.trim() !== diagram.title) {
        renameMutation.mutate(newTitle.trim());
      }
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [diagram.title],
  );

  return (
    <div className="fixed inset-0 z-50 flex flex-col bg-[var(--canvas-bg)]">
      <EditorHeader
        title={diagram.title}
        diagramType={diagram.type as DiagramType}
        onRename={handleRename}
        sidebarOpen={sidebarOpen}
        onToggleSidebar={() => setSidebarOpen((prev) => !prev)}
      />

      <div className="flex flex-1 overflow-hidden">
        {/* Left sidebar */}
        <div
          className={`shrink-0 border-r border-border bg-background transition-[width] duration-200 ease-out ${
            sidebarOpen ? "w-60" : "w-14"
          }`}
        >
          <div className="flex h-full flex-col items-center pt-2">
            {!sidebarOpen && (
              <span className="text-[10px] text-muted-foreground mt-2">
                {"\u2318"}B
              </span>
            )}
          </div>
        </div>

        {/* Canvas */}
        <div className="flex-1 relative">
          <DiagramCanvas />
        </div>

        {/* Right panel */}
        <RightPanel open={rightPanelOpen} />
      </div>

      <EditorStatusBar diagramType={diagram.type as DiagramType} />
    </div>
  );
}
