import React, { useCallback, useEffect, useRef } from 'react';
import { Sidebar } from './components/Sidebar/Sidebar';
import { ConfirmDialog } from './components/Settings/ConfirmDialog';
import { TabBar } from './components/TabBar/TabBar';
import { Terminal } from './components/Terminal/Terminal';
import { useAppShortcuts } from './hooks/useAppShortcuts';
import { usePortfolioWorkflow } from './hooks/usePortfolioWorkflow';
import { useResearchCaptureFlow } from './hooks/useResearchCaptureFlow';
import type { ResearchComposerState } from './hooks/useResearchComposer';
import { useResearchWorkspaces } from './hooks/useResearchWorkspaces';
import { useTabs } from './hooks/useTabs';
import { createEntry } from './hooks/useTerminal';
import { useTerminalOrchestrator } from './hooks/useTerminalOrchestrator';
import { useTickerHistory } from './hooks/useTickerHistory';
import { agentSettingsBridge } from './lib/agentSettingsBridge';
import { terminalBridge } from './lib/terminalBridge';
import { AgentConfigStatus } from './types/agentSettings';
import {
  NoteCaptureResult,
  ResearchNavigationIntent,
} from './types/research';
import './App.css';

type AppView = 'terminal' | 'research' | 'settings';

const ResearchMode = React.lazy(() =>
  import('./components/Research/ResearchMode').then((module) => ({
    default: module.ResearchMode,
  })),
);

const SettingsPage = React.lazy(() =>
  import('./components/Settings/SettingsPage').then((module) => ({
    default: module.SettingsPage,
  })),
);

