import { useState, useMemo, useEffect, useRef, useCallback } from "react";
import { useStdout } from "ink";
import { getModelDisplayName } from "@dexto/llm";
import { isUserMessage } from "@dexto/core";
import { useAgentEvents } from "./useAgentEvents.js";
import { useInputOrchestrator } from "./useInputOrchestrator.js";
import { InputService, MessageService } from "../services/index.js";
import { convertHistoryToUIMessages } from "../utils/messageFormatting.js";
import { useTextBuffer } from "../components/shared/text-buffer.js";
function useCLIState({
  agent,
  initialSessionId,
  startupInfo,
  initialBypassPermissions = false,
  onKeyboardScroll: _onKeyboardScroll
}) {
  const [messages, setMessages] = useState([]);
  const [pendingMessages, setPendingMessages] = useState([]);
  const [dequeuedBuffer, setDequeuedBuffer] = useState([]);
  const [steerMessages, setSteerMessages] = useState([]);
  const [queuedMessages, setQueuedMessages] = useState([]);
  const [todos, setTodos] = useState([]);
  const [ui, setUi] = useState({
    isProcessing: false,
    isCancelling: false,
    isThinking: false,
    isCompacting: false,
    activeOverlay: "none",
    showReasoning: true,
    exitWarningShown: false,
    exitWarningTimestamp: null,
    mcpWizardServerType: null,
    copyModeEnabled: false,
    pendingModelSwitch: null,
    selectedMcpServer: null,
    historySearch: {
      isActive: false,
      query: "",
      matchIndex: 0,
      originalInput: "",
      lastMatch: ""
    },
    promptAddWizard: null,
    autoApproveEdits: false,
    bypassPermissions: initialBypassPermissions,
    todoExpanded: true,
    // Default to expanded to show full todo list
    backgroundTasksRunning: 0,
    backgroundTasksExpanded: false,
    backgroundTasks: [],
    chatgptRateLimitStatus: null,
    insufficientCredits: null,
    planModeActive: false,
    planModeInitialized: false,
    commandOutput: null
  });
  const [input, setInput] = useState({
    value: "",
    history: [],
    historyIndex: -1,
    draftBeforeHistory: "",
    images: [],
    pastedBlocks: [],
    pasteCounter: 0,
    editingQueuedFollowUp: false
  });
  const initialConfig = agent.getCurrentLLMConfig();
  const [session, setSession] = useState({
    id: initialSessionId,
    hasActiveSession: initialSessionId !== null,
    modelName: getModelDisplayName(initialConfig.model, initialConfig.provider)
  });
  const [approval, setApproval] = useState(null);
  const [approvalQueue, setApprovalQueue] = useState([]);
  const inputService = useMemo(() => new InputService(), []);
  const messageService = useMemo(() => new MessageService(), []);
  const { stdout } = useStdout();
  const terminalWidth = stdout?.columns || 80;
  const inputWidth = Math.max(20, terminalWidth - 4);
  const handleBufferChange = useCallback((text) => {
    setInput((prev) => ({ ...prev, value: text }));
  }, []);
  const buffer = useTextBuffer({
    initialText: "",
    viewport: { width: inputWidth, height: 10 },
    onChange: handleBufferChange
  });
  useEffect(() => {
    buffer.setViewport(inputWidth, 10);
  }, [inputWidth, buffer.setViewport]);
  const overlayContainerRef = useRef(null);
  useAgentEvents({
    agent,
    setMessages,
    setPendingMessages,
    setUi,
    setSession,
    setInput,
    setApproval,
    setApprovalQueue,
    setSteerMessages,
    setQueuedMessages,
    currentSessionId: session.id,
    buffer
  });
  const approvalHandler = useCallback((inputStr, key) => {
    return overlayContainerRef.current?.handleInput(inputStr, key) ?? false;
  }, []);
  const overlayHandler = useCallback((inputStr, key) => {
    return overlayContainerRef.current?.handleInput(inputStr, key) ?? false;
  }, []);
  useInputOrchestrator({
    ui,
    approval,
    input,
    session,
    steerMessages,
    buffer,
    setUi,
    setInput,
    setMessages,
    setPendingMessages,
    setSteerMessages,
    agent,
    handlers: {
      approval: approvalHandler,
      overlay: overlayHandler
    }
  });
  useEffect(() => {
    setTodos([]);
  }, [session.id]);
  useEffect(() => {
    if (!initialSessionId || !session.hasActiveSession || messages.length > 0) {
      return;
    }
    let cancelled = false;
    (async () => {
      try {
        const history = await agent.getSessionHistory(initialSessionId);
        if (!history?.length || cancelled) return;
        const historyMessages = convertHistoryToUIMessages(history, initialSessionId);
        setMessages(historyMessages);
        const userInputHistory = history.filter(isUserMessage).map(
          (msg) => msg.content.filter(
            (part) => part.type === "text"
          ).map((part) => part.text).join("\n")
        ).filter((text) => text.trim().length > 0);
        setInput((prev) => ({
          ...prev,
          history: userInputHistory,
          historyIndex: -1,
          editingQueuedFollowUp: false
        }));
      } catch (error) {
        if (cancelled) return;
        setMessages((prev) => [
          ...prev,
          {
            id: `error-${Date.now()}`,
            role: "system",
            content: `Error: ${error instanceof Error ? error.message : String(error)}`,
            timestamp: /* @__PURE__ */ new Date()
          }
        ]);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [agent, initialSessionId, messages.length, session.hasActiveSession]);
  const visibleMessages = messages;
  return {
    messages,
    setMessages,
    pendingMessages,
    setPendingMessages,
    dequeuedBuffer,
    setDequeuedBuffer,
    steerMessages,
    setSteerMessages,
    queuedMessages,
    setQueuedMessages,
    todos,
    setTodos,
    ui,
    setUi,
    input,
    setInput,
    session,
    setSession,
    approval,
    setApproval,
    approvalQueue,
    setApprovalQueue,
    buffer,
    inputService,
    messageService,
    overlayContainerRef,
    visibleMessages,
    agent,
    startupInfo
  };
}
export {
  useCLIState
};
