import {
  authenticateResponseInterceptor,
  defaultResponseInterceptor,
  errorMessageResponseInterceptor,
  RequestClient,
} from '@vben/request';
import { preferences } from '@vben/preferences';
import { useAccessStore } from '@vben/stores';

import { message } from 'ant-design-vue';

import { requestClient } from '#/api/request';
import { useAuthStore } from '#/store';
import { refreshTokenApi } from '#/api/core';

const imApiURL = import.meta.env.VITE_IM_API_URL || '/im-api';

const imRequestClient = new RequestClient({
  baseURL: imApiURL,
  responseReturn: 'data',
});

function formatToken(token: null | string) {
  return token ? `Bearer ${token}` : null;
}

imRequestClient.addRequestInterceptor({
  fulfilled: async (config) => {
    const accessStore = useAccessStore();
    config.headers.Authorization = formatToken(accessStore.accessToken);
    return config;
  },
});

imRequestClient.addResponseInterceptor(
  defaultResponseInterceptor({
    codeField: 'code',
    dataField: 'data',
    successCode: 0,
  }),
);

imRequestClient.addResponseInterceptor(
  authenticateResponseInterceptor({
    client: imRequestClient,
    doReAuthenticate: async () => {
      const accessStore = useAccessStore();
      const authStore = useAuthStore();
      accessStore.setAccessToken(null);
      if (
        preferences.app.loginExpiredMode === 'modal' &&
        accessStore.isAccessChecked
      ) {
        accessStore.setLoginExpired(true);
      } else {
        await authStore.logout();
      }
    },
    doRefreshToken: async () => {
      const accessStore = useAccessStore();
      const resp = await refreshTokenApi();
      const newToken = resp.data;
      accessStore.setAccessToken(newToken);
      return newToken;
    },
    enableRefreshToken: preferences.app.enableRefreshToken,
    formatToken,
  }),
);

imRequestClient.addResponseInterceptor(
  errorMessageResponseInterceptor((msg: string, error) => {
    const responseData = error?.response?.data ?? {};
    const errorMessage = responseData?.error ?? responseData?.message ?? '';
    message.error(errorMessage || msg);
  }),
);

export namespace ImApi {
  export interface Conversation {
    id: string;
    type: number;
    lastMessageContent: null | string;
    lastMessageAt: null | string;
    unreadCount: number;
    groupName: null | string;
    groupAvatar: null | string;
    otherUserId: null | string;
    otherUserName: null | string;
    otherUserAvatar: null | string;
  }

  export interface Message {
    id: string;
    conversationId: string;
    senderId: string;
    senderName: string;
    senderAvatar: null | string;
    contentType: number;
    content: string;
    metadata: MessageMetadata | null;
    replyToId: null | string;
    createdAt: string;
  }

  export interface MessageMetadata {
    fileName?: null | string;
    fileSize?: null | number;
    fileUrl?: null | string;
    imageUrl?: null | string;
    imageWidth?: null | number;
    imageHeight?: null | number;
    emojiCode?: null | string;
  }

  export interface MessageHistory {
    messages: Message[];
    hasMore: boolean;
  }

  export interface UnreadCounts {
    items: { conversationId: string; unreadCount: number }[];
    total: number;
  }

  export interface GroupInfo {
    id: string;
    conversationId: string;
    name: string;
    avatar: null | string;
    description: null | string;
    ownerId: string;
    memberCount: number;
    createdAt: string;
  }

  export interface GroupMember {
    userId: string;
    userName: string;
    avatar: null | string;
    role: number;
    joinedAt: string;
  }

  export interface User {
    id: string;
    username: string;
    email: string;
    isActive: boolean;
    createdAt: string;
    roles: string[];
  }
}

export async function getConversationsApi() {
  return imRequestClient.get<ImApi.Conversation[]>('/conversations');
}

export async function getMessageHistoryApi(
  conversationId: string,
  beforeId?: string,
  limit: number = 50,
) {
  const params: Record<string, any> = { limit };
  if (beforeId) params.beforeId = beforeId;
  return imRequestClient.get<ImApi.MessageHistory>(
    `/conversations/${conversationId}/messages`,
    { params },
  );
}

export async function getUnreadCountApi() {
  return imRequestClient.get<ImApi.UnreadCounts>('/unread');
}

export async function createGroupApi(data: {
  avatar?: string;
  description?: string;
  memberUserIds: string[];
  name: string;
}) {
  return imRequestClient.post<ImApi.GroupInfo>('/groups', data);
}

export async function updateGroupApi(
  groupId: string,
  data: { avatar?: string; description?: string; name?: string },
) {
  return imRequestClient.put<ImApi.GroupInfo>(`/groups/${groupId}`, data);
}

export async function deleteGroupApi(groupId: string) {
  return imRequestClient.delete(`/groups/${groupId}`);
}

export async function addGroupMemberApi(groupId: string, userIds: string[]) {
  return imRequestClient.post(`/groups/${groupId}/members`, { userIds });
}

export async function removeGroupMemberApi(groupId: string, userId: string) {
  return imRequestClient.delete(`/groups/${groupId}/members/${userId}`);
}

export async function getGroupMembersApi(groupId: string) {
  return imRequestClient.get<ImApi.GroupMember[]>(`/groups/${groupId}/members`);
}

// 用户搜索 — 直连 rag-backend
export async function searchUsersApi(search?: string) {
  const params: Record<string, any> = {};
  if (search) params.search = search;
  return requestClient.get<ImApi.User[]>('/users', { params });
}

// 创建或获取私聊会话 — IM 后端
export async function createPrivateConversationApi(targetUserId: string) {
  return imRequestClient.post<ImApi.Conversation>('/conversations/private', {
    targetUserId,
  });
}
