"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const react = require("../../../_vendor/@legendapp/state/react.cjs");
const index_browser = require("../../../_vendor/nanoid/index.browser.cjs");
const React = require("react");
const index = require("../../../_vendor/usehooks-ts/dist-index.cjs");
const combinedStore = require("../../../stores/combined-store.cjs");
const concurrencyStore = require("../../../stores/concurrency-store.cjs");
const streamingStore = require("../../../stores/streaming-store.cjs");
const queueStore = require("../../../stores/queue-store.cjs");
const commandHistoryStore = require("../../../stores/command-history-store.cjs");
const coreStore = require("../../../stores/core-store.cjs");
const core = require("../../../types/core.cjs");
const messageStore = require("../../../stores/message-store.cjs");
function useMessageSending(options) {
  const { onSendMessage, onCreateNewChat, onFileUploadError, beforeOnSendMessage } = options;
  const currentChat = react.use$(coreStore.coreStore$.currentChat);
  const canSendMessage = react.use$(combinedStore.combinedComputed$.canSendMessage);
  const canSendNewMessage = react.use$(concurrencyStore.concurrencyComputed$.canSendNewMessage);
  const streamingStatus = react.use$(streamingStore.streamingComputed$.streamingStatus);
  const hasPendingMessages = react.use$(queueStore.queueComputed$.hasPendingMessages);
  const lastSentMessageRef = React.useRef(null);
  const [isSending, setIsSending] = React.useState(false);
  const timeoutRef = React.useRef(null);
  const checkUnuploadedFiles = (attachments) => {
    return attachments.some(
      (att) => att.uploadStatus !== "completed" && att.uploadStatus !== void 0
    );
  };
  const checkDuplicateRequest = (content) => {
    const now = Date.now();
    if (lastSentMessageRef.current) {
      const { content: lastContent, timestamp: lastTime } = lastSentMessageRef.current;
      const timeDiff = now - lastTime;
      if (lastContent === content && timeDiff < 1e3) {
        console.warn(
          "Duplicate message detected. Please wait before sending the same message again."
        );
        return true;
      }
    }
    return false;
  };
  const addMessageToQueue = index.useEventCallback(
    (content, attachments, clearInput, focusInput, modelId) => {
      if (!content.trim() && attachments.length === 0) return;
      const trimmedContent = content.trim();
      const hasUnuploadedFiles = checkUnuploadedFiles(attachments);
      if (hasUnuploadedFiles) {
        onFileUploadError?.("Please wait for all files to finish uploading");
        return;
      }
      if (checkDuplicateRequest(trimmedContent)) return;
      const pendingMessage = {
        id: index_browser.nanoid(),
        content: trimmedContent,
        attachments: attachments.length > 0 ? attachments : void 0,
        modelId,
        timestamp: (/* @__PURE__ */ new Date()).toISOString(),
        priority: 0
        // 默认优先级
      };
      queueStore.queueActions.addPendingMessage(pendingMessage);
      commandHistoryStore.commandHistoryActions.addCommand(trimmedContent);
      clearInput();
      focusInput();
      console.log(`Message queued: "${trimmedContent}"`);
    }
  );
  const handleSendMessage = index.useEventCallback(
    async (content, attachments, clearInput, focusInput, modelId) => {
      if (beforeOnSendMessage && !await beforeOnSendMessage()) {
        return;
      }
      if (streamingStatus.isStreaming && streamingStatus.currentMessageId) {
        return addMessageToQueue(content, attachments, clearInput, focusInput, modelId);
      }
      if (!content.trim() && attachments.length === 0 || !canSendMessage || isSending) return;
      const trimmedContent = content.trim();
      const hasUnuploadedFiles = checkUnuploadedFiles(attachments);
      if (hasUnuploadedFiles) {
        onFileUploadError?.("Please wait for all files to finish uploading");
        return;
      }
      if (checkDuplicateRequest(trimmedContent)) return;
      if (!canSendNewMessage) {
        console.warn(
          "Maximum concurrent messages reached. Please wait for current messages to complete."
        );
        return;
      }
      setIsSending(true);
      lastSentMessageRef.current = { content: trimmedContent, timestamp: Date.now() };
      try {
        let chatId = currentChat?.id;
        if (!chatId) {
          if (onCreateNewChat) {
            chatId = onCreateNewChat();
          } else {
            console.warn("No current chat available and no onCreateNewChat provided");
            return;
          }
        }
        clearInput();
        focusInput();
        const userMessage = {
          id: index_browser.nanoid(),
          content: trimmedContent,
          role: core.Role.User,
          timestamp: (/* @__PURE__ */ new Date()).toISOString(),
          createdAt: (/* @__PURE__ */ new Date()).toISOString(),
          version: 1,
          isStreaming: false,
          status: core.Status.Pending,
          retryCount: 0,
          maxRetries: 3,
          abortController: new AbortController(),
          attachments: attachments.length > 0 ? attachments : void 0
        };
        messageStore.messageActions.addMessage(userMessage);
        commandHistoryStore.commandHistoryActions.addCommand(trimmedContent);
        if (onSendMessage && chatId) {
          concurrencyStore.concurrencyActions.incrementActiveSessions();
          queueStore.queueActions.enqueueMessage(userMessage.id, "sendingQueue");
          const timeoutDuration = 3e4;
          timeoutRef.current = setTimeout(() => {
            userMessage.abortController?.abort();
            messageStore.messageActions.updateMessage(userMessage.id, {
              status: core.Status.Failed,
              error: {
                message: "Request timeout after 30 seconds",
                code: "TIMEOUT",
                timestamp: (/* @__PURE__ */ new Date()).toISOString()
              }
            });
            queueStore.queueActions.dequeueMessage(userMessage.id, "sendingQueue");
            queueStore.queueActions.enqueueMessage(userMessage.id, "failedQueue");
            concurrencyStore.concurrencyActions.decrementActiveSessions();
          }, timeoutDuration);
          try {
            const validAttachments = attachments.filter((att) => att.uploadStatus === "completed" || att.uploadStatus === void 0).map((att) => ({
              ...att,
              url: att.url
            }));
            await onSendMessage(
              trimmedContent,
              chatId,
              validAttachments.length > 0 ? validAttachments : void 0,
              modelId,
              userMessage.id
            );
            if (timeoutRef.current) {
              clearTimeout(timeoutRef.current);
              timeoutRef.current = null;
            }
            queueStore.queueActions.dequeueMessage(userMessage.id, "sendingQueue");
          } catch (error) {
            if (timeoutRef.current) {
              clearTimeout(timeoutRef.current);
              timeoutRef.current = null;
            }
            queueStore.queueActions.dequeueMessage(userMessage.id, "sendingQueue");
            queueStore.queueActions.enqueueMessage(userMessage.id, "failedQueue");
            messageStore.messageActions.updateMessage(userMessage.id, {
              status: core.Status.Failed,
              error: {
                message: error instanceof Error ? error.message : "Failed to send message",
                timestamp: (/* @__PURE__ */ new Date()).toISOString()
              }
            });
            throw error;
          } finally {
            concurrencyStore.concurrencyActions.decrementActiveSessions();
          }
        }
      } catch (error) {
        console.error("Send message failed:", error);
      } finally {
        setIsSending(false);
      }
    }
  );
  const getSendButtonState = (text, attachmentsCount) => {
    return react.use$(combinedStore.combinedComputed$.sendButtonState(text, attachmentsCount));
  };
  const sendNextQueuedMessage = index.useEventCallback(async () => {
    const nextMessage = queueStore.queueActions.dequeuePendingMessage();
    if (!nextMessage) return;
    console.log(`Sending queued message: "${nextMessage.content}"`);
    try {
      let chatId = currentChat?.id;
      if (!chatId) {
        if (onCreateNewChat) {
          chatId = onCreateNewChat();
        } else {
          console.warn("No current chat available and no onCreateNewChat provided");
          return;
        }
      }
      const userMessage = {
        id: index_browser.nanoid(),
        content: nextMessage.content,
        role: core.Role.User,
        timestamp: (/* @__PURE__ */ new Date()).toISOString(),
        createdAt: (/* @__PURE__ */ new Date()).toISOString(),
        version: 1,
        isStreaming: false,
        status: core.Status.Pending,
        retryCount: 0,
        maxRetries: 3,
        abortController: new AbortController(),
        attachments: nextMessage.attachments
      };
      messageStore.messageActions.addMessage(userMessage);
      if (onSendMessage && chatId) {
        concurrencyStore.concurrencyActions.incrementActiveSessions();
        queueStore.queueActions.enqueueMessage(userMessage.id, "sendingQueue");
        try {
          const validAttachments = nextMessage.attachments?.filter((att) => att.uploadStatus === "completed" || att.uploadStatus === void 0).map((att) => ({ ...att, url: att.url }));
          await onSendMessage(
            nextMessage.content,
            chatId,
            validAttachments && validAttachments.length > 0 ? validAttachments : void 0,
            nextMessage.modelId,
            userMessage.id
          );
          queueStore.queueActions.dequeueMessage(userMessage.id, "sendingQueue");
        } catch (error) {
          queueStore.queueActions.dequeueMessage(userMessage.id, "sendingQueue");
          queueStore.queueActions.enqueueMessage(userMessage.id, "failedQueue");
          messageStore.messageActions.updateMessage(userMessage.id, {
            status: core.Status.Failed,
            error: {
              message: error instanceof Error ? error.message : "Failed to send message",
              timestamp: (/* @__PURE__ */ new Date()).toISOString()
            }
          });
          throw error;
        } finally {
          concurrencyStore.concurrencyActions.decrementActiveSessions();
        }
      }
    } catch (error) {
      console.error("Send queued message failed:", error);
    }
  });
  React.useEffect(() => {
    if (!streamingStatus.isStreaming && hasPendingMessages) {
      const timer = setTimeout(() => {
        sendNextQueuedMessage();
      }, 500);
      return () => clearTimeout(timer);
    }
  }, [streamingStatus.isStreaming, hasPendingMessages, sendNextQueuedMessage]);
  React.useEffect(() => {
    return () => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
    };
  }, []);
  const sendJumpQueueMessage = index.useEventCallback(async (messageId) => {
    const pendingMessages = queueStore.queueComputed$.sortedPendingMessages.peek();
    const jumpMessage = pendingMessages.find((msg) => msg.id === messageId);
    if (!jumpMessage) {
      console.error(`Jump queue message not found with ID: ${messageId}`);
      return;
    }
    console.log(`🚀 Sending jump queue message: "${jumpMessage.content}"`);
    queueStore.queueActions.removePendingMessage(messageId);
    try {
      let chatId = currentChat?.id;
      if (!chatId) {
        if (onCreateNewChat) {
          chatId = onCreateNewChat();
        } else {
          console.warn("No current chat available and no onCreateNewChat provided");
          return;
        }
      }
      const userMessage = {
        id: index_browser.nanoid(),
        content: jumpMessage.content,
        role: core.Role.User,
        timestamp: (/* @__PURE__ */ new Date()).toISOString(),
        createdAt: (/* @__PURE__ */ new Date()).toISOString(),
        version: 1,
        isStreaming: false,
        status: core.Status.Pending,
        retryCount: 0,
        maxRetries: 3,
        abortController: new AbortController(),
        attachments: jumpMessage.attachments
      };
      messageStore.messageActions.addMessage(userMessage);
      if (onSendMessage && chatId) {
        concurrencyStore.concurrencyActions.incrementActiveSessions();
        queueStore.queueActions.enqueueMessage(userMessage.id, "sendingQueue");
        try {
          const validAttachments = jumpMessage.attachments?.filter(
            (att) => att.uploadStatus === "completed" || att.uploadStatus === void 0
          ).map((att) => ({ ...att, url: att.url }));
          await onSendMessage(
            jumpMessage.content,
            chatId,
            validAttachments && validAttachments.length > 0 ? validAttachments : void 0,
            jumpMessage.modelId,
            userMessage.id
          );
          queueStore.queueActions.dequeueMessage(userMessage.id, "sendingQueue");
        } catch (error) {
          queueStore.queueActions.dequeueMessage(userMessage.id, "sendingQueue");
          queueStore.queueActions.enqueueMessage(userMessage.id, "failedQueue");
          messageStore.messageActions.updateMessage(userMessage.id, {
            status: core.Status.Failed,
            error: {
              message: error instanceof Error ? error.message : "Failed to send jump queue message",
              timestamp: (/* @__PURE__ */ new Date()).toISOString()
            }
          });
          throw error;
        } finally {
          concurrencyStore.concurrencyActions.decrementActiveSessions();
        }
      }
    } catch (error) {
      console.error("Send jump queue message failed:", error);
    }
  });
  const handleStopStreaming = index.useEventCallback(
    () => {
      if (streamingStatus.isStreaming && streamingStatus.currentMessageId) {
        messageStore.messageActions.cancelStreamingMessage(streamingStatus.currentMessageId);
        streamingStore.streamingActions.stopStreaming();
      }
      const pendingMessages = queueStore.queueComputed$.sortedPendingMessages.peek();
      const combinedContent = pendingMessages.map((msg) => msg.content).join("\n");
      const allAttachments = [];
      pendingMessages.forEach((msg) => {
        if (msg.attachments && msg.attachments.length > 0) {
          allAttachments.push(...msg.attachments);
        }
      });
      const uniqueAttachments = allAttachments.filter((attachment, index2, arr) => {
        return arr.findIndex(
          (a) => a.id === attachment.id || a.url && attachment.url && a.url === attachment.url
        ) === index2;
      });
      queueStore.queueActions.clearAllQueues();
      return {
        combinedAttachments: uniqueAttachments,
        combinedContent
      };
    }
  );
  return {
    // 状态
    canSendMessage,
    canSendNewMessage,
    streamingStatus,
    isSending,
    hasPendingMessages,
    // 方法
    handleSendMessage,
    handleStopStreaming,
    getSendButtonState,
    checkUnuploadedFiles,
    sendNextQueuedMessage,
    sendJumpQueueMessage,
    addMessageToQueue
  };
}
exports.useMessageSending = useMessageSending;
//# sourceMappingURL=use-message-sending.cjs.map
