import axios from 'axios'
import { ElMessage } from 'element-plus'
import router from '@/router'
import { isJwtExpired } from '@/utils/jwt'

const imClient = axios.create({
  baseURL: import.meta.env.VITE_IM_API_BASE_URL ?? '',
  timeout: 15000,
})

if (import.meta.env.DEV) {
  imClient.interceptors.request.use((config) => {
    console.debug('[tenant-platform][IM] request', {
      method: config.method?.toUpperCase(),
      url: config.baseURL ? `${config.baseURL}${config.url ?? ''}` : config.url,
      params: config.params,
    })
    return config
  })
  imClient.interceptors.response.use((res) => {
    console.debug('[tenant-platform][IM] response', {
      status: res.status,
      url: res.config.url,
    })
    return res
  })
}

imClient.interceptors.request.use((config) => {
  const token = localStorage.getItem('token')
  if (token && !isJwtExpired(token)) {
    config.headers.Authorization = `Bearer ${token}`
  } else if (token && isJwtExpired(token)) {
    localStorage.removeItem('token')
    if (router.currentRoute.value.path !== '/login') {
      router.push('/login?reason=' + encodeURIComponent('登录已失效，请重新登录'))
    }
    return Promise.reject(new Error('登录已失效，请重新登录'))
  }
  return config
})

imClient.interceptors.response.use(
  (res) => res,
  (error) => {
    const status = error.response?.status
    if (status === 401) {
      localStorage.removeItem('token')
      if (router.currentRoute.value.path !== '/login') {
        router.push('/login')
      }
      ElMessage.error('登录已失效，请重新登录')
      return Promise.reject(error)
    }
    if (status === 403) {
      localStorage.removeItem('token')
      if (router.currentRoute.value.path !== '/login') {
        router.push('/login?reason=' + encodeURIComponent('登录已失效，请重新登录'))
      }
      ElMessage.error(error.response?.data?.message ?? '登录已失效，请重新登录')
      return Promise.reject(error)
    }
    const msg = error.response?.data?.message ?? 'IM 请求失败'
    ElMessage.error(msg)
    return Promise.reject(error)
  },
)

export interface ImUser {
  id: string
  appKey: string
  userId: string
  nickname: string
  avatar?: string
  admin?: boolean
  status: 'ACTIVE' | 'BANNED'
  gender: 'UNKNOWN' | 'MALE' | 'FEMALE'
  createdAt: number
}

export interface ImProfile {
  id?: string
  appKey?: string
  userId: string
  nickname?: string | null
  avatar?: string | null
  gender?: 'UNKNOWN' | 'MALE' | 'FEMALE' | string | null
  status?: 'ACTIVE' | 'BANNED' | string | null
  createdAt?: number | null
}

export interface ImGroup {
  id: string
  appKey: string
  name: string
  creatorId: string
  groupType?: string | null
  memberIds: string
  adminIds: string
  announcement?: string | null
  createdAt: number
}

export interface ImMessage {
  id: string
  appKey: string
  fromUserId: string
  toId: string
  chatType: 'SINGLE' | 'GROUP'
  msgType: string
  content: string
  status: string
  mentionedUserIds?: string | null
  groupReadCount?: number | null
  createdAt: number
}

export interface PagedResult<T> {
  content: T[]
  totalElements: number
  totalPages: number
  size: number
  number: number
}

export interface ImStats {
  totalMessages: number
  totalUsers: number
  totalGroups: number
  todayMessages: number
}

export interface OperationLog {
  id: string
  appKey: string
  operatorId: string
  action: string
  resourceType: string
  resourceId?: string | null
  detail?: string | null
  summary?: string | null
  createdAt: number
}

export interface KeywordFilter {
  id: string
  appKey: string
  pattern: string
  replacement?: string | null
  action: 'REPLACE' | 'BLOCK'
  enabled: boolean
  createdAt: number
}

