/**
 * 群组状态 Zustand Store
 */

import { create } from 'zustand';
import type {
  GroupResponse,
  GroupMemberResponse,
} from '../../types/dto';
import { CacheEntry, createCacheEntry, isCacheExpired, DEFAULT_TTL } from '../utils/cache';

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

export interface GroupManagerState {
  // 群组列表缓存
  groupsListEntry: CacheEntry<GroupResponse[]> | null;

  // 群组详情缓存
  groupsMap: Map<string, CacheEntry<GroupResponse>>;

  // 群组成员缓存 (key: members:groupId:page:pageSize)
  membersMap: Map<string, CacheEntry<GroupMemberResponse[]>>;

  // 加载状态
  isLoadingGroups: boolean;
  loadingGroupIds: Set<string>;
  loadingMemberKeys: Set<string>;

  // 待处理请求（去重）
  pendingRequests: Map<string, Promise<any>>;
}

export interface GroupManagerActions {
  // 获取状态
  getGroupsList: () => GroupResponse[] | null;
  getGroup: (groupId: string) => GroupResponse | null;
  getMembers: (groupId: string, page?: number, pageSize?: number) => GroupMemberResponse[] | null;
  isGroupsListExpired: () => boolean;
  isGroupExpired: (groupId: string) => boolean;
  isMembersExpired: (groupId: string, page?: number, pageSize?: number) => boolean;
  isLoadingGroup: (groupId: string) => boolean;
  isLoadingMembers: (groupId: string, page?: number, pageSize?: number) => boolean;

  // 设置状态
  setGroupsList: (groups: GroupResponse[]) => void;
  setGroupsListEntry: (entry: CacheEntry<GroupResponse[]>) => void;
  setGroup: (groupId: string, group: GroupResponse) => void;
  setMembers: (groupId: string, members: GroupMemberResponse[], page?: number, pageSize?: number) => void;
  setLoadingGroups: (loading: boolean) => void;
  setLoadingGroup: (groupId: string, loading: boolean) => void;
  setLoadingMembers: (groupId: string, loading: boolean, page?: number, pageSize?: number) => void;

  // 缓存管理
  invalidateGroupsList: () => void;
  invalidateGroup: (groupId: string) => void;
  invalidateMembers: (groupId: string) => void;
  invalidateAll: () => void;

  // 请求去重
  getPendingRequest: <T>(key: string) => Promise<T> | undefined;
  setPendingRequest: <T>(key: string, request: Promise<T>) => void;
  deletePendingRequest: (key: string) => void;
  clearPendingRequests: () => void;

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

// ==================== 辅助函数 ====================

function buildMembersKey(groupId: string, page: number = 1, pageSize: number = 20): string {
  return `members:${groupId}:${page}:${pageSize}`;
}

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

const initialState: GroupManagerState = {
  groupsListEntry: null,
  groupsMap: new Map(),
  membersMap: new Map(),
  isLoadingGroups: false,
  loadingGroupIds: new Set(),
  loadingMemberKeys: new Set(),
  pendingRequests: new Map(),
};

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

export type GroupManagerStore = GroupManagerState & GroupManagerActions;

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

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

  getGroupsList: () => {
    const entry = get().groupsListEntry;
    if (!entry) return null;
    if (isCacheExpired(entry)) return null;
    return entry.data;
  },

  getGroup: (groupId: string) => {
    const entry = get().groupsMap.get(groupId);
    if (!entry) return null;
    if (isCacheExpired(entry)) return null;
    return entry.data;
  },

  getMembers: (groupId: string, page = 1, pageSize = 20) => {
    const key = buildMembersKey(groupId, page, pageSize);
    const entry = get().membersMap.get(key);
    if (!entry) return null;
    if (isCacheExpired(entry)) return null;
    return entry.data;
  },

  isGroupsListExpired: () => {
    const entry = get().groupsListEntry;
    if (!entry) return true;
    return isCacheExpired(entry);
  },

  isGroupExpired: (groupId: string) => {
    const entry = get().groupsMap.get(groupId);
    if (!entry) return true;
    return isCacheExpired(entry);
  },

  isMembersExpired: (groupId: string, page = 1, pageSize = 20) => {
    const key = buildMembersKey(groupId, page, pageSize);
    const entry = get().membersMap.get(key);
    if (!entry) return true;
    return isCacheExpired(entry);
  },

