import { useCallback, useEffect } from 'react';
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom';
import { PanelRight, MessageSquare, Terminal, Bot } from 'lucide-react';
import type { Chat, WorkspacePane } from '@/api/types';
import { useWorkspacePanes, MAX_PANES } from '@/hooks/useWorkspacePanes';
import { useSessionChats } from '@/hooks/useSessionChats';
import { useViewport } from '@/hooks/useViewport';
import { ChatPane } from '@/components/panes/ChatPane';
import { ChatTabBar } from '@/components/ChatTabBar';
import { SessionLandingPage } from '@/components/SessionLandingPage';
import { SwipeablePaneTab } from '@/components/SwipeablePaneTab';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { cn } from '@/lib/utils';

interface Props {
  sessionId: string;
  projectId: string;
}

export function Workspace({ sessionId, projectId }: Props) {
  const {
    panes,
    activePaneIdx,
    setActivePaneIdx,
    activePaneIdxRef,
    openChatInPane,
    switchTab,
    removeTab,
    closeOtherTabs,
    closeTabsToRight,
    closeAllTabs,
    showLandingPage,
    addSplitPane,
    removePane,
    removeChatFromPanes,
    initializeFirstChatIfEmpty,
    handlePaneDragStart,
    handlePaneDragOver,
    handlePaneDragLeave,
    handlePaneDrop,
    handlePaneDragEnd,
    dragOverIdx,
    draggingIdxRef,
  } = useWorkspacePanes(sessionId);

  // Thin wrapper so useSessionChats can route open_chat_in_active_pane events
  // without knowing about pane indexing.
  const openChatInActivePane = useCallback(
    (chatId: string) => openChatInPane(activePaneIdxRef.current, chatId),
    [openChatInPane, activePaneIdxRef],
  );

  const {
    chats,
    createChat,
    archiveChat,
    unarchiveChat,
    deleteChat,
    renameChat,
    handleLandingSend,
  } = useSessionChats(sessionId, {
    removeChatFromPanes,
    openChatInPane,
    openChatInActivePane,
    initializeFirstChatIfEmpty,
  });

  const { isMobile } = useViewport();
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();
  const location = useLocation();

  // URL -> state (mobile only). Handles deep-link arrival and Back button
  // history pops. On a bare URL (no ?pane), reset to first pane so Back
  // from a ?pane URL returns the user to a sensible default.
  useEffect(() => {
    if (!isMobile || panes.length === 0) return;
    const paneId = searchParams.get('pane');
    if (!paneId) {
      if (activePaneIdx !== 0) setActivePaneIdx(0);
      return;
    }
    const idx = panes.findIndex((p) => p.id === paneId);
    if (idx >= 0 && idx !== activePaneIdx) setActivePaneIdx(idx);
  }, [isMobile, searchParams, panes, activePaneIdx, setActivePaneIdx]);

  // Switch active pane and push URL (mobile only). User-initiated only;
  // never called from URL-sync effect.
  const switchActivePane = useCallback(
    (idx: number) => {
      setActivePaneIdx(idx);
      if (isMobile) {
        const pane = panes[idx];
        if (!pane) return;
        const params = new URLSearchParams(location.search);
        params.set('pane', pane.id);
        navigate(`${location.pathname}?${params.toString()}`);
      }
    },
    [setActivePaneIdx, isMobile, panes, navigate, location.pathname, location.search],
  );

  function chatsForPane(pane: WorkspacePane): Chat[] {
    return pane.chatIds
      .map((id) => chats.find((c) => c.id === id))
      .filter((c): c is Chat => c !== undefined);
  }

  function paneLabel(pane: WorkspacePane): string {
    const activeChatId = pane.chatId;
    if (activeChatId) {
      const chat = chats.find((c) => c.id === activeChatId);
      if (chat) return chat.name ?? 'New chat';
    }
    if (pane.kind === 'chat') return 'Chat';
    if (pane.kind === 'terminal') return 'Terminal';
    if (pane.kind === 'agent') return 'Agent';
    return 'Empty';
  }

  return (
    <div className="flex flex-col h-full min-h-0">
      {!isMobile && (
        <div className="flex items-center gap-2 border-b border-border bg-muted/20 px-3 py-1.5 shrink-0">
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <button
                type="button"
                disabled={panes.length >= MAX_PANES}
                className={cn(
                  'flex items-center gap-1 text-xs px-2 py-1 rounded hover:bg-muted',
                  panes.length >= MAX_PANES && 'opacity-40 cursor-not-allowed hover:bg-transparent'
                )}
              >
                <PanelRight size={14} />
                Split
              </button>
            </DropdownMenuTrigger>
            <DropdownMenuContent>
              <DropdownMenuItem onSelect={() => addSplitPane('chat')}>
                <MessageSquare size={14} /> Chat
              </DropdownMenuItem>
              <DropdownMenuItem onSelect={() => addSplitPane('terminal')}>
                <Terminal size={14} /> Terminal
              </DropdownMenuItem>
              <DropdownMenuItem onSelect={() => addSplitPane('agent')}>
                <Bot size={14} /> Agent
              </DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        </div>
      )}

      {isMobile && panes.length > 1 && (
        <div className="flex items-center gap-1 overflow-x-auto border-b border-border bg-muted/10 px-2 py-1 shrink-0">
          {panes.map((pane, idx) => (
            <SwipeablePaneTab
              key={pane.id}
              label={paneLabel(pane)}
              isActive={idx === activePaneIdx}
              onTap={() => switchActivePane(idx)}
              onClose={() => removePane(idx)}
              canClose={panes.length > 1}
            />
          ))}
        </div>
      )}

      <div
        className={cn('flex-1 min-h-0', isMobile ? 'flex' : 'grid')}
        style={
          isMobile
            ? undefined
            : { gridTemplateColumns: `repeat(${panes.length}, minmax(0, 1fr))` }
        }
      >
        {panes.map((pane, idx) => {
          const visible = !isMobile || idx === activePaneIdx;
          if (!visible) return null;
          return (
          <div
            key={pane.id}
            className={cn(
              'flex flex-col h-full min-h-0 border-r border-border last:border-r-0 relative',
              isMobile ? 'flex-1 w-full' : undefined,
              !isMobile && idx === activePaneIdx && 'ring-1 ring-inset ring-ring/20',
              !isMobile && dragOverIdx === idx && draggingIdxRef.current !== idx &&
                'before:absolute before:inset-y-0 before:left-0 before:w-0.5 before:bg-primary before:z-10'
            )}
            onClick={() => setActivePaneIdx(idx)}
            onDragOver={!isMobile && panes.length > 1 ? handlePaneDragOver(idx) : undefined}
            onDragLeave={!isMobile && panes.length > 1 ? handlePaneDragLeave : undefined}
            onDrop={!isMobile && panes.length > 1 ? handlePaneDrop(idx) : undefined}
          >
            <div
              draggable={!isMobile && panes.length > 1}
              onDragStart={!isMobile && panes.length > 1 ? handlePaneDragStart(idx) : undefined}
              onDragEnd={!isMobile && panes.length > 1 ? handlePaneDragEnd : undefined}
            >
              <ChatTabBar
                pane={pane}
                tabs={chatsForPane(pane)}
                onSwitchTab={(tabIdx) => switchTab(idx, tabIdx)}
                onRemoveTab={(chatId) => removeTab(idx, chatId)}
                onCloseOthers={(chatId) => closeOtherTabs(idx, chatId)}
                onCloseToRight={(chatId) => closeTabsToRight(idx, chatId)}
                onCloseAll={() => closeAllTabs(idx)}
                onNewChat={() => void createChat(idx)}
                onShowHistory={() => showLandingPage(idx)}
                onRename={renameChat}
                onRemovePane={panes.length > 1 ? () => removePane(idx) : undefined}
              />
            </div>

            <div className="flex-1 min-h-0 overflow-hidden">
              {pane.kind === 'chat' && pane.chatId ? (
                <ChatPane sessionId={sessionId} chatId={pane.chatId} projectId={projectId} sessionChats={chats} />
              ) : (
                <SessionLandingPage
                  sessionId={sessionId}
                  projectId={projectId}
                  chats={chats}
                  onOpenChat={(chatId) => openChatInPane(idx, chatId)}
                  onSend={(content) => void handleLandingSend(idx, content)}
                  onReopenChat={async (chatId) => {
                    await unarchiveChat(chatId);
                    openChatInPane(idx, chatId);
                  }}
                  onArchiveChat={archiveChat}
                  onRenameChat={renameChat}
                  onDeleteChat={deleteChat}
                />
              )}
            </div>
          </div>
          );
        })}
      </div>
    </div>
  );
}
