import { useEffect, useRef } from "react";
import { setMaxListeners } from "events";
import { parseCodexBaseURL } from "@dexto/core";
import { getModelDisplayName } from "@dexto/llm";
import { generateMessageId } from "../utils/idGenerator.js";
function extractTextContent(content) {
  return content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
}
function useAgentEvents({
  agent,
  setMessages,
  setPendingMessages,
  setUi,
  setSession,
  setInput,
  setApproval,
  setApprovalQueue,
  setSteerMessages,
  setQueuedMessages,
  currentSessionId,
  buffer
}) {
  const externalTriggerRef = useRef({ active: false, sessionId: null, messageId: null });
  useEffect(() => {
    const controller = new AbortController();
    const { signal } = controller;
    setMaxListeners(25, signal);
    const syncQueue = (sessionId, queue) => {
      const getMessages = queue === "steer" ? agent.getSteerMessages(sessionId) : agent.getFollowUpMessages(sessionId);
      void getMessages.then((messages) => {
        if (queue === "steer") {
          setSteerMessages(messages);
        } else {
          setQueuedMessages(messages);
        }
      }).catch(() => {
      });
    };
    agent.on(
      "llm:switched",
      (payload) => {
        if (payload.newConfig?.model) {
          setSession((prev) => ({
            ...prev,
            modelName: getModelDisplayName(
              payload.newConfig.model,
              payload.newConfig.provider
            )
          }));
        }
        const nextIsChatGPTLogin = payload.newConfig?.provider === "openai-compatible" && parseCodexBaseURL(payload.newConfig?.baseURL)?.authMode === "chatgpt";
        if (!nextIsChatGPTLogin) {
          setUi((prev) => ({
            ...prev,
            chatgptRateLimitStatus: null,
            ...prev.activeOverlay === "chatgpt-usage-cap" ? { activeOverlay: "none" } : {}
          }));
        }
      },
      { signal }
    );
    agent.on(
      "llm:rate-limit-status",
      (payload) => {
        if (payload.sessionId !== currentSessionId) {
          return;
        }
        setUi((prev) => ({
          ...prev,
          chatgptRateLimitStatus: payload.snapshot,
          ...payload.snapshot.exceeded && prev.activeOverlay === "none" ? { activeOverlay: "chatgpt-usage-cap" } : {}
        }));
      },
      { signal }
    );
    agent.on(
      "service:event",
      (payload) => {
        if (payload.service !== "orchestration" || payload.event !== "tasks-updated") {
          return;
        }
        if (payload.sessionId && payload.sessionId !== currentSessionId) {
          return;
        }
        const data = payload.data;
        if (data.tasks) {
          setUi((prev) => {
            const runningCount = typeof data.runningCount === "number" ? data.runningCount : prev.backgroundTasksRunning;
            return {
              ...prev,
              backgroundTasks: data.tasks ?? prev.backgroundTasks,
              backgroundTasksRunning: runningCount
            };
          });
        } else if (typeof data.runningCount === "number") {
          setUi((prev) => ({
            ...prev,
            backgroundTasksRunning: data.runningCount ?? prev.backgroundTasksRunning
          }));
        }
      },
      { signal }
    );
    agent.on(
      "tool:background",
      (payload) => {
        if (payload.sessionId !== currentSessionId) {
          return;
        }
        const messageId = `tool-${payload.toolCallId}`;
        setMessages(
          (prev) => prev.map((message) => {
            if (message.id !== messageId) {
              return message;
            }
            return {
              ...message,
              toolStatus: "running",
              toolResult: "Background task started",
              isBackground: true
            };
          })
        );
      },
      { signal }
    );
    agent.on(
      "tool:background-completed",
      (payload) => {
        if (payload.sessionId !== currentSessionId) {
          return;
        }
        const messageId = `tool-${payload.toolCallId}`;
        setMessages(
          (prev) => prev.map((message) => {
            if (message.id !== messageId) {
              return message;
            }
            return {
              ...message,
              toolStatus: "finished",
              toolResult: "Background task completed",
              isBackground: true
            };
          })
        );
      },
      { signal }
    );
    agent.on(
      "session:reset",
      () => {
        setMessages([]);
        setApproval(null);
        setApprovalQueue([]);
        setSteerMessages([]);
        setQueuedMessages([]);
        setUi((prev) => ({
          ...prev,
          activeOverlay: "none",
          chatgptRateLimitStatus: null,
          insufficientCredits: null
        }));
      },
      { signal }
    );
    agent.on(
      "session:created",
      (payload) => {
        if (payload.switchTo) {
          if (process.stdout.isTTY) {
            process.stdout.write("\x1B[2J\x1B[3J\x1B[H");
          }
          setMessages([]);
          setPendingMessages([]);
          setApproval(null);
          setApprovalQueue([]);
          setSteerMessages([]);
          setQueuedMessages([]);
          buffer.setText("");
          setInput((prev) => ({
            ...prev,
            value: "",
            history: [],
            historyIndex: -1,
            draftBeforeHistory: "",
            editingQueuedFollowUp: false,
            images: [],
            pastedBlocks: [],
            pasteCounter: 0
          }));
          if (payload.sessionId === null) {
            setSession((prev) => ({ ...prev, id: null, hasActiveSession: false }));
          } else {
            setSession((prev) => ({
              ...prev,
              id: payload.sessionId,
              hasActiveSession: true
            }));
          }
          setUi((prev) => ({
            ...prev,
            activeOverlay: "none",
            chatgptRateLimitStatus: null,
            insufficientCredits: null,
            historySearch: {
              isActive: false,
              query: "",
              matchIndex: 0,
              originalInput: "",
              lastMatch: ""
            }
          }));
        }
      },
      { signal }
    );
    agent.on(
      "context:cleared",
      () => {
        setApproval(null);
        setApprovalQueue([]);
        setSteerMessages([]);
        setQueuedMessages([]);
        setUi((prev) => ({
          ...prev,
          activeOverlay: "none",
          chatgptRateLimitStatus: null,
          insufficientCredits: null
        }));
      },
      { signal }
    );
    agent.on(
      "context:compacting",
      (payload) => {
        if (payload.sessionId !== currentSessionId) return;
        setUi((prev) => ({ ...prev, isCompacting: true }));
      },
      { signal }
    );
    agent.on(
      "context:compacted",
      (payload) => {
        if (payload.sessionId !== currentSessionId) return;
        setUi((prev) => ({ ...prev, isCompacting: false }));
        const reductionPercent = payload.originalTokens > 0 ? Math.round(
          (payload.originalTokens - payload.compactedTokens) / payload.originalTokens * 100
        ) : 0;
        const compactionContent = `\u{1F4E6} Context compacted
   ${payload.originalMessages} messages \u2192 ${payload.compactedMessages} messages
   ~${payload.originalTokens.toLocaleString()} \u2192 ~${payload.compactedTokens.toLocaleString()} tokens (${reductionPercent}% reduction)`;
        setMessages((prev) => [
          ...prev,
          {
            id: generateMessageId("system"),
            role: "system",
            content: compactionContent,
            timestamp: /* @__PURE__ */ new Date()
          }
        ]);
      },
      { signal }
    );
    agent.on(
      "message:queued",
      (payload) => {
        if (!payload.sessionId) return;
        syncQueue(payload.sessionId, payload.queue);
      },
      { signal }
    );
    agent.on(
      "message:removed",
      (payload) => {
        if (!payload.sessionId) {
          if (payload.queue === "steer") {
            setSteerMessages((prev) => prev.filter((m) => m.id !== payload.id));
          } else {
            setQueuedMessages((prev) => prev.filter((m) => m.id !== payload.id));
          }
          return;
        }
        syncQueue(payload.sessionId, payload.queue);
      },
      { signal }
    );
    agent.on(
      "run:invoke",
      (payload) => {
        if (payload.sessionId !== currentSessionId) {
          return;
        }
        const messageId = generateMessageId("assistant");
        externalTriggerRef.current = {
          active: true,
          sessionId: payload.sessionId,
          messageId
        };
        const promptText = extractTextContent(payload.content);
        const sourceLabel = payload.source === "scheduler" ? "\u23F0 Scheduled Task" : payload.source === "a2a" ? "\u{1F916} A2A Request" : payload.source === "api" ? "\u{1F50C} API Request" : "\u{1F4E5} External Request";
        const triggerTimestamp = /* @__PURE__ */ new Date();
        const scheduleName = typeof payload.metadata?.scheduleName === "string" ? payload.metadata.scheduleName : null;
        const triggerLabel = scheduleName ? `${sourceLabel}: ${scheduleName}` : sourceLabel;
        setMessages((prev) => [
          ...prev,
          {
            id: generateMessageId("system"),
            role: "system",
            content: triggerLabel,
            timestamp: triggerTimestamp,
            styledType: "external-trigger",
            styledData: {
              label: triggerLabel,
              source: payload.source ?? "external",
              timestamp: triggerTimestamp
            }
          },
          {
            id: generateMessageId("user"),
            role: "user",
            content: promptText,
            timestamp: /* @__PURE__ */ new Date()
          }
        ]);
        setUi((prev) => ({
          ...prev,
          isProcessing: true,
          isThinking: true
        }));
        setPendingMessages([
          {
            id: messageId,
            role: "assistant",
            content: "",
            timestamp: /* @__PURE__ */ new Date(),
            isStreaming: true
          }
        ]);
      },
      { signal }
    );
    agent.on(
      "llm:chunk",
      (payload) => {
        if (!externalTriggerRef.current.active || payload.sessionId !== externalTriggerRef.current.sessionId) {
          return;
        }
        if (payload.chunkType !== "text") {
          return;
        }
        setPendingMessages(
          (prev) => prev.map(
            (msg) => msg.id === externalTriggerRef.current.messageId ? { ...msg, content: msg.content + payload.content } : msg
          )
        );
        setUi((prev) => prev.isThinking ? { ...prev, isThinking: false } : prev);
      },
      { signal }
    );
    agent.on(
      "llm:thinking",
      (payload) => {
        if (!externalTriggerRef.current.active || payload.sessionId !== externalTriggerRef.current.sessionId) {
          return;
        }
        setUi((prev) => ({ ...prev, isThinking: true }));
      },
      { signal }
    );
    agent.on(
      "run:complete",
      (payload) => {
        if (!externalTriggerRef.current.active || payload.sessionId !== externalTriggerRef.current.sessionId) {
          return;
        }
        setPendingMessages((prev) => {
          const pendingMsg = prev.find(
            (m) => m.id === externalTriggerRef.current.messageId
          );
          if (pendingMsg) {
            setMessages((msgs) => [...msgs, { ...pendingMsg, isStreaming: false }]);
          }
          return prev.filter((m) => m.id !== externalTriggerRef.current.messageId);
        });
        setUi((prev) => ({
          ...prev,
          isProcessing: false,
          isThinking: false
        }));
        externalTriggerRef.current = { active: false, sessionId: null, messageId: null };
      },
      { signal }
    );
    return () => {
      controller.abort();
    };
  }, [
    agent,
    setMessages,
    setPendingMessages,
    setUi,
    setSession,
    setInput,
    setApproval,
    setApprovalQueue,
    setSteerMessages,
    setQueuedMessages,
    currentSessionId,
    buffer
  ]);
}
export {
  useAgentEvents
};