function App() {
  const tabs = useTabs();
  const tickerHistory = useTickerHistory();
  const portfolioWorkflow = usePortfolioWorkflow();
  const [activeView, setActiveView] = React.useState<AppView>('terminal');
  const [researchIntent, setResearchIntent] = React.useState<ResearchNavigationIntent | null>(null);
  const [agentStatus, setAgentStatus] = React.useState<AgentConfigStatus | null>(null);
  const [sidebarOpen, setSidebarOpen] = React.useState(true);
  const outputRef = useRef<HTMLDivElement | null>(null);
  const hasAutoLoadedPortfolioRef = useRef(false);
  const activePortfolioWorkflow = portfolioWorkflow.readWorkflow(tabs.activeWorkspaceId);
  const researchWorkspaces = useResearchWorkspaces();
  const { captureNote: captureResearchNote } = useResearchCaptureFlow({
    ensureWorkspace: researchWorkspaces.ensureWorkspace,
  });

  const refreshAgentStatus = useCallback(async () => {
    const status = await agentSettingsBridge.getStatus();
    setAgentStatus(status);
    return status;
  }, []);

  const handleAgentStatusChange = useCallback((status: AgentConfigStatus) => {
    setAgentStatus(status);
  }, []);

  const handleOpenSettings = useCallback(async () => {
    try {
      await refreshAgentStatus();
    } finally {
      portfolioWorkflow.exitPortfolioMode(tabs.activeWorkspaceId);
      setActiveView('settings');
    }
  }, [portfolioWorkflow, refreshAgentStatus, tabs.activeWorkspaceId]);

  const handleReturnToTerminal = useCallback(() => {
    setActiveView('terminal');
  }, []);

  const handleEnsureResearchWorkspace = useCallback(
    (request: { ticker?: string; workspaceId?: string | null }) =>
      researchWorkspaces.ensureWorkspace(request),
    [researchWorkspaces],
  );

  const handleCaptureResearchNote = useCallback(
    async (args: {
      draft: ResearchComposerState;
      fallbackTicker?: string;
      explicitWorkspaceId?: string | null;
      autoCreateFromTicker?: boolean;
    }): Promise<NoteCaptureResult> => {
      const result = await captureResearchNote(args);
      researchWorkspaces.selectWorkspace(result.note.workspaceId);
      return result;
    },
    [captureResearchNote, researchWorkspaces],
  );

  const handleOpenResearch = useCallback(
    async (intent: ResearchNavigationIntent = {}) => {
      const workspace = await researchWorkspaces.ensureWorkspaceForIntent(intent);
      if (workspace) {
        researchWorkspaces.selectWorkspace(workspace.id);
      }
      setResearchIntent(intent);
      setActiveView('research');
    },
    [researchWorkspaces],
  );

  const {
    commandInputRef,
    clearWorkspaceSession,
    handleClearPortfolioAction,
    handleCommand,
    handleStartPortfolioAction,
    handleUpdatePortfolioDraft,
    isProcessing,
    pendingAgentApproval,
    resetCommandIndex,
    resolvePendingAgentApproval,
    runCommand,
  } = useTerminalOrchestrator({
    tabs,
    tickerHistory,
    portfolioWorkflow,
    setActiveView,
  });

  const clearTerminal = useCallback(() => {
    setActiveView('terminal');
    clearWorkspaceSession(tabs.activeWorkspaceId);
  }, [clearWorkspaceSession, tabs.activeWorkspaceId]);

  const handleCreateWorkspace = useCallback(() => {
    setActiveView('terminal');
    tabs.createWorkspace();
  }, [tabs]);

  const appendTerminalSystemMessage = useCallback(
    (message: string) => {
      tabs.appendWorkspaceEntry(
        tabs.activeWorkspaceId,
        createEntry({
          type: 'system',
          content: message,
        }),
      );
    },
    [tabs],
  );

  useAppShortcuts({
    activeView,
    activeWorkspaceId: tabs.activeWorkspaceId,
    commandInputRef,
    isProcessing,
    onClearTerminal: clearTerminal,
    onCloseWorkspace: tabs.closeWorkspace,
    onCreateWorkspace: handleCreateWorkspace,
    onOpenResearch: () => {
      void handleOpenResearch();
    },
    onOpenSettings: () => {
      void handleOpenSettings();
    },
    onToggleSidebar: () => setSidebarOpen((prev) => !prev),
  });

  useEffect(() => {
    let active = true;

    void refreshAgentStatus().catch(() => {
      if (active) {
        setAgentStatus(null);
      }
    });

    return () => {
      active = false;
    };
  }, [refreshAgentStatus]);

  useEffect(() => {
    return () => {
      void terminalBridge.dispose();
    };
  }, []);

  useEffect(() => {
    if (hasAutoLoadedPortfolioRef.current || activeView !== 'terminal' || isProcessing) {
      return;
    }

    hasAutoLoadedPortfolioRef.current = true;
    void handleCommand('/portfolio');
  }, [activeView, handleCommand, isProcessing]);

  const tabBarTabs = tabs.workspaces.map((workspace) => ({
    id: workspace.id,
    name: workspace.name,
    isActive: workspace.id === tabs.activeWorkspaceId,
  }));

  return (
    <div className="flex h-screen bg-[#0a0a0a]">
      <Sidebar
        activeView={activeView}
        isOpen={sidebarOpen}
        onOpenResearch={() => {
          void handleOpenResearch();
        }}
        onOpenTerminal={() => setActiveView('terminal')}
        onOpenSettings={() => {
          void handleOpenSettings();
        }}
        onToggle={() => setSidebarOpen((prev) => !prev)}
        onCommand={handleCommand}
        portfolio={activePortfolioWorkflow.portfolioSnapshot}
        tickerHistory={tickerHistory.history}
        isTickerHistoryLoaded={tickerHistory.isLoaded}
      />

      <div
        className={`flex-1 ${sidebarOpen ? 'ml-0' : ''} transition-all flex min-h-0 min-w-0 flex-col`}
      >
        {activeView === 'terminal' ? (
          <TabBar
            tabs={tabBarTabs}
            onTabClick={(id) => {
              setActiveView('terminal');
              tabs.setActiveWorkspace(id);
            }}
            onTabClose={(id) => tabs.closeWorkspace(id)}
            onNewTab={handleCreateWorkspace}
            onTabRename={(id, name) => tabs.renameWorkspace(id, name)}
          />
        ) : null}

        {activeView === 'settings' ? (
          <React.Suspense fallback={<div className="flex-1 p-6 text-sm text-[#8ea6c0]">Loading settings...</div>}>
            <SettingsPage
              status={agentStatus}
              onRefreshStatus={refreshAgentStatus}
              onStatusChange={handleAgentStatusChange}
              onBackToTerminal={handleReturnToTerminal}
            />
          </React.Suspense>
        ) : activeView === 'research' ? (
          <React.Suspense fallback={<div className="flex-1 p-6 text-sm text-[#8ea6c0]">Loading research workspace...</div>}>
            <ResearchMode
              workspaces={researchWorkspaces.workspaces}
              activeWorkspaceId={researchWorkspaces.activeWorkspaceId}
              navigationIntent={researchIntent}
              onSelectWorkspace={researchWorkspaces.selectWorkspace}
              onEnsureWorkspace={handleEnsureResearchWorkspace}
              onCaptureResearchNote={handleCaptureResearchNote}
              onConsumeNavigationIntent={() => setResearchIntent(null)}
            />
          </React.Suspense>
        ) : (
          <Terminal
            history={tabs.activeWorkspace?.history ?? []}
            isProcessing={isProcessing}
            outputRef={outputRef}
            inputRef={commandInputRef}
            onSubmit={handleCommand}
            onRunCommand={runCommand}
            onStartPortfolioAction={handleStartPortfolioAction}
            onUpdatePortfolioDraft={handleUpdatePortfolioDraft}
            onClearPortfolioAction={handleClearPortfolioAction}
            resetCommandIndex={resetCommandIndex}
            portfolioWorkflow={activePortfolioWorkflow}
            researchWorkspaces={researchWorkspaces.workspaces}
            activeResearchWorkspaceId={researchWorkspaces.activeWorkspaceId}
            onSelectResearchWorkspace={researchWorkspaces.selectWorkspace}
            onEnsureResearchWorkspace={handleEnsureResearchWorkspace}
            onCaptureResearchNote={handleCaptureResearchNote}
            onOpenResearchContext={(intent) => {
              void handleOpenResearch(intent);
            }}
            onAppendSystemMessage={appendTerminalSystemMessage}
          />
        )}
      </div>

      <ConfirmDialog
        isOpen={pendingAgentApproval !== null}
        title={pendingAgentApproval?.title ?? 'Approve command'}
        message={pendingAgentApproval?.message ?? ''}
        confirmLabel="Approve"
        cancelLabel="Deny"
        variant="warning"
        onConfirm={() => resolvePendingAgentApproval(true)}
        onCancel={() => resolvePendingAgentApproval(false)}
      />
    </div>
  );
}

export default App;
