import { useCallback, useEffect, useRef, useState, useMemo } from "react";
import { ChatMessage, MessageBlock, MessagesState, MessagesActions, SystemPushState, ChatConfig } from "./types";
import { fetchMessages, sendMessage, retryMessage } from "./api";
import { uid } from "./utils";

const POLLING_INTERVAL = 10000; // 10秒轮询一次
const PAGE_SIZE = 20;

interface UseMessagesProps {
  config: ChatConfig;
  onMessagesUpdate?: (shouldScroll: boolean) => void;
}

export function useMessages({ config, onMessagesUpdate }: UseMessagesProps): [MessagesState, MessagesActions, SystemPushState] {
  // 消息状态
  const [displayMessages, setDisplayMessages] = useState<ChatMessage[]>([]);
  const [latestMessages, setLatestMessages] = useState<ChatMessage[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<Error | null>(null);
  const [hasMore, setHasMore] = useState(false);
  const [offset, setOffset] = useState(0);
  const [totalCount, setTotalCount] = useState(0);

  // 系统推送状态
  const [systemPush, setSystemPush] = useState(true);
  const systemPushDisabledTimeRef = useRef<number | null>(null);

  // 状态引用
  const configRef = useRef(config);
  const isInitialLoadRef = useRef(true);
  const timeoutIdRef = useRef<NodeJS.Timeout | null>(null);
  const isPollingRef = useRef(false);
  const isViewingHistoryRef = useRef(false);
  const prevTotalCountRef = useRef(totalCount);

  // 过滤消息
  const filterMessages = useCallback((messages: ChatMessage[]) => {
    if (systemPush || !systemPushDisabledTimeRef.current) {
      return messages;
    }

    // 系统推送关闭时，只显示关闭前的系统消息和所有非系统消息
    return messages.filter(msg => 
      msg.role !== 'system' || 
      msg.createdAt <= systemPushDisabledTimeRef.current!
    );
  }, [systemPush]);

  // 合并和去重消息
  const mergeMessages = useCallback((oldMessages: ChatMessage[], newMessages: ChatMessage[]) => {
    const messageMap = new Map<string, ChatMessage>();
    
    // 使用 Map 自动去重，后面的会覆盖前面的
    [...oldMessages, ...newMessages].forEach(msg => {
      messageMap.set(msg.id, msg);
    });

    // 转回数组并按 id 排序
    const merged = Array.from(messageMap.values())
      .sort((a, b) => Number(a.id) - Number(b.id));

    // 过滤系统消息
    return filterMessages(merged);
  }, [filterMessages]);

  // 更新 config 引用
  useEffect(() => {
    configRef.current = config;
  }, [config]);

  // 监听总消息数变化
  useEffect(() => {
    if (!isViewingHistoryRef.current && totalCount !== prevTotalCountRef.current) {
      // 有新消息，需要滚动
      onMessagesUpdate?.(true);
    }
    prevTotalCountRef.current = totalCount;
  }, [totalCount, onMessagesUpdate]);

  // 获取最新消息
  const updateMessages = useCallback(async (showLoading: boolean = false) => {
    try {
      if (showLoading) {
        setIsLoading(true);
      }

      const response = await fetchMessages(configRef.current, 0, PAGE_SIZE);
      const filteredMessages = filterMessages(response.messages);
      
      setLatestMessages(response.messages); // 保存完整的消息列表
      if (!isViewingHistoryRef.current) {
        setDisplayMessages(filteredMessages); // 显示过滤后的消息
      }
      setTotalCount(response.totalCount);
      setHasMore(response.hasMore);
      setOffset(PAGE_SIZE);
    } catch (err) {
      console.error("获取消息失败:", err);
      setError(err instanceof Error ? err : new Error("获取消息失败"));
    } finally {
      if (showLoading) {
        setIsLoading(false);
      }
    }
  }, [filterMessages]);

  // 加载更多历史消息
  const loadMoreMessages = useCallback(async () => {
    if (isLoading || !hasMore) return;

    try {
      isViewingHistoryRef.current = true;
      setIsLoading(true);
      
      const response = await fetchMessages(configRef.current, offset, PAGE_SIZE);
      
      // 合并并去重消息
      setDisplayMessages(prev => mergeMessages(prev, response.messages));
      setHasMore(response.hasMore);
      setOffset(prev => prev + PAGE_SIZE);
      setTotalCount(response.totalCount);
    } catch (err) {
      console.error("加载历史消息失败:", err);
      setError(err instanceof Error ? err : new Error("加载历史消息失败"));
    } finally {
      setIsLoading(false);
    }
  }, [offset, hasMore, isLoading, mergeMessages]);

  // 返回最新消息
  const backToLatest = useCallback(async () => {
    isViewingHistoryRef.current = false;
    setDisplayMessages(filterMessages(latestMessages));
    onMessagesUpdate?.(true);
  }, [latestMessages, filterMessages, onMessagesUpdate]);

  // 发送消息
  const handleSendMessage = useCallback(async (blocks: MessageBlock[], videoId?: string) => {
    setIsLoading(true);
    setError(null);
    
    // 暂停轮询
    if (timeoutIdRef.current) {
      clearTimeout(timeoutIdRef.current);
    }
    isPollingRef.current = true; // 设置轮询标志，防止其他轮询启动
    
    try {
      // 立即添加用户消息（临时显示）
      const userMessage: ChatMessage = {
        id: Date.now().toString(),
        role: "user",
        createdAt: Date.now(),
        blocks,
        chatType: 'chat',
        status: 'pending',
      };

      // 无论是否在查看历史，发送消息后都切换到最新视图
      isViewingHistoryRef.current = false;
      setDisplayMessages(prev => {
        const newMessages = mergeMessages(prev, [userMessage]);
        // 在 setState 的回调中触发滚动，确保消息已更新到界面
        setTimeout(() => onMessagesUpdate?.(true), 0);
        return newMessages;
      });

      // 发送到服务器
      await sendMessage(blocks, configRef.current, videoId);
      
      // 立即获取最新的消息列表
      await updateMessages(false);
      onMessagesUpdate?.(true);
    } catch (err) {
      console.error("发送消息失败:", err);
      setError(err instanceof Error ? err : new Error("发送消息失败"));
    } finally {
      setIsLoading(false);
      
      // 恢复轮询
      if (systemPush) {
        isPollingRef.current = false;
        // 延迟一个轮询间隔后再开始轮询
        timeoutIdRef.current = setTimeout(() => {
          poll();
        }, POLLING_INTERVAL);
      }
    }
  }, [updateMessages, mergeMessages]);

  // 重试消息
  const handleRetryMessage = useCallback(async (messageId: string) => {
    setIsLoading(true);
    setError(null);
    
    try {
      // 重试时切换到最新视图
      isViewingHistoryRef.current = false;
      await retryMessage(messageId, configRef.current);
      await updateMessages(false);
    } catch (err) {
      console.error("重试消息失败:", err);
      setError(err instanceof Error ? err : new Error("重试消息失败"));
    } finally {
      setIsLoading(false);
    }
  }, [updateMessages]);

  // 清空消息
  const handleClearMessages = useCallback(() => {
    setDisplayMessages([]);
    setLatestMessages([]);
    setHasMore(false);
    setOffset(0);
    setTotalCount(0);
  }, []);

  // 系统推送开关
  const toggleSystemPush = useCallback(() => {
    setSystemPush(prev => {
      if (prev) {
        // 关闭系统推送时，记录当前时间
        systemPushDisabledTimeRef.current = Date.now();
      } else {
        // 开启系统推送时，清除时间记录并更新显示
        systemPushDisabledTimeRef.current = null;
        // 立即更新显示的消息
        setDisplayMessages(filterMessages(latestMessages));
      }
      return !prev;
    });
  }, [latestMessages, filterMessages]);

  // 定义轮询函数
  const poll = useCallback(async () => {
    if (isPollingRef.current) return;
    
    try {
      isPollingRef.current = true;
      await updateMessages(false);
    } finally {
      isPollingRef.current = false;
      if (systemPush) {
        timeoutIdRef.current = setTimeout(poll, POLLING_INTERVAL);
      }
    }
  }, [systemPush, updateMessages]);

  // 轮询获取最新消息
  useEffect(() => {
    if (!systemPush) return;

    poll();

    return () => {
      if (timeoutIdRef.current) {
        clearTimeout(timeoutIdRef.current);
      }
    };
  }, [systemPush, poll]);

  // 初始加载
  useEffect(() => {
    if (isInitialLoadRef.current) {
      isInitialLoadRef.current = false;
      updateMessages(true);
    }
  }, [updateMessages]);

  // 监听 消息列表中是否存在 pending 状态的消息，有的话 将 loading 置为 true
  useEffect(() => {
    if (displayMessages.some(msg => msg.status === 'pending')) {
      setIsLoading(true);
    } else {
      setIsLoading(false);
    }
  }, [displayMessages]);

  return [
    { 
      messages: displayMessages, 
      isLoading, 
      error, 
      hasMore, 
      loadMoreMessages,
      backToLatest,
      isViewingHistory: isViewingHistoryRef.current 
    },
    { 
      sendMessage: handleSendMessage, 
      clearMessages: handleClearMessages, 
      retryMessage: handleRetryMessage 
    },
    { 
      enabled: systemPush, 
      toggle: toggleSystemPush 
    }
  ];
}