/**
 * 消息状态 Zustand Store
 * 使用 zustand 进行状态管理，提供响应式状态更新
 *
 * 重构说明：
 * - 移除了 MessageStateManager 包装层
 * - 直接使用 zustand store 进行状态管理
 * - 移除了 SubscriptionManager，改用 Zustand selector 进行响应式订阅
 */

import { create } from 'zustand';
import AsyncStorage from '@react-native-async-storage/async-storage';
import type {
  ConversationResponse,
  MessageResponse,
} from '../../types/dto';

const LAST_SYSTEM_MESSAGE_AT_KEY = 'last_system_message_at';

// ==================== 状态接口 ====================

/**
 * 消息状态接口（不包含订阅者，订阅者单独管理）
 */
export interface MessageState {
  // 会话相关
  conversations: Map<string, ConversationResponse>;
  conversationList: ConversationResponse[];

  // 消息相关 - 按会话ID存储
  messagesMap: Map<string, MessageResponse[]>;

  // 未读数
  totalUnreadCount: number;
  systemUnreadCount: number;

  // 最后一条系统通知时间
  lastSystemMessageAt: string | null;

  // 连接状态
  isWSConnected: boolean;

  // 当前活动会话ID（用户正在查看的会话）
  currentConversationId: string | null;

  // 加载状态
  isLoadingConversations: boolean;
  loadingMessagesSet: Set<string>;

  // 初始化状态
  isInitialized: boolean;

  // 输入状态 - 按群组ID存储正在输入的用户ID列表
  typingUsersMap: Map<string, string[]>;

  // 当前用户的禁言状态 - 按群组ID存储
  mutedStatusMap: Map<string, boolean>;

  // 会话免打扰状态 - 按会话ID存储
  notificationMutedMap: Map<string, boolean>;
}

// ==================== Actions 接口 ====================

export interface MessageActions {
  // 获取状态
  getState: () => MessageState;
  getConversations: () => ConversationResponse[];
  getConversation: (conversationId: string) => ConversationResponse | null;
  getMessages: (conversationId: string) => MessageResponse[];
  getUnreadCount: () => { total: number; system: number };
  isConnected: () => boolean;
  isLoading: () => boolean;
  isLoadingMessages: (conversationId: string) => boolean;
  getTypingUsers: (groupId: string) => string[];
  isMuted: (groupId: string) => boolean;
  getActiveConversation: () => string | null;
  isNotificationMuted: (conversationId: string) => boolean;

  // 设置状态
  setConversations: (conversations: Map<string, ConversationResponse>) => void;
  updateConversation: (conversation: ConversationResponse) => void;
  removeConversation: (conversationId: string) => void;
  setMessages: (conversationId: string, messages: MessageResponse[]) => void;
  addMessage: (conversationId: string, message: MessageResponse) => void;
  updateMessage: (conversationId: string, messageId: string, updates: Partial<MessageResponse>) => void;
  setUnreadCount: (total: number, system: number) => void;
  setLastSystemMessageAt: (time: string | null) => void;
  setSSEConnected: (connected: boolean) => void;
  setCurrentConversation: (conversationId: string | null) => void;
  setLoading: (loading: boolean) => void;
  setLoadingMessages: (conversationId: string, loading: boolean) => void;
  setTypingUsers: (groupId: string, users: string[]) => void;
  setMutedStatus: (groupId: string, isMuted: boolean) => void;
  setNotificationMuted: (conversationId: string, notificationMuted: boolean) => void;
  setInitialized: (initialized: boolean) => void;

  // 重置
  reset: () => void;
}

// ==================== 初始状态 ====================

const initialState: MessageState = {
  conversations: new Map(),
  conversationList: [],
  messagesMap: new Map(),
  totalUnreadCount: 0,
  systemUnreadCount: 0,
  lastSystemMessageAt: null,
  isWSConnected: false,
  currentConversationId: null,
  isLoadingConversations: false,
  loadingMessagesSet: new Set(),
  isInitialized: false,
  typingUsersMap: new Map(),
  mutedStatusMap: new Map(),
  notificationMutedMap: new Map(),
};

// ==================== 工具函数 ====================

/**
 * 规范化会话ID
 */
export function normalizeConversationId(conversationId: string | number | null | undefined): string {
  return conversationId == null ? '' : String(conversationId);
}

/**
 * 更新会话列表排序
 * 排序规则：置顶优先，再按最后消息时间排序
 */
function sortConversationList(conversations: Map<string, ConversationResponse>): ConversationResponse[] {
  return Array.from(conversations.values()).sort((a, b) => {
    const aPinned = a.is_pinned ? 1 : 0;
    const bPinned = b.is_pinned ? 1 : 0;
    if (aPinned !== bPinned) {
      return bPinned - aPinned;
    }
    const aTime = new Date(a.last_message_at || a.updated_at || 0).getTime();
    const bTime = new Date(b.last_message_at || b.updated_at || 0).getTime();
    if (Number.isNaN(aTime) || Number.isNaN(bTime)) return 0;
    return bTime - aTime;
  });
}