export interface GlobalMute {
  id: string
  appKey: string
  enabled: boolean
  createdAt: number
  updatedAt: number
}

export interface WebhookConfig {
  id: string
  appKey: string
  url: string
  secret?: string | null
  enabled: boolean
  createdAt: number
  consecutiveFailures?: number
  lastFailureAt?: number | null
}

export interface WebhookConfigForm {
  url: string
  secret?: string
  enabled?: boolean
}

export interface WebhookDelivery {
  id: string
  appKey: string
  callbackId: string
  callbackEvent: string
  url: string
  httpStatus: number
  responseBody?: string | null
  errorMessage?: string | null
  attempt: number
  success: boolean
  createdAt: number
}

export interface WebhookAlert {
  id: string
  appKey: string
  webhookId: string
  webhookUrl: string
  alertType: string
  description?: string | null
  acknowledged: boolean
  createdAt: number
  acknowledgedAt?: number | null
}

export interface GroupJoinRequest {
  id: string
  appKey: string
  groupId: string
  requesterId: string
  remark?: string | null
  status: 'PENDING' | 'ACCEPTED' | 'REJECTED'
  createdAt: number
  reviewedAt?: number | null
}

export const imAdminApi = {
  listUsers(appKey: string, page = 0, size = 20) {
    return imClient.get<{ data: PagedResult<ImUser> }>(
      '/api/im/admin/users', { params: { appKey, page, size } },
    )
  },

  updateUserStatus(appKey: string, userId: string, status: 'ACTIVE' | 'BANNED') {
    return imClient.put(`/api/im/admin/users/${encodeURIComponent(userId)}/status`, { status }, { params: { appKey } })
  },

  listGroups(appKey: string) {
    return imClient.get<{ data: ImGroup[] }>('/api/im/admin/groups', { params: { appKey } })
  },

  getStats(appKey: string) {
    return imClient.get<{ data: ImStats }>('/api/im/admin/stats', { params: { appKey } })
  },

  getOperationLogs(appKey: string, page = 0, size = 20) {
    return imClient.get<{ data: PagedResult<OperationLog> }>('/api/im/admin/operation-logs', {
      params: { appKey, page, size },
    })
  },

  listWebhooks(appKey: string) {
    return imClient.get<{ data: WebhookConfig[] }>('/api/im/admin/webhooks', {
      params: { appKey },
    })
  },

  createWebhook(appKey: string, form: WebhookConfigForm) {
    return imClient.post<{ data: WebhookConfig }>('/api/im/admin/webhooks', form, {
      params: { appKey },
    })
  },

  updateUser(
    appKey: string,
    userId: string,
    form: { nickname?: string; avatar?: string; gender?: string; status?: string; admin?: boolean },
  ) {
    return imClient.put<{ data: ImUser }>(
      `/api/im/admin/users/${encodeURIComponent(userId)}`,
      form,
      { params: { appKey } },
    )
  },

  generateUserSig(
    appKey: string,
    userId: string,
    form?: { expireSeconds?: number; userBuf?: string },
  ) {
    return imClient.post<{ data: { appKey: string; userId: string; userSig: string; issuedAt: number; expiresAt: number; userBuf?: string } }>(
      `/api/im/admin/users/${encodeURIComponent(userId)}/usersig`,
      form ?? {},
      { params: { appKey } },
    )
  },

  verifyUserSig(
    appKey: string,
    userId: string,
    userSig: string,
  ) {
    return imClient.post<{ data: { valid: boolean; appKey: string; userId: string; issuedAt: number; expiresAt: number; userBuf?: string } }>(
      `/api/im/admin/users/${encodeURIComponent(userId)}/usersig/verify`,
      { userSig },
      { params: { appKey } },
    )
  },

  updateWebhook(appKey: string, webhookId: string, form: WebhookConfigForm) {
    return imClient.put<{ data: WebhookConfig }>(`/api/im/admin/webhooks/${encodeURIComponent(webhookId)}`, form, {
      params: { appKey },
    })
  },

  deleteWebhook(appKey: string, webhookId: string) {
    return imClient.delete<{ data: null }>(`/api/im/admin/webhooks/${encodeURIComponent(webhookId)}`, {
      params: { appKey },
    })
  },

  listKeywordFilters(appKey: string) {
    return imClient.get<{ data: KeywordFilter[] }>('/api/im/admin/keyword-filters', {
      params: { appKey },
    })
  },

  createKeywordFilter(
    appKey: string,
    form: { pattern: string; replacement?: string; action: 'REPLACE' | 'BLOCK'; enabled: boolean },
  ) {
    return imClient.post<{ data: KeywordFilter }>('/api/im/admin/keyword-filters', form, {
      params: { appKey },
    })
  },

  updateKeywordFilter(
    appKey: string,
    filterId: string,
    form: { pattern: string; replacement?: string; action: 'REPLACE' | 'BLOCK'; enabled: boolean },
  ) {
    return imClient.put<{ data: KeywordFilter }>(`/api/im/admin/keyword-filters/${encodeURIComponent(filterId)}`, form, {
      params: { appKey },
    })
  },

  deleteKeywordFilter(appKey: string, filterId: string) {
    return imClient.delete<{ data: null }>(`/api/im/admin/keyword-filters/${encodeURIComponent(filterId)}`, {
      params: { appKey },
    })
  },

  getGlobalMute(appKey: string) {
    return imClient.get<{ data: GlobalMute }>('/api/im/admin/global-mute', {
      params: { appKey },
    })
  },

  setGlobalMute(appKey: string, enabled: boolean) {
    return imClient.put<{ data: GlobalMute }>('/api/im/admin/global-mute', null, {
      params: { appKey, enabled },
    })
  },

  listGroupMembers(appKey: string, groupId: string) {
    return imClient.get<{ data: ImUser[] }>(
      `/api/im/admin/groups/${encodeURIComponent(groupId)}/members`,
      { params: { appKey } },
    )
  },

  searchGroupMembers(appKey: string, groupId: string, keyword: string, size = 20) {
    return imClient.get<{ data: ImUser[] }>(
      `/api/im/admin/groups/${encodeURIComponent(groupId)}/members/search`,
      { params: { appKey, keyword, size } },
    )
  },

  addGroupMember(appKey: string, groupId: string, userId: string) {
    return imClient.post<{ data: ImGroup }>(
      `/api/im/admin/groups/${encodeURIComponent(groupId)}/members`,
      { userId },
      { params: { appKey } },
    )
  },

  removeGroupMember(appKey: string, groupId: string, userId: string) {
    return imClient.delete<{ data: ImGroup }>(
      `/api/im/admin/groups/${encodeURIComponent(groupId)}/members/${encodeURIComponent(userId)}`,
      { params: { appKey } },
    )
  },

  setGroupRole(appKey: string, groupId: string, userId: string, role: 'ADMIN' | 'MEMBER') {
    return imClient.post<{ data: ImGroup }>(
      `/api/im/admin/groups/${encodeURIComponent(groupId)}/roles`,
      { userId, role },
      { params: { appKey } },
    )
  },

  muteGroupMember(appKey: string, groupId: string, userId: string, minutes: number) {
    return imClient.post<{ data: ImGroup }>(
      `/api/im/admin/groups/${encodeURIComponent(groupId)}/mute`,
      { userId, minutes },
      { params: { appKey } },
    )
  },

  listGroupJoinRequests(appKey: string, groupId: string) {
    return imClient.get<{ data: GroupJoinRequest[] }>(
      `/api/im/admin/groups/${encodeURIComponent(groupId)}/join-requests`,
      { params: { appKey } },
    )
  },

  sendGroupJoinRequest(appKey: string, groupId: string, remark?: string) {
    return imClient.post<{ data: GroupJoinRequest }>(
      `/api/im/groups/${encodeURIComponent(groupId)}/join-requests`,
      null,
      {
        params: {
          appKey,
          ...(remark ? { remark } : {}),
        },
      },
    )
  },

  acceptGroupJoinRequest(appKey: string, groupId: string, requestId: string) {
    return imClient.post<{ data: GroupJoinRequest }>(
      `/api/im/admin/groups/${encodeURIComponent(groupId)}/join-requests/${encodeURIComponent(requestId)}/accept`,
      null,
      { params: { appKey } },
    )
  },

  rejectGroupJoinRequest(appKey: string, groupId: string, requestId: string) {
    return imClient.post<{ data: GroupJoinRequest }>(
      `/api/im/admin/groups/${encodeURIComponent(groupId)}/join-requests/${encodeURIComponent(requestId)}/reject`,
      null,
      { params: { appKey } },
    )
  },

  getMessages(
    appKey: string,
    userA: string,
    userB: string,
    page = 0,
    size = 20,
    filters?: {
      msgType?: string
      keyword?: string
      startTime?: string
      endTime?: string
    },
  ) {
    return imClient.get<{ data: PagedResult<ImMessage> }>('/api/im/admin/messages', {
      params: {
        appKey,
        userA,
        userB,
        page,
        size,
        ...(filters?.msgType ? { msgType: filters.msgType } : {}),
        ...(filters?.keyword ? { keyword: filters.keyword } : {}),
        ...(filters?.startTime ? { startTime: filters.startTime } : {}),
        ...(filters?.endTime ? { endTime: filters.endTime } : {}),
      },
    })
  },

  revokeMessage(appKey: string, messageId: string) {
    return imClient.post<{ data: ImMessage }>(
      `/api/im/admin/messages/${encodeURIComponent(messageId)}/revoke`,
      {},
      { params: { appKey } },
    )
  },

  dismissGroup(appKey: string, groupId: string) {
    return imClient.delete<{ data: null }>(`/api/im/admin/groups/${encodeURIComponent(groupId)}`, { params: { appKey } })
  },

  registerUser(
    appKey: string,
    userId: string,
    nickname?: string,
    avatar?: string,
    gender?: string,
    status?: string,
    admin?: boolean,
  ) {
    return imClient.post<{ data: ImUser }>(
      '/api/im/admin/users',
      {
        userId,
        nickname,
        avatar,
        ...(gender ? { gender } : {}),
        ...(status ? { status } : {}),
        ...(admin !== undefined ? { admin } : {}),
      },
      { params: { appKey } },
    )
  },

  createGroup(
    appKey: string,
    name: string,
    creatorId: string,
    memberIds: string[],
    groupType?: string,
    announcement?: string,
  ) {
    return imClient.post<{ data: ImGroup }>(
      '/api/im/admin/groups',
      {
        name,
        creatorId,
        memberIds,
        ...(groupType ? { groupType } : {}),
        ...(announcement ? { announcement } : {}),
      },
      { params: { appKey } },
    )
  },

  updateGroup(
    appKey: string,
    groupId: string,
    form: { name?: string; groupType?: string; announcement?: string },
  ) {
    return imClient.put<{ data: ImGroup }>(
      `/api/im/admin/groups/${encodeURIComponent(groupId)}`,
      form,
      { params: { appKey } },
    )
  },

  searchUsers(appKey: string, keyword: string, size = 20) {
    return imClient.get<{ data: ImUser[] }>(
      '/api/im/admin/users/search',
      { params: { appKey, keyword, size } },
    )
  },

  searchMessages(
    appKey: string,
    filters: {
      keyword?: string
      chatType?: string
      msgType?: string
      startTime?: string
      endTime?: string
      page?: number
      size?: number
    } = {},
  ) {
    return imClient.get<{ data: PagedResult<ImMessage> }>('/api/im/admin/messages/search', {
      params: {
        appKey,
        ...(filters.keyword ? { keyword: filters.keyword } : {}),
        ...(filters.chatType ? { chatType: filters.chatType } : {}),
        ...(filters.msgType ? { msgType: filters.msgType } : {}),
        ...(filters.startTime ? { startTime: filters.startTime } : {}),
        ...(filters.endTime ? { endTime: filters.endTime } : {}),
        page: filters.page ?? 0,
        size: filters.size ?? 20,
      },
    })
  },

  getProfile(appKey: string, userId: string) {
    return imClient.get<{ data: ImProfile }>(
      `/api/im/accounts/${encodeURIComponent(userId)}`,
      { params: { appKey } },
    )
  },

  updateProfile(appKey: string, userId: string, nickname?: string, avatar?: string, gender?: string) {
    return imClient.put<{ data: ImProfile }>(
      `/api/im/accounts/${encodeURIComponent(userId)}`,
      {},
      {
        params: {
          appKey,
          ...(nickname ? { nickname } : {}),
          ...(avatar ? { avatar } : {}),
          ...(gender ? { gender } : {}),
        },
      },
    )
  },

  transferGroupOwner(appKey: string, groupId: string, newOwnerId: string) {
    return imClient.post<{ data: ImGroup }>(
      `/api/im/admin/groups/${encodeURIComponent(groupId)}/owner`,
      { newOwnerId },
      { params: { appKey } },
    )
  },

  updateGroupAttributes(appKey: string, groupId: string, attributes: Record<string, unknown>) {
    return imClient.put<{ data: ImGroup }>(
      `/api/im/admin/groups/${encodeURIComponent(groupId)}/attributes`,
      { attributes },
      { params: { appKey } },
    )
  },

  removeGroupAttributes(appKey: string, groupId: string, keys: string[]) {
    return imClient.post<{ data: ImGroup }>(
      `/api/im/admin/groups/${encodeURIComponent(groupId)}/attributes/delete`,
      { keys },
      { params: { appKey } },
    )
  },

  getGroupReadReceipts(appKey: string, groupId: string, messageIds?: string[]) {
    return imClient.post<{ data: Array<{ messageId: string; readCount: number; readUserIds: string[] }> }>(
      `/api/im/admin/groups/${encodeURIComponent(groupId)}/read-receipts`,
      { messageIds },
      { params: { appKey } },
    )
  },

  queryUserState(appKey: string, userIds: string[]) {
    return imClient.get<{ data: Record<string, { online: boolean; lastSeenAt: number }> }>(
      '/api/im/admin/users/state',
      { params: { userIds: userIds.join(',') } },
    )
  },

  listWebhookDeliveries(
    appKey: string,
    params: { callbackEvent?: string; success?: boolean; page?: number; size?: number } = {},
  ) {
    return imClient.get<{ data: PagedResult<WebhookDelivery> }>('/api/im/admin/webhook-deliveries', {
      params: { appKey, ...params },
    })
  },

  listWebhookAlerts(
    appKey: string,
    params: { acknowledged?: boolean; page?: number; size?: number } = {},
  ) {
    return imClient.get<{ data: PagedResult<WebhookAlert> }>('/api/im/admin/webhook-alerts', {
      params: { appKey, ...params },
    })
  },

  acknowledgeWebhookAlert(appKey: string, alertId: string) {
    return imClient.post<{ data: WebhookAlert }>(
      `/api/im/admin/webhook-alerts/${encodeURIComponent(alertId)}/acknowledge`,
      null,
      { params: { appKey } },
    )
  },

  getWebhookHealth(appKey: string, webhookId: string) {
    return imClient.get<{
      data: {
        webhookId: string
        url: string
        enabled: boolean
        consecutiveFailures: number
        lastFailureAt: number | null
        unacknowledgedAlerts: number
      }
    }>(`/api/im/admin/webhooks/${encodeURIComponent(webhookId)}/health`, { params: { appKey } })
  },
}