  isLoadingGroup: (groupId: string) => {
    return get().loadingGroupIds.has(groupId);
  },

  isLoadingMembers: (groupId: string, page = 1, pageSize = 20) => {
    const key = buildMembersKey(groupId, page, pageSize);
    return get().loadingMemberKeys.has(key);
  },

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

  setGroupsList: (groups: GroupResponse[]) => {
    set({
      groupsListEntry: createCacheEntry(groups, DEFAULT_TTL.GROUP),
    });
  },

  setGroupsListEntry: (entry: CacheEntry<GroupResponse[]>) => {
    set({ groupsListEntry: entry });
  },

  setGroup: (groupId: string, group: GroupResponse) => {
    set(state => {
      const newGroupsMap = new Map(state.groupsMap);
      newGroupsMap.set(groupId, createCacheEntry(group, DEFAULT_TTL.GROUP));
      return { groupsMap: newGroupsMap };
    });
  },

  setMembers: (groupId: string, members: GroupMemberResponse[], page = 1, pageSize = 20) => {
    const key = buildMembersKey(groupId, page, pageSize);
    set(state => {
      const newMembersMap = new Map(state.membersMap);
      newMembersMap.set(key, createCacheEntry(members, DEFAULT_TTL.GROUP_MEMBERS));
      return { membersMap: newMembersMap };
    });
  },

  setLoadingGroups: (loading: boolean) => {
    set({ isLoadingGroups: loading });
  },

  setLoadingGroup: (groupId: string, loading: boolean) => {
    set(state => {
      const newLoadingGroupIds = new Set(state.loadingGroupIds);
      if (loading) {
        newLoadingGroupIds.add(groupId);
      } else {
        newLoadingGroupIds.delete(groupId);
      }
      return { loadingGroupIds: newLoadingGroupIds };
    });
  },

  setLoadingMembers: (groupId: string, loading: boolean, page = 1, pageSize = 20) => {
    const key = buildMembersKey(groupId, page, pageSize);
    set(state => {
      const newLoadingMemberKeys = new Set(state.loadingMemberKeys);
      if (loading) {
        newLoadingMemberKeys.add(key);
      } else {
        newLoadingMemberKeys.delete(key);
      }
      return { loadingMemberKeys: newLoadingMemberKeys };
    });
  },

  // ==================== 缓存管理 ====================

  invalidateGroupsList: () => {
    set({ groupsListEntry: null });
  },

  invalidateGroup: (groupId: string) => {
    set(state => {
      const newGroupsMap = new Map(state.groupsMap);
      newGroupsMap.delete(groupId);

      // 删除相关的成员缓存
      const newMembersMap = new Map(state.membersMap);
      for (const key of newMembersMap.keys()) {
        if (key.startsWith(`members:${groupId}:`)) {
          newMembersMap.delete(key);
        }
      }

      return { groupsMap: newGroupsMap, membersMap: newMembersMap };
    });
  },

  invalidateMembers: (groupId: string) => {
    set(state => {
      const newMembersMap = new Map(state.membersMap);
      for (const key of newMembersMap.keys()) {
        if (key.startsWith(`members:${groupId}:`)) {
          newMembersMap.delete(key);
        }
      }
      return { membersMap: newMembersMap };
    });
  },

  invalidateAll: () => {
    set({
      groupsListEntry: null,
      groupsMap: new Map(),
      membersMap: new Map(),
      pendingRequests: new Map(),
    });
  },

  // ==================== 请求去重 ====================

  getPendingRequest: <T>(key: string) => {
    return get().pendingRequests.get(key) as Promise<T> | undefined;
  },

  setPendingRequest: <T>(key: string, request: Promise<T>) => {
    set(state => {
      const newPendingRequests = new Map(state.pendingRequests);
      newPendingRequests.set(key, request);
      return { pendingRequests: newPendingRequests };
    });
  },

  deletePendingRequest: (key: string) => {
    set(state => {
      const newPendingRequests = new Map(state.pendingRequests);
      newPendingRequests.delete(key);
      return { pendingRequests: newPendingRequests };
    });
  },

  clearPendingRequests: () => {
    set({ pendingRequests: new Map() });
  },

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

  reset: () => {
    set({
      ...initialState,
      groupsMap: new Map(),
      membersMap: new Map(),
      loadingGroupIds: new Set(),
      loadingMemberKeys: new Set(),
      pendingRequests: new Map(),
    });
  },
}));