import { useEffect, useRef } from "react";
import AIChat from "@/features/ai/components/chat/ai-chat";
import { AgentLauncher } from "@/features/ai/components/agent-launcher";
import { useChatInitialization } from "@/features/ai/hooks/use-chat-initialization";
import CommandPalette from "@/features/command-palette/components/command-palette";
import { ConnectionDialog } from "@/features/database/components/connection/connection-dialog";
import { initializeDebuggerEventBridge } from "@/features/debugger/services/debug-adapter-events";
import { useBufferStore } from "@/features/editor/stores/buffer-store";
import LinuxFolderPickerDialog from "@/features/file-system/components/linux-folder-picker-dialog";
import { ProjectNameMenu } from "@/features/file-system/components/project-name-menu";
import { getSymlinkInfo } from "@/features/file-system/controllers/platform";
import { useFileSystemStore } from "@/features/file-system/controllers/store";
import { useFileSystemFolderDrop } from "@/features/file-system/hooks/use-file-system-folder-drop";
import { openDroppedWorkspacePaths } from "@/features/file-system/utils/open-dropped-workspace-paths";
import { useGitStore } from "@/features/git/stores/git-store";
import { useOnboardingStore } from "@/features/onboarding/store";
import { SplitViewRoot } from "@/features/panes/components/split-view-root";
import { usePaneKeyboard } from "@/features/panes/hooks/use-pane-keyboard";
import QuickOpen from "@/features/quick-open/components/quick-open";
import { useSettingsStore } from "@/features/settings/store";
import VimCommandBar from "@/features/vim/components/vim-command-bar";
import { useVimKeyboard } from "@/features/vim/hooks/use-vim-keyboard";
import { useVimStore } from "@/features/vim/stores/vim-store";
import { useTerminalStore } from "@/features/terminal/stores/terminal-store";
import { useMenuEventsWrapper } from "@/features/window/hooks/use-menu-events-wrapper";
import { WindowCloseGuard } from "@/features/window/components/window-close-guard";
import { useWorkspaceTabsStore } from "@/features/window/stores/workspace-tabs-store";
import { useUIState } from "@/features/window/stores/ui-state-store";
import { ExtensionDialogs } from "@/extensions/ui/components/extension-dialog";
import { toast } from "@/ui/toast";
import { frontendTrace } from "@/utils/frontend-trace";
import { getInternalTabDragData } from "@/features/tabs/utils/internal-tab-drag";
import { VimSearchBar } from "../../vim/components/vim-search-bar";
import CustomTitleBarWithSettings from "../../window/components/custom-title-bar";
import BottomPane from "./bottom-pane/bottom-pane";
import Footer from "./footer/footer";
import { ResizablePane } from "./resizable-pane";
import { MainSidebar, SidebarActivityRail } from "./sidebar/main-sidebar";

const SIDEBAR_COLLAPSE_THRESHOLD = 48;

