"use client";
import { useState, useCallback, useEffect, useMemo, useRef } from "react";
import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
import { apiFetch } from "@open-mercato/ui/backend/utils/api";
import { AI_CHAT_SHORTCUT } from "../constants.js";
import { filterTools } from "../utils/toolMatcher.js";
import { useMcpTools } from "./useMcpTools.js";
import { useRecentActions } from "./useRecentActions.js";
import { useRecentTools } from "./useRecentTools.js";
import { useAiAssistantVisibility } from "./useAiAssistantVisibility.js";
function generateId() {
  return Math.random().toString(36).substring(2, 15);
}
const SAFE_TOOL_PATTERNS = [
  /^search_/,
  // search_query, search_schema, search_get, search_aggregate, search_status
  /^get_/,
  // get_ operations are read-only
  /^list_/,
  // list_ operations are read-only
  /^view_/,
  // view_ operations are read-only
  /^context_/,
  // context_whoami etc.
  /_get$/,
  // tools ending with _get
  /_list$/,
  // tools ending with _list
  /_status$/,
  // tools ending with _status
  /_schema$/
  // tools ending with _schema
];
const DANGEROUS_TOOL_PATTERNS = [
  /^delete_/,
  /^remove_/,
  /_delete$/,
  /_remove$/,
  /^reindex_/,
  /_reindex$/
];
function isToolSafeToAutoExecute(toolName) {
  if (DANGEROUS_TOOL_PATTERNS.some((p) => p.test(toolName))) {
    return false;
  }
  return SAFE_TOOL_PATTERNS.some((p) => p.test(toolName));
}
function getToolPrompt(tool) {
  const schema = tool.inputSchema;
  if (!schema || typeof schema !== "object") {
    return "What would you like to do?";
  }
  const properties = schema.properties;
  if (!properties || Object.keys(properties).length === 0) {
    return "This tool has no parameters. Ready to execute?";
  }
  const paramNames = Object.keys(properties).slice(0, 3);
  return `Please provide the following: ${paramNames.join(", ")}.`;
}
function useCommandPalette(options) {
  const { pageContext, selectedEntities = [], disableKeyboardShortcut = false } = options;
  const { isEnabled: isAiAssistantEnabled } = useAiAssistantVisibility();
  const [state, setState] = useState({
    isOpen: false,
    phase: "idle",
    inputValue: "",
    selectedIndex: 0,
    isLoading: false,
    isStreaming: false,
    connectionStatus: "disconnected",
    // Legacy fields for backwards compatibility
    page: "home",
    mode: "commands"
  });
  const { tools, isLoading: toolsLoading, executeTool: executeToolApi } = useMcpTools();
  const { recentActions, addRecentAction } = useRecentActions();
  const { recentTools, saveRecentTool } = useRecentTools(tools);
  const [selectedTool, setSelectedTool] = useState(null);
  const [messages, setMessages] = useState([]);
  const [pendingToolCalls, setPendingToolCalls] = useState([]);
  const [initialContext, setInitialContext] = useState(null);
  const [availableEntities, setAvailableEntities] = useState(null);
  const [debugEvents, setDebugEvents] = useState([]);
  const [showDebug, setShowDebug] = useState(false);
  const [opencodeSessionId, setOpencodeSessionId] = useState(null);
  const opencodeSessionIdRef = useRef(null);
  const [isThinking, setIsThinking] = useState(false);
  const [agentStatus, setAgentStatus] = useState({ type: "idle" });
  const [isSessionAuthorized, setIsSessionAuthorized] = useState(false);
  const [pendingQuestion, setPendingQuestion] = useState(null);
  const answeredQuestionIds = useRef(/* @__PURE__ */ new Set());
  const shouldStartNewMessage = useRef(false);
  const currentStreamController = useRef(null);
  const updateOpencodeSessionId = useCallback((id) => {
    opencodeSessionIdRef.current = id;
    setOpencodeSessionId(id);
  }, []);
  const addDebugEvent = useCallback((type, data) => {
    const clonedData = JSON.parse(JSON.stringify(data));
    setDebugEvents((prev) => [
      ...prev.slice(-999),
      // Keep last 1000 events
      {
        id: generateId(),
        timestamp: /* @__PURE__ */ new Date(),
        type,
        data: clonedData
      }
    ]);
  }, []);
  const clearDebugEvents = useCallback(() => {
    setDebugEvents([]);
  }, []);
  useEffect(() => {
    if (toolsLoading) {
      setState((prev) => ({ ...prev, connectionStatus: "connecting" }));
    } else if (tools.length > 0) {
      setState((prev) => ({ ...prev, connectionStatus: "connected" }));
    } else {
      setState((prev) => ({ ...prev, connectionStatus: "disconnected" }));
    }
  }, [tools, toolsLoading]);
  useEffect(() => {
    if (state.isOpen && tools.length > 0) {
      if (!initialContext) {
        console.log("[CommandPalette] Fetching initial context via context_whoami...");
        executeToolApi("context_whoami", {}).then((result) => {
          if (result.success && result.result) {
            console.log("[CommandPalette] Got initial context:", result.result);
            const ctx = result.result;
            setInitialContext(ctx);
          }
        }).catch((err) => {
          console.error("[CommandPalette] Failed to fetch initial context:", err);
        });
      }
      if (!availableEntities) {
        console.log("[CommandPalette] Fetching available entities via search_schema...");
        executeToolApi("search_schema", {}).then((result) => {
          if (result.success && result.result) {
            const schemaResult = result.result;
            console.log("[CommandPalette] Got entity schema:", schemaResult.entities?.length, "entities");
            if (schemaResult.entities) {
              setAvailableEntities(schemaResult.entities.filter((e) => e.enabled));
            }
          }
        }).catch((err) => {
          console.error("[CommandPalette] Failed to fetch entity schema:", err);
        });
      }
    }
  }, [state.isOpen, tools.length, initialContext, availableEntities, executeToolApi]);
  const filteredTools = useMemo(() => {
    const query = state.inputValue.startsWith("/") ? state.inputValue.slice(1) : state.inputValue;
    return filterTools(tools, query);
  }, [tools, state.inputValue]);
  useEffect(() => {
    const handleOpenChat = () => {
      setState((prev) => ({
        ...prev,
        isOpen: true,
        phase: "chatting",
        page: "tool-chat",
        inputValue: "",
        mode: "chat"
      }));
    };
    window.addEventListener("om:open-ai-chat", handleOpenChat);
    return () => window.removeEventListener("om:open-ai-chat", handleOpenChat);
  }, []);
  useEffect(() => {
    if (disableKeyboardShortcut) return;
    const handleKeyDown = (event) => {
      if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === AI_CHAT_SHORTCUT.key) {
        event.preventDefault();
        setState((prev) => {
          if (prev.isOpen) {
            return {
              ...prev,
              isOpen: false,
              phase: "idle",
              inputValue: "",
              page: "home",
              selectedIndex: 0,
              mode: "commands"
            };
          } else {
            return {
              ...prev,
              isOpen: true
            };
          }
        });
        if (state.isOpen) {
          setSelectedTool(null);
          setMessages([]);
          setPendingToolCalls([]);
        }
      }
      if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === AI_CHAT_SHORTCUT.key) {
        if (!isAiAssistantEnabled && !state.isOpen) {
          return;
        }
        event.preventDefault();
        if (state.isOpen) {
          setState((prev) => ({
            ...prev,
            isOpen: false,
            phase: "idle",
            inputValue: "",
            page: "home",
            selectedIndex: 0,
            mode: "commands"
          }));
          setSelectedTool(null);
          setMessages([]);
          setPendingToolCalls([]);
        } else {
          setState((prev) => ({
            ...prev,
            isOpen: true,
            phase: "chatting",
            page: "tool-chat",
            inputValue: "",
            mode: "chat"
          }));
        }
      }
      if (event.key === "Escape" && state.isOpen) {
        event.preventDefault();
        if (state.phase !== "idle") {
          setState((prev) => ({
            ...prev,
            phase: "idle",
            inputValue: "",
            page: "home",
            selectedIndex: 0,
            mode: "commands"
          }));
          setSelectedTool(null);
          setMessages([]);
          setPendingToolCalls([]);
        } else {
          setState((prev) => ({
            ...prev,
            isOpen: false,
            phase: "idle",
            inputValue: "",
            page: "home",
            selectedIndex: 0,
            mode: "commands"
          }));
          setSelectedTool(null);
          setMessages([]);
          setPendingToolCalls([]);
        }
      }
    };
    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [state.isOpen, state.phase, state.inputValue, disableKeyboardShortcut, isAiAssistantEnabled]);
  const open = useCallback(() => {
    setState((prev) => ({ ...prev, isOpen: true }));
  }, []);
  const openChat = useCallback(() => {
    setState((prev) => ({
      ...prev,
      isOpen: true,
      phase: "chatting",
      page: "tool-chat",
      inputValue: "",
      mode: "chat"
    }));
  }, []);
  const close = useCallback(() => {
    setState((prev) => ({
      ...prev,
      isOpen: false,
      phase: "idle",
      inputValue: "",
      page: "home",
      selectedIndex: 0,
      mode: "commands"
    }));
    setSelectedTool(null);
    setMessages([]);
    setPendingToolCalls([]);
    updateOpencodeSessionId(null);
    setIsSessionAuthorized(false);
    setAgentStatus({ type: "idle" });
  }, [updateOpencodeSessionId]);
  const reset = useCallback(() => {
    setState((prev) => ({
      ...prev,
      phase: "idle",
      inputValue: "",
      page: "home",
      selectedIndex: 0,
      mode: "commands"
    }));
    setSelectedTool(null);
    setMessages([]);
    setPendingToolCalls([]);
    updateOpencodeSessionId(null);
    setIsSessionAuthorized(false);
    setAgentStatus({ type: "idle" });
  }, [updateOpencodeSessionId]);
  const setIsOpen = useCallback(
    (isOpen) => {
      if (isOpen) {
        open();
      } else {
        close();
      }
    },
    [open, close]
  );
  const setMode = useCallback((mode) => {
    setState((prev) => ({ ...prev, mode }));
  }, []);
  const setInputValue = useCallback((value) => {
    setState((prev) => ({ ...prev, inputValue: value, selectedIndex: 0 }));
  }, []);
  const setSelectedIndex = useCallback((index) => {
    setState((prev) => ({ ...prev, selectedIndex: index }));
  }, []);
  const goToToolChat = useCallback(
    (tool) => {
      setSelectedTool(tool);
      saveRecentTool(tool.name);
      const initialMessage = {
        id: generateId(),
        role: "assistant",
        content: `I'll help you with "${tool.name}". ${getToolPrompt(tool)}`,
        createdAt: /* @__PURE__ */ new Date()
      };
      setMessages([initialMessage]);
      setPendingToolCalls([]);
      setState((prev) => ({
        ...prev,
        page: "tool-chat",
        inputValue: "",
        selectedIndex: 0,
        mode: "chat"
      }));
    },
    [saveRecentTool]
  );
  const goBack = useCallback(() => {
    if (state.phase !== "idle") {
      setState((prev) => ({
        ...prev,
        phase: "idle",
        page: "home",
        inputValue: "",
        selectedIndex: 0,
        mode: "commands"
      }));
      setSelectedTool(null);
      setMessages([]);
      setPendingToolCalls([]);
    }
  }, [state.phase]);
  const routeQuery = useCallback(
    async (query) => {
      const { ok, result, status } = await apiCall("/api/ai_assistant/route", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          query,
          availableTools: tools.map((t) => ({
            name: t.name,
            description: t.description
          }))
        })
      });
      if (!ok) {
        throw new Error(`Routing failed: ${status}`);
      }
      if (!result) {
        throw new Error("Routing returned empty response");
      }
      return result;
    },
    [tools]
  );
  const startAgenticChat = useCallback(
    async (initialQuery) => {
      setState((prev) => ({
        ...prev,
        phase: "chatting",
        page: "tool-chat",
        inputValue: "",
        mode: "chat"
      }));
      setState((prev) => ({ ...prev, isStreaming: true }));
      setAgentStatus({ type: "thinking" });
      try {
        const userMessage = {
          id: generateId(),
          role: "user",
          content: initialQuery,
          createdAt: /* @__PURE__ */ new Date()
        };
        setMessages([userMessage]);
        currentStreamController.current?.abort();
        const controller = new AbortController();
        currentStreamController.current = controller;
        const response = await apiFetch("/api/ai_assistant/chat", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            messages: [{ role: "user", content: initialQuery }],
            context: pageContext,
            authContext: initialContext,
            availableEntities: availableEntities?.map((e) => e.entityId),
            mode: "agentic"
          }),
          signal: controller.signal
        });
        if (!response.ok) {
          const errorText = await response.text();
          console.error("[startAgenticChat] Error response body:", errorText);
          throw new Error(`Chat request failed: ${response.status} - ${errorText}`);
        }
        const reader = response.body?.getReader();
        if (!reader) {
          throw new Error("No response body");
        }
        const decoder = new TextDecoder();
        let assistantContent = "";
        let buffer = "";
        let chunkCount = 0;
        while (true) {
          const { done, value } = await reader.read();
          if (done) break;
          chunkCount++;
          const rawChunk = decoder.decode(value, { stream: true });
          buffer += rawChunk;
          const lines = buffer.split("\n");
          buffer = lines.pop() || "";
          for (const line of lines) {
            if (line.startsWith("data: ")) {
              const data = line.slice(6);
              if (data === "[DONE]") continue;
              try {
                const event = JSON.parse(data);
                if (event.type !== "question") {
                  addDebugEvent(event.type, event);
                }
                if (event.type === "text") {
                  setIsThinking(false);
                  setAgentStatus({ type: "responding" });
                  if (shouldStartNewMessage.current) {
                    shouldStartNewMessage.current = false;
                    setMessages((prev) => prev.map((m) => m.id === "streaming" ? { ...m, id: generateId() } : m));
                    assistantContent = "";
                  }
                  assistantContent += event.content || "";
                  setMessages((prev) => {
                    const existingAssistant = prev.find((m) => m.id === "streaming");
                    if (existingAssistant) {
                      return prev.map(
                        (m) => m.id === "streaming" ? { ...m, content: assistantContent } : m
                      );
                    } else {
                      return [
                        ...prev,
                        {
                          id: "streaming",
                          role: "assistant",
                          content: assistantContent,
                          createdAt: /* @__PURE__ */ new Date()
                        }
                      ];
                    }
                  });
                } else if (event.type === "tool-call") {
                  const toolName = event.toolName;
                  const toolArgs = event.args ?? {};
                  setAgentStatus({ type: "tool", toolName });
                  if (!isToolSafeToAutoExecute(toolName)) {
                    setPendingToolCalls((prev) => [
                      ...prev,
                      {
                        id: event.id,
                        toolName,
                        args: toolArgs,
                        status: "completed"
                        // Already executed server-side
                      }
                    ]);
                  }
                } else if (event.type === "debug") {
                  const debugEvent = event;
                  if (debugEvent.partType === "step-start") {
                    setAgentStatus({ type: "executing" });
                  }
                  if (debugEvent.partType === "step-finish" && debugEvent.data?.reason === "tool-calls") {
                    setAgentStatus({ type: "thinking" });
                  }
                } else if (event.type === "error") {
                  console.error("[startAgenticChat] Error event:", event.error);
                  setAgentStatus({ type: "idle" });
                } else if (event.type === "done") {
                  setIsThinking(false);
                  setAgentStatus({ type: "idle" });
                  setState((prev) => ({ ...prev, isStreaming: false }));
                  if (event.sessionId) {
                    updateOpencodeSessionId(event.sessionId);
                  }
                } else if (event.type === "question") {
                  const question = event.question;
                  if (answeredQuestionIds.current.has(question.id)) {
                  } else {
                    setIsThinking(false);
                    setAgentStatus({ type: "idle" });
                    setState((prev) => ({ ...prev, isStreaming: false }));
                    setPendingQuestion(question);
                    if (question.sessionID) {
                      updateOpencodeSessionId(question.sessionID);
                    }
                    addDebugEvent("question", {
                      type: "question",
                      questionId: question.id,
                      sessionID: question.sessionID,
                      questionText: question.questions?.[0]?.question || "No question text",
                      header: question.questions?.[0]?.header || "Confirmation",
                      options: question.questions?.[0]?.options?.map((o) => o.label) || [],
                      fullQuestion: question
                    });
                  }
                } else if (event.type === "session-authorized") {
                  setIsSessionAuthorized(true);
                }
              } catch (parseError) {
                console.warn("[startAgenticChat] Failed to parse event:", data, parseError);
              }
            }
          }
        }
        setMessages((prev) => prev.map((m) => m.id === "streaming" ? { ...m, id: generateId() } : m));
      } catch (error) {
        if (error instanceof Error && error.name === "AbortError") {
          return;
        }
        console.error("[startAgenticChat] Error:", error);
        setAgentStatus({ type: "idle" });
        setMessages((prev) => [
          ...prev,
          {
            id: generateId(),
            role: "assistant",
            content: `Sorry, I encountered an error: ${error instanceof Error ? error.message : "Unknown error"}`,
            createdAt: /* @__PURE__ */ new Date()
          }
        ]);
      } finally {
        setState((prev) => ({ ...prev, isStreaming: false }));
        setAgentStatus({ type: "idle" });
      }
    },
    [pageContext, initialContext, availableEntities, executeToolApi, addDebugEvent, updateOpencodeSessionId]
  );
  const startGeneralChat = useCallback(
    async (initialQuery) => {
      setState((prev) => ({
        ...prev,
        phase: "chatting",
        page: "tool-chat",
        inputValue: "",
        mode: "chat"
      }));
      setState((prev) => ({ ...prev, isStreaming: true }));
      try {
        const userMessage = {
          id: generateId(),
          role: "user",
          content: initialQuery,
          createdAt: /* @__PURE__ */ new Date()
        };
        setMessages([userMessage]);
        const response = await apiFetch("/api/ai_assistant/chat", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            messages: [{ role: "user", content: initialQuery }],
            context: pageContext,
            authContext: initialContext,
            availableEntities: availableEntities?.map((e) => e.entityId),
            mode: "default"
          })
        });
        if (!response.ok) {
          throw new Error(`Chat request failed: ${response.status}`);
        }
        const reader = response.body?.getReader();
        if (!reader) {
          throw new Error("No response body");
        }
        const decoder = new TextDecoder();
        let assistantContent = "";
        while (true) {
          const { done, value } = await reader.read();
          if (done) break;
          const chunk = decoder.decode(value, { stream: true });
          assistantContent += chunk;
          setMessages((prev) => {
            const existingAssistant = prev.find((m) => m.id === "streaming");
            if (existingAssistant) {
              return prev.map(
                (m) => m.id === "streaming" ? { ...m, content: assistantContent } : m
              );
            } else {
              return [
                ...prev,
                {
                  id: "streaming",
                  role: "assistant",
                  content: assistantContent,
                  createdAt: /* @__PURE__ */ new Date()
                }
              ];
            }
          });
        }
        setMessages((prev) => prev.map((m) => m.id === "streaming" ? { ...m, id: generateId() } : m));
      } catch (error) {
        console.error("General chat error:", error);
        setMessages((prev) => [
          ...prev,
          {
            id: generateId(),
            role: "assistant",
            content: "Sorry, I encountered an error. Please try again.",
            createdAt: /* @__PURE__ */ new Date()
          }
        ]);
      } finally {
        setState((prev) => ({ ...prev, isStreaming: false }));
      }
    },
    [pageContext, initialContext, availableEntities]
  );
  const executeTool = useCallback(
    async (toolName, args = {}) => {
      setState((prev) => ({ ...prev, isLoading: true }));
      try {
        const result = await executeToolApi(toolName, args);
        if (result.success) {
          const tool = tools.find((t) => t.name === toolName);
          addRecentAction({
            toolName,
            displayName: tool?.description || toolName,
            args
          });
        }
        return result;
      } finally {
        setState((prev) => ({ ...prev, isLoading: false }));
      }
    },
    [executeToolApi, tools, addRecentAction]
  );
  const approveToolCall = useCallback(
    async (toolCallId) => {
      const toolCall = pendingToolCalls.find((tc) => tc.id === toolCallId);
      if (!toolCall) return;
      setPendingToolCalls(
        (prev) => prev.map((tc) => tc.id === toolCallId ? { ...tc, status: "executing" } : tc)
      );
      try {
        const result = await executeToolApi(toolCall.toolName, toolCall.args);
        setPendingToolCalls(
          (prev) => prev.map(
            (tc) => tc.id === toolCallId ? {
              ...tc,
              status: result.success ? "completed" : "error",
              result: result.result,
              error: result.error
            } : tc
          )
        );
        if (result.success) {
          const tool = tools.find((t) => t.name === toolCall.toolName);
          addRecentAction({
            toolName: toolCall.toolName,
            displayName: tool?.description || toolCall.toolName,
            args: toolCall.args
          });
          setMessages((prev) => [
            ...prev,
            {
              id: generateId(),
              role: "assistant",
              content: `Done! The ${toolCall.toolName.replace(/_/g, " ")} operation completed successfully.`,
              createdAt: /* @__PURE__ */ new Date()
            }
          ]);
        } else {
          setMessages((prev) => [
            ...prev,
            {
              id: generateId(),
              role: "assistant",
              content: `I encountered an issue: ${result.error || "Unknown error"}`,
              createdAt: /* @__PURE__ */ new Date()
            }
          ]);
        }
      } catch (error) {
        setPendingToolCalls(
          (prev) => prev.map(
            (tc) => tc.id === toolCallId ? {
              ...tc,
              status: "error",
              error: error instanceof Error ? error.message : "Unknown error"
            } : tc
          )
        );
      }
    },
    [pendingToolCalls, executeToolApi, tools, addRecentAction]
  );
  const rejectToolCall = useCallback((toolCallId) => {
    setPendingToolCalls(
      (prev) => prev.map((tc) => tc.id === toolCallId ? { ...tc, status: "rejected" } : tc)
    );
    setMessages((prev) => [
      ...prev,
      {
        id: generateId(),
        role: "assistant",
        content: "Tool call cancelled. How else can I help?",
        createdAt: /* @__PURE__ */ new Date()
      }
    ]);
  }, []);
  const sendAgenticMessage = useCallback(
    async (content) => {
      if (!content.trim()) return;
      const userMessage = {
        id: generateId(),
        role: "user",
        content: content.trim(),
        createdAt: /* @__PURE__ */ new Date()
      };
      setMessages((prev) => [...prev, userMessage]);
      setState((prev) => ({ ...prev, isStreaming: true }));
      setIsThinking(true);
      setAgentStatus({ type: "thinking" });
      try {
        currentStreamController.current?.abort();
        const controller = new AbortController();
        currentStreamController.current = controller;
        const response = await apiFetch("/api/ai_assistant/chat", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            messages: [...messages, userMessage].map((m) => ({
              role: m.role,
              content: m.content
            })),
            sessionId: opencodeSessionIdRef.current
          }),
          signal: controller.signal
        });
        if (!response.ok) {
          throw new Error(`Chat request failed: ${response.status}`);
        }
        const reader = response.body?.getReader();
        if (!reader) {
          throw new Error("No response body");
        }
        const decoder = new TextDecoder();
        let assistantContent = "";
        let buffer = "";
        while (true) {
          const { done, value } = await reader.read();
          if (done) break;
          buffer += decoder.decode(value, { stream: true });
          const lines = buffer.split("\n");
          buffer = lines.pop() || "";
          for (const line of lines) {
            if (line.startsWith("data: ")) {
              const data = line.slice(6);
              if (data === "[DONE]") continue;
              try {
                const event = JSON.parse(data);
                if (event.type !== "question") {
                  addDebugEvent(event.type, event);
                }
                if (event.type === "thinking") {
                  setIsThinking(true);
                  setAgentStatus({ type: "thinking" });
                } else if (event.type === "session-authorized") {
                  setIsSessionAuthorized(true);
                } else if (event.type === "text") {
                  if (shouldStartNewMessage.current) {
                    shouldStartNewMessage.current = false;
                    setMessages((prev) => prev.map((m) => m.id === "streaming" ? { ...m, id: generateId() } : m));
                    assistantContent = "";
                  }
                  setIsThinking(false);
                  setAgentStatus({ type: "responding" });
                  assistantContent += event.content || "";
                  setMessages((prev) => {
                    const existingAssistant = prev.find(
                      (m) => m.role === "assistant" && m.id === "streaming"
                    );
                    if (existingAssistant) {
                      return prev.map(
                        (m) => m.id === "streaming" ? { ...m, content: assistantContent } : m
                      );
                    } else {
                      return [
                        ...prev,
                        {
                          id: "streaming",
                          role: "assistant",
                          content: assistantContent,
                          createdAt: /* @__PURE__ */ new Date()
                        }
                      ];
                    }
                  });
                } else if (event.type === "done") {
                  setIsThinking(false);
                  setAgentStatus({ type: "idle" });
                  setState((prev) => ({ ...prev, isStreaming: false }));
                  if (event.sessionId) {
                    updateOpencodeSessionId(event.sessionId);
                  }
                } else if (event.type === "error") {
                  setIsThinking(false);
                  setAgentStatus({ type: "idle" });
                  setMessages((prev) => [
                    ...prev,
                    {
                      id: generateId(),
                      role: "assistant",
                      content: `Error: ${event.error || "Unknown error occurred"}`,
                      createdAt: /* @__PURE__ */ new Date()
                    }
                  ]);
                } else if (event.type === "tool-call") {
                  const toolName = event.toolName;
                  const toolArgs = event.args ?? {};
                  setAgentStatus({ type: "tool", toolName });
                  if (!isToolSafeToAutoExecute(toolName)) {
                    setPendingToolCalls((prev) => [
                      ...prev,
                      { id: event.id, toolName, args: toolArgs, status: "completed" }
                    ]);
                  }
                } else if (event.type === "question") {
                  const question = event.question;
                  if (answeredQuestionIds.current.has(question.id)) {
                  } else {
                    setIsThinking(false);
                    setAgentStatus({ type: "idle" });
                    setState((prev) => ({ ...prev, isStreaming: false }));
                    setPendingQuestion(question);
                    addDebugEvent("question", {
                      type: "question",
                      questionId: question.id,
                      sessionID: question.sessionID,
                      questionText: question.questions?.[0]?.question || "No question text",
                      header: question.questions?.[0]?.header || "Confirmation",
                      options: question.questions?.[0]?.options?.map((o) => o.label) || [],
                      fullQuestion: question
                    });
                  }
                } else if (event.type === "debug") {
                  const debugEvent = event;
                  if (debugEvent.partType === "step-start") {
                    setAgentStatus({ type: "executing" });
                  }
                  if (debugEvent.partType === "step-finish" && debugEvent.data?.reason === "tool-calls") {
                    setAgentStatus({ type: "thinking" });
                  }
                }
              } catch {
                assistantContent += data;
                setMessages((prev) => {
                  const existingAssistant = prev.find(
                    (m) => m.role === "assistant" && m.id === "streaming"
                  );
                  if (existingAssistant) {
                    return prev.map(
                      (m) => m.id === "streaming" ? { ...m, content: assistantContent } : m
                    );
                  } else {
                    return [
                      ...prev,
                      {
                        id: "streaming",
                        role: "assistant",
                        content: assistantContent,
                        createdAt: /* @__PURE__ */ new Date()
                      }
                    ];
                  }
                });
              }
            } else if (line.trim() && !line.startsWith(":")) {
              assistantContent += line;
              setMessages((prev) => {
                const existingAssistant = prev.find(
                  (m) => m.role === "assistant" && m.id === "streaming"
                );
                if (existingAssistant) {
                  return prev.map(
                    (m) => m.id === "streaming" ? { ...m, content: assistantContent } : m
                  );
                } else {
                  return [
                    ...prev,
                    {
                      id: "streaming",
                      role: "assistant",
                      content: assistantContent,
                      createdAt: /* @__PURE__ */ new Date()
                    }
                  ];
                }
              });
            }
          }
        }
        setMessages((prev) => prev.map((m) => m.id === "streaming" ? { ...m, id: generateId() } : m));
      } catch (error) {
        if (error instanceof Error && error.name === "AbortError") {
          return;
        }
        console.error("Tool chat error:", error);
        setAgentStatus({ type: "idle" });
        setMessages((prev) => [
          ...prev,
          {
            id: generateId(),
            role: "assistant",
            content: "Sorry, I encountered an error. Please try again.",
            createdAt: /* @__PURE__ */ new Date()
          }
        ]);
      } finally {
        setState((prev) => ({ ...prev, isStreaming: false }));
        setIsThinking(false);
        setAgentStatus({ type: "idle" });
      }
    },
    [messages, addDebugEvent, updateOpencodeSessionId]
  );
  const handleSubmit = useCallback(
    async (query) => {
      if (!query.trim()) return;
      if (opencodeSessionIdRef.current) {
        await sendAgenticMessage(query);
      } else {
        await startAgenticChat(query);
      }
    },
    [startAgenticChat, sendAgenticMessage]
  );
  const answerQuestion = useCallback(
    async (answer) => {
      if (!pendingQuestion) return;
      const questionId = pendingQuestion.id;
      answeredQuestionIds.current.add(questionId);
      shouldStartNewMessage.current = true;
      setPendingQuestion(null);
      setIsThinking(true);
      setAgentStatus({ type: "thinking" });
      const selectedOption = pendingQuestion.questions[0]?.options[answer];
      setMessages((prev) => [
        ...prev,
        {
          id: generateId(),
          role: "user",
          content: `[Confirmed: ${selectedOption?.label || "Yes"}]`,
          createdAt: /* @__PURE__ */ new Date()
        }
      ]);
      try {
        const sessionId = pendingQuestion.sessionID;
        const { ok, result, status } = await apiCall("/api/ai_assistant/chat", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            answerQuestion: {
              questionId,
              answer,
              sessionId
            }
          })
        });
        if (!ok) {
          throw new Error(result?.error || `Answer request failed: ${status}`);
        }
      } catch (error) {
        console.error("[answerQuestion] Error:", error);
        setIsThinking(false);
        setAgentStatus({ type: "idle" });
        setMessages((prev) => [
          ...prev,
          {
            id: generateId(),
            role: "assistant",
            content: `Error: ${error instanceof Error ? error.message : "Failed to send answer"}`,
            createdAt: /* @__PURE__ */ new Date()
          }
        ]);
      }
    },
    [pendingQuestion]
  );
  const sendMessage = useCallback(
    async (content) => {
      if (!content.trim()) return;
      const userMessage = {
        id: generateId(),
        role: "user",
        content: content.trim(),
        createdAt: /* @__PURE__ */ new Date()
      };
      setMessages((prev) => [...prev, userMessage]);
      setState((prev) => ({ ...prev, isStreaming: true }));
      try {
        const response = await apiFetch("/api/ai_assistant/chat", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            messages: [...messages, userMessage].map((m) => ({
              role: m.role,
              content: m.content
            })),
            context: pageContext
          })
        });
        if (!response.ok) {
          throw new Error(`Chat request failed: ${response.status}`);
        }
        const reader = response.body?.getReader();
        if (!reader) {
          throw new Error("No response body");
        }
        const decoder = new TextDecoder();
        let assistantContent = "";
        while (true) {
          const { done, value } = await reader.read();
          if (done) break;
          const chunk = decoder.decode(value, { stream: true });
          assistantContent += chunk;
          setMessages((prev) => {
            const existingAssistant = prev.find(
              (m) => m.role === "assistant" && m.id === "streaming"
            );
            if (existingAssistant) {
              return prev.map(
                (m) => m.id === "streaming" ? { ...m, content: assistantContent } : m
              );
            } else {
              return [
                ...prev,
                {
                  id: "streaming",
                  role: "assistant",
                  content: assistantContent,
                  createdAt: /* @__PURE__ */ new Date()
                }
              ];
            }
          });
        }
        setMessages((prev) => prev.map((m) => m.id === "streaming" ? { ...m, id: generateId() } : m));
      } catch (error) {
        console.error("Chat error:", error);
        setMessages((prev) => [
          ...prev,
          {
            id: generateId(),
            role: "assistant",
            content: "Sorry, I encountered an error. Please try again.",
            createdAt: /* @__PURE__ */ new Date()
          }
        ]);
      } finally {
        setState((prev) => ({ ...prev, isStreaming: false }));
      }
    },
    [messages, pageContext]
  );
  const clearMessages = useCallback(() => {
    setMessages([]);
    setPendingToolCalls([]);
  }, []);
  const stopExecution = useCallback(() => {
    currentStreamController.current?.abort();
    currentStreamController.current = null;
    setState((prev) => ({ ...prev, isStreaming: false }));
    setAgentStatus({ type: "idle" });
    setIsThinking(false);
    setMessages((prev) => [
      ...prev.map((m) => m.id === "streaming" ? { ...m, id: generateId() } : m),
      // Finalize any streaming message
      {
        id: generateId(),
        role: "system",
        content: "Execution stopped by user.",
        createdAt: /* @__PURE__ */ new Date()
      }
    ]);
  }, []);
  return {
    // State
    state: {
      ...state,
      isLoading: state.isLoading || toolsLoading
    },
    isThinking,
    agentStatus,
    isSessionAuthorized,
    pageContext,
    selectedEntities,
    tools,
    filteredTools,
    recentActions,
    recentTools,
    messages,
    pendingToolCalls,
    selectedTool,
    initialContext,
    availableEntities,
    // Navigation actions
    open,
    openChat,
    close,
    setIsOpen,
    setInputValue,
    setSelectedIndex,
    // Intelligent routing - submit natural language query
    handleSubmit,
    reset,
    // Page navigation (legacy, kept for compatibility)
    goToToolChat,
    goBack,
    // Tool execution
    executeTool,
    approveToolCall,
    rejectToolCall,
    // Chat actions
    sendMessage,
    sendAgenticMessage,
    clearMessages,
    stopExecution,
    // Legacy compatibility
    setMode,
    // Debug mode
    debugEvents,
    showDebug,
    setShowDebug,
    clearDebugEvents,
    // OpenCode question handling
    pendingQuestion,
    answerQuestion
  };
}
export {
  useCommandPalette
};
//# sourceMappingURL=useCommandPalette.js.map