/**
 * 按 message_id 合并消息并按 seq 排序
 */
export function mergeMessagesById(base: MessageResponse[], incoming: MessageResponse[]): MessageResponse[] {
  if (incoming.length === 0) return base;
  const merged = new Map<string, MessageResponse>();
  [...base, ...incoming].forEach(msg => {
    merged.set(String(msg.id), msg);
  });
  return Array.from(merged.values()).sort((a, b) => a.seq - b.seq);
}

// ==================== Store 创建 ====================

export type MessageStore = MessageState & MessageActions;

export const useMessageStore = create<MessageStore>((set, get) => ({
  // ==================== 初始状态 ====================
  ...initialState,

  // ==================== 获取状态 ====================

  getState: () => {
    const state = get();
    return {
      conversations: state.conversations,
      conversationList: state.conversationList,
      messagesMap: state.messagesMap,
      totalUnreadCount: state.totalUnreadCount,
      systemUnreadCount: state.systemUnreadCount,
      lastSystemMessageAt: state.lastSystemMessageAt,
      isWSConnected: state.isWSConnected,
      currentConversationId: state.currentConversationId,
      isLoadingConversations: state.isLoadingConversations,
      loadingMessagesSet: state.loadingMessagesSet,
      isInitialized: state.isInitialized,
      typingUsersMap: state.typingUsersMap,
      mutedStatusMap: state.mutedStatusMap,
      notificationMutedMap: state.notificationMutedMap,
    };
  },

  getConversations: () => {
    return get().conversationList;
  },

  getConversation: (conversationId: string) => {
    const normalizedId = normalizeConversationId(conversationId);
    return get().conversations.get(normalizedId) || null;
  },

  getMessages: (conversationId: string) => {
    const normalizedId = normalizeConversationId(conversationId);
    return get().messagesMap.get(normalizedId) || [];
  },

  getUnreadCount: () => {
    const state = get();
    return {
      total: state.totalUnreadCount,
      system: state.systemUnreadCount,
    };
  },

  isConnected: () => {
    return get().isWSConnected;
  },

  isLoading: () => {
    return get().isLoadingConversations;
  },

  isLoadingMessages: (conversationId: string) => {
    const normalizedId = normalizeConversationId(conversationId);
    return get().loadingMessagesSet.has(normalizedId);
  },

  getTypingUsers: (groupId: string) => {
    return get().typingUsersMap.get(groupId) || [];
  },

  isMuted: (groupId: string) => {
    return get().mutedStatusMap.get(groupId) || false;
  },

  getActiveConversation: () => {
    return get().currentConversationId;
  },

  isNotificationMuted: (conversationId: string) => {
    return get().notificationMutedMap.get(conversationId) || false;
  },

  // ==================== 设置状态 ====================

  setConversations: (conversations: Map<string, ConversationResponse>) => {
    const conversationList = sortConversationList(conversations);
    const notificationMutedMap = new Map<string, boolean>();
    conversations.forEach((conv, id) => {
      if (conv.notification_muted) {
        notificationMutedMap.set(id, true);
      }
    });
    set(state => ({
      conversations,
      conversationList,
      notificationMutedMap: new Map([...state.notificationMutedMap, ...notificationMutedMap]),
    }));
  },

  updateConversation: (conversation: ConversationResponse) => {
    const id = normalizeConversationId(conversation.id);
    set(state => {
      const newConversations = new Map(state.conversations);
      newConversations.set(id, { ...conversation, id });
      const conversationList = sortConversationList(newConversations);
      const newNotificationMutedMap = new Map(state.notificationMutedMap);
      if (conversation.notification_muted) {
        newNotificationMutedMap.set(id, true);
      } else {
        newNotificationMutedMap.delete(id);
      }
      return { conversations: newConversations, conversationList, notificationMutedMap: newNotificationMutedMap };
    });
  },

  removeConversation: (conversationId: string) => {
    const normalizedId = normalizeConversationId(conversationId);
    set(state => {
      const target = state.conversations.get(normalizedId);
      const removedUnread = target?.unread_count || 0;

      const newConversations = new Map(state.conversations);
      newConversations.delete(normalizedId);

      const newMessagesMap = new Map(state.messagesMap);
      newMessagesMap.delete(normalizedId);

      const newLoadingMessagesSet = new Set(state.loadingMessagesSet);
      newLoadingMessagesSet.delete(normalizedId);

      const newTotalUnreadCount = Math.max(0, state.totalUnreadCount - removedUnread);

      const newCurrentConversationId = state.currentConversationId === normalizedId
        ? null
        : state.currentConversationId;

      const conversationList = sortConversationList(newConversations);

      return {
        conversations: newConversations,
        conversationList,
        messagesMap: newMessagesMap,
        totalUnreadCount: newTotalUnreadCount,
        currentConversationId: newCurrentConversationId,
        loadingMessagesSet: newLoadingMessagesSet,
      };
    });
  },

  setMessages: (conversationId: string, messages: MessageResponse[]) => {
    const normalizedId = normalizeConversationId(conversationId);
    set(state => {
      const newMessagesMap = new Map(state.messagesMap);
      newMessagesMap.set(normalizedId, messages);
      return { messagesMap: newMessagesMap };
    });
  },

  addMessage: (conversationId: string, message: MessageResponse) => {
    const normalizedId = normalizeConversationId(conversationId);
    set(state => {
      const existing = state.messagesMap.get(normalizedId) || [];
      const exists = existing.some(m => String(m.id) === String(message.id));

      if (exists) {
        return state;
      }

      const updated = mergeMessagesById(existing, [message]);
      const newMessagesMap = new Map(state.messagesMap);
      newMessagesMap.set(normalizedId, updated);
      return { messagesMap: newMessagesMap };
    });
  },

  updateMessage: (conversationId: string, messageId: string, updates: Partial<MessageResponse>) => {
    const normalizedId = normalizeConversationId(conversationId);
    set(state => {
      const messages = state.messagesMap.get(normalizedId);
      if (!messages) return state;

      const updated = messages.map(m =>
        String(m.id) === String(messageId) ? { ...m, ...updates } : m
      );

      const newMessagesMap = new Map(state.messagesMap);
      newMessagesMap.set(normalizedId, updated);
      return { messagesMap: newMessagesMap };
    });
  },

  setUnreadCount: (total: number, system: number) => {
    set({ totalUnreadCount: total, systemUnreadCount: system });
  },

  setLastSystemMessageAt: (time: string | null) => {
    set({ lastSystemMessageAt: time });
    if (time) {
      AsyncStorage.setItem(LAST_SYSTEM_MESSAGE_AT_KEY, time).catch(() => {});
    } else {
      AsyncStorage.removeItem(LAST_SYSTEM_MESSAGE_AT_KEY).catch(() => {});
    }
  },

  setSSEConnected: (connected: boolean) => {
    set({ isWSConnected: connected });
  },

  setCurrentConversation: (conversationId: string | null) => {
    set({ currentConversationId: conversationId });
  },

  setLoading: (loading: boolean) => {
    set({ isLoadingConversations: loading });
  },

  setLoadingMessages: (conversationId: string, loading: boolean) => {
    const normalizedId = normalizeConversationId(conversationId);
    set(state => {
      const newLoadingMessagesSet = new Set(state.loadingMessagesSet);
      if (loading) {
        newLoadingMessagesSet.add(normalizedId);
      } else {
        newLoadingMessagesSet.delete(normalizedId);
      }
      return { loadingMessagesSet: newLoadingMessagesSet };
    });
  },

  setTypingUsers: (groupId: string, users: string[]) => {
    set(state => {
      const newTypingUsersMap = new Map(state.typingUsersMap);
      newTypingUsersMap.set(groupId, users);
      return { typingUsersMap: newTypingUsersMap };
    });
  },

  setMutedStatus: (groupId: string, isMuted: boolean) => {
    set(state => {
      const newMutedStatusMap = new Map(state.mutedStatusMap);
      newMutedStatusMap.set(groupId, isMuted);
      return { mutedStatusMap: newMutedStatusMap };
    });
  },

  setNotificationMuted: (conversationId: string, notificationMuted: boolean) => {
    set(state => {
      const newNotificationMutedMap = new Map(state.notificationMutedMap);
      newNotificationMutedMap.set(conversationId, notificationMuted);
      return { notificationMutedMap: newNotificationMutedMap };
    });
  },

  setInitialized: (initialized: boolean) => {
    set({ isInitialized: initialized });
  },

  // ==================== 重置 ====================

  reset: () => {
    set({
      ...initialState,
      conversations: new Map(),
      messagesMap: new Map(),
      loadingMessagesSet: new Set(),
      typingUsersMap: new Map(),
      mutedStatusMap: new Map(),
      notificationMutedMap: new Map(),
    });
    AsyncStorage.removeItem(LAST_SYSTEM_MESSAGE_AT_KEY).catch(() => {});
  },
}));

export async function loadPersistedLastSystemMessageAt(): Promise<void> {
  const time = await AsyncStorage.getItem(LAST_SYSTEM_MESSAGE_AT_KEY);
  if (time) {
    useMessageStore.setState({ lastSystemMessageAt: time });
  }
}