export function MainLayout() {
  useChatInitialization();
  usePaneKeyboard();

  const {
    isSidebarVisible,
    setIsSidebarVisible,
    isDatabaseConnectionVisible,
    setIsDatabaseConnectionVisible,
  } = useUIState();
  const { settings, updateSetting } = useSettingsStore();
  const relativeLineNumbers = useVimStore.use.relativeLineNumbers();
  const { setRelativeLineNumbers } = useVimStore.use.actions();
  const handleOpenFolderByPath = useFileSystemStore.use.handleOpenFolderByPath?.();
  const handleFileOpen = useFileSystemStore.use.handleFileOpen?.();
  const rootFolderPath = useFileSystemStore.use.rootFolderPath?.();
  const switchToProject = useFileSystemStore.use.switchToProject?.();
  const setIsSwitchingProject = useFileSystemStore.use.setIsSwitchingProject?.();
  const refreshWorkspaceGitStatus = useGitStore((state) => state.actions.refreshWorkspaceGitStatus);
  const setWorkspaceGitStatus = useGitStore((state) => state.actions.setWorkspaceGitStatus);
  const onboardingOpen = useOnboardingStore((state) => state.isOpen);
  const onboardingContext = useOnboardingStore((state) => state.context);
  const consumeOnboardingOpenRequest = useOnboardingStore((state) => state.consumeOpenRequest);
  const openOnboardingBuffer = useBufferStore.use.actions().openOnboardingBuffer;

  const hasRestoredWorkspace = useRef(false);
  const { isDraggingOver } = useFileSystemFolderDrop(async (paths) => {
    if (!paths || paths.length === 0) return;

    const result = await openDroppedWorkspacePaths(paths, {
      getPathInfo: getSymlinkInfo,
      openFolder: handleOpenFolderByPath,
      openFile: handleFileOpen
        ? async (path) => {
            await handleFileOpen(path, false);
            return true;
          }
        : undefined,
      onError: (path, error) => {
        console.error("Failed to open dropped path:", path, error);
      },
    });

    if (result.openedFolderCount + result.openedFileCount === 0) {
      toast.warning("No supported dropped files or folders could be opened.");
    }
  });

  const sidebarPosition = settings.sidebarPosition;
  const terminalWidthMode = useTerminalStore((state) => state.widthMode);
  const showInlineAiChat = settings.isAIChatVisible;
  const showLeftSidebarTabs = settings.sidebarTabsPosition === "left";

  useEffect(() => {
    void initializeDebuggerEventBridge();
  }, []);

  useEffect(() => {
    if (!onboardingOpen || !onboardingContext) return;

    openOnboardingBuffer(onboardingContext);
    consumeOnboardingOpenRequest();
  }, [consumeOnboardingOpenRequest, onboardingContext, onboardingOpen, openOnboardingBuffer]);

  useEffect(() => {
    if (settings.vimRelativeLineNumbers !== relativeLineNumbers) {
      setRelativeLineNumbers(settings.vimRelativeLineNumbers, {
        persist: false,
      });
    }
  }, [settings.vimRelativeLineNumbers, relativeLineNumbers, setRelativeLineNumbers]);

  // Initialize event listeners
  useMenuEventsWrapper();

  // Initialize vim mode handling
  useVimKeyboard({
    onSave: () => {
      // Dispatch the same save event that existing keyboard shortcuts use
      window.dispatchEvent(new CustomEvent("menu-save"));
    },
    onGoToLine: (line: number) => {
      // Dispatch go to line event
      window.dispatchEvent(
        new CustomEvent("menu-go-to-line", {
          detail: { line },
        }),
      );
    },
  });

  // Restore workspace on app startup
  useEffect(() => {
    if (hasRestoredWorkspace.current) return;

    const resolveRestorableActiveTab = async () => {
      while (true) {
        const activeTab = useWorkspaceTabsStore.getState().getActiveProjectTab();
        if (!activeTab) return null;

        if (activeTab.path.startsWith("remote://")) {
          return activeTab;
        }

        try {
          const info = await getSymlinkInfo(activeTab.path);
          if (info.is_dir) {
            return activeTab;
          }
        } catch (error) {
          console.warn("Persisted workspace no longer exists:", activeTab.path, error);
        }

        useWorkspaceTabsStore.getState().removeProjectTab(activeTab.id);
        toast.warning(`Removed missing project "${activeTab.name}"`);
      }
    };

    const restoreWorkspace = async () => {
      // Get the active project tab from persisted state
      const activeTab = await resolveRestorableActiveTab();
      frontendTrace("info", "workspace-open", "startupRestore:checked", {
        hasActiveTab: !!activeTab,
        tabPath: activeTab?.path ?? null,
      });

      if (activeTab && switchToProject && setIsSwitchingProject) {
        hasRestoredWorkspace.current = true;
        frontendTrace("info", "workspace-open", "startupRestore:start", {
          tabPath: activeTab.path,
        });

        // Set flag BEFORE calling switchToProject to prevent tab bar from hiding
        setIsSwitchingProject(true);

        try {
          await switchToProject(activeTab.id);
          frontendTrace("info", "workspace-open", "startupRestore:end", {
            tabPath: activeTab.path,
          });
        } catch (error) {
          console.error("Failed to restore workspace:", error);
          frontendTrace("error", "workspace-open", "startupRestore:error", {
            tabPath: activeTab.path,
          });
          // Make sure to clear the flag even if restoration fails
          setIsSwitchingProject(false);
        }
      }
    };

    restoreWorkspace();
  }, [switchToProject, setIsSwitchingProject]);

  useEffect(() => {
    if (!rootFolderPath) {
      setWorkspaceGitStatus(null, null);
      return;
    }

    let timeoutId: ReturnType<typeof setTimeout> | null = null;

    const refreshGitState = (event?: Event) => {
      const filePath =
        event instanceof CustomEvent && typeof event.detail?.filePath === "string"
          ? event.detail.filePath
          : null;

      if (filePath && !filePath.startsWith(rootFolderPath)) {
        return;
      }

      if (timeoutId) clearTimeout(timeoutId);
      timeoutId = setTimeout(() => {
        void refreshWorkspaceGitStatus(rootFolderPath);
      }, 300);
    };

    window.addEventListener("git-status-updated", refreshGitState);
    window.addEventListener("git-status-changed", refreshGitState);

    return () => {
      window.removeEventListener("git-status-updated", refreshGitState);
      window.removeEventListener("git-status-changed", refreshGitState);
      if (timeoutId) clearTimeout(timeoutId);
    };
  }, [rootFolderPath, refreshWorkspaceGitStatus, setWorkspaceGitStatus]);

  return (
    <div className="relative flex h-full w-full flex-col overflow-hidden bg-secondary-bg">
      {/* Drag-and-drop overlay */}
      {isDraggingOver && !getInternalTabDragData() && (
        <div className="pointer-events-none absolute inset-0 z-50 flex items-center justify-center bg-primary-bg/90 backdrop-blur-sm">
          <div className="rounded-lg border-2 border-accent border-dashed bg-secondary-bg px-8 py-6">
            <p className="font-medium text-text text-xl">
              Drop folder to open project, or file to open buffer
            </p>
          </div>
        </div>
      )}

      <CustomTitleBarWithSettings />

      <div className="relative z-10 flex flex-1 flex-col overflow-hidden">
        <div className="flex flex-1 flex-row overflow-hidden" style={{ minHeight: 0 }}>
          {/* Left sidebar or AI chat based on settings */}
          {sidebarPosition === "right" ? (
            <div className={!showInlineAiChat ? "hidden" : undefined}>
              <ResizablePane
                position="left"
                widthKey="aiChatWidth"
                collapsible
                collapseThreshold={0}
                onCollapse={() => updateSetting("isAIChatVisible", false)}
              >
                <AIChat mode="chat" />
              </ResizablePane>
            </div>
          ) : (
            sidebarPosition === "left" && (
              <>
                {showLeftSidebarTabs ? <SidebarActivityRail /> : null}
                <ResizablePane
                  position="left"
                  widthKey="sidebarWidth"
                  hidden={!isSidebarVisible}
                  collapsible
                  collapseThreshold={SIDEBAR_COLLAPSE_THRESHOLD}
                  edgePadding={!showLeftSidebarTabs}
                  onCollapse={() => setIsSidebarVisible(false)}
                >
                  <MainSidebar showActivityRail={!showLeftSidebarTabs} />
                </ResizablePane>
              </>
            )
          )}

          {/* Main content area with split view */}
          <div className="flex min-h-0 min-w-0 flex-1 flex-col gap-2 px-2">
            <div className="relative min-h-0 flex-1 overflow-hidden rounded-lg border border-border/70 bg-primary-bg">
              <SplitViewRoot />
            </div>
            {terminalWidthMode === "editor" && <BottomPane />}
          </div>

          {/* Right sidebar or AI chat based on settings */}
          {sidebarPosition === "right" ? (
            <>
              {showLeftSidebarTabs ? <SidebarActivityRail /> : null}
              <ResizablePane
                position="right"
                widthKey="sidebarWidth"
                hidden={!isSidebarVisible}
                collapsible
                collapseThreshold={SIDEBAR_COLLAPSE_THRESHOLD}
                edgePadding={!showLeftSidebarTabs}
                onCollapse={() => setIsSidebarVisible(false)}
              >
                <MainSidebar showActivityRail={!showLeftSidebarTabs} />
              </ResizablePane>
            </>
          ) : (
            <div className={!showInlineAiChat ? "hidden" : undefined}>
              <ResizablePane
                position="right"
                widthKey="aiChatWidth"
                collapsible
                collapseThreshold={0}
                onCollapse={() => updateSetting("isAIChatVisible", false)}
              >
                <AIChat mode="chat" />
              </ResizablePane>
            </div>
          )}
        </div>

        {terminalWidthMode === "full" && (
          <div className="px-2">
            <BottomPane />
          </div>
        )}
      </div>

      <Footer />

      {/* Global modals and overlays */}
      <QuickOpen />
      <VimCommandBar />
      <VimSearchBar />
      <CommandPalette />
      <AgentLauncher />
      <ProjectNameMenu />

      {/* Dialog components */}
      <ConnectionDialog
        isOpen={isDatabaseConnectionVisible}
        onClose={() => setIsDatabaseConnectionVisible(false)}
      />
      <LinuxFolderPickerDialog />
      <WindowCloseGuard />
      <ExtensionDialogs />
    </div>
  );
}
