import adminClient from "./client"
import type { ApiResponse } from "../../types"
import type { AdminPluginLink, AdminPluginManageAction, AdminProvisionPlugin } from "./instances"
import type { MemberLevel } from "./membership"
import { listResult, pageResult, type PageResult } from "./response"

export type AgentTier = "yunqi" | "yunxiang" | "yunce" | "yunling" | "yunzun" | "yunguan"

export interface AdminUserMembership {
  user_id: number
  member_level_id: number | null
  member_level_locked: boolean
  agent_tier: AgentTier | null
  total_spent: number
  total_points: number
  available_points: number
  upgraded_at: string | null
  member_level: MemberLevel | null
}

export interface AdminUserRefundQuota {
  base_limit: number
  extra: number
  limit: number
  used: number
  remaining: number | null
  unlimited: boolean
  reset_at: string | null
}

export interface AdminUserInviteCodeQuota {
  current_code: string | null
  base_limit: number
  extra: number
  limit: number
  used: number
  remaining: number
}

export interface AdminUserInviteCodeItem {
  id: number
  code: string
  is_current: boolean
  source: string
  created_at: string
}

export interface AdminUserInviteCodeLogItem {
  id: number
  action: string
  count: number
  before_used: number
  after_used: number
  before_extra: number
  after_extra: number
  reason: string
  operator_id: number | null
  created_at: string
}

export interface AdminUserVerificationQuota {
  free_quota_per_user: number
  purchase_enabled: boolean
  price_cents: number
  free_used: number
  free_remaining: number
  paid_remaining: number
  paid_purchased: number
  paid_used: number
  remaining_total: number
  balance_cents: number
  can_submit: boolean
  can_purchase: boolean
}

export interface AdminUserVerificationRecordItem {
  id: number
  provider: string
  mode: string
  status: string
  provider_task_id: string | null
  real_name: string | null
  id_card_no: string | null
  id_card_front_image?: string | null
  id_card_back_image?: string | null
  id_card_face_image?: string | null
  reject_reason: string | null
  provider_response?: Record<string, unknown> | null
  material_expires_at?: string | null
  material_cleaned?: boolean
  verified_at: string | null
  rejected_at: string | null
  created_at: string
}

export interface AdminUserTicketItem {
  id: number
  ticket_no: string
  subject: string
  status: string
  priority: string
  department_name: string | null
  instance_id: number | null
  assignee_id: number | null
  admin_unread_count: number
  user_unread_count: number
  satisfaction_rating: number | null
  last_message_at: string | null
  closed_at: string | null
  created_at: string
}

export interface AdminUserDetailStats {
  instances_total: number
  instances_active: number
  instances_suspended: number
  orders_total: number
  orders_paid_amount: number
  balance_logs_total: number
  verification_records_total: number
  tickets_total: number
  tickets_open: number
  tickets_unread: number
}

export interface AdminUser {
  id: number
  email: string | null
  username: string
  phone: string | null
  real_name?: string | null
  id_card_no?: string | null
  real_name_full?: string | null
  id_card_no_full?: string | null
  id_card_front_image?: string | null
  id_card_back_image?: string | null
  id_card_face_image?: string | null
  id_card_verify_remark?: string | null
  id_card_verified?: string | null
  nickname: string | null
  avatar: string | null
  role: "user" | "admin" | "super_admin"
  status: "active" | "inactive" | "banned"
  is_email_verified: boolean
  is_phone_verified: boolean
  has_password: boolean
  balance: number
  full_refund_quota_extra: number
  full_refund_quota_reset_at: string | null
  last_login_at: string | null
  created_at: string
  membership?: AdminUserMembership | null
  refund_quota?: AdminUserRefundQuota | null
  invite_code_quota?: AdminUserInviteCodeQuota | null
  invite_codes?: AdminUserInviteCodeItem[]
  invite_code_logs?: AdminUserInviteCodeLogItem[]
  verification_quota?: AdminUserVerificationQuota | null
  verification_records?: AdminUserVerificationRecordItem[]
  tickets?: AdminUserTicketItem[]
  stats?: AdminUserDetailStats
}

export interface AdminUserInstance {
  id: number
  user_id: number
  order_id: number
  product_id: number
  product_name: string
  product_group_name: string | null
  status: string
  suspend_type: string | null
  hostname: string | null
  alias: string | null
  main_ip: string | null
  ssh_port: number | null
  upstream_id: number | null
  cloud_server_id: number | null
  cloud_server_name: string | null
  cloud_server_base_url: string | null
  upstream_console_url: string | null
  nat_acl_limit?: number | null
  ip_num?: number | null
  cycle: string
  unit_price: number
  next_renew_amount: number
  auto_renew: number
  expires_at: string | null
  created_at: string | null
  terminated_at: string | null
  provision_attempts: number
  last_provision_at: string | null
  provision_log: string | null
  provision_plugin?: AdminProvisionPlugin | null
  plugin_manage_actions?: AdminPluginManageAction[]
  plugin_links?: AdminPluginLink[]
}

export interface AdminUserInstanceDetail extends AdminUserInstance {
  user: {
    id: number
    username: string | null
    nickname: string | null
    email: string | null
    phone: string | null
    balance: number
  }
}

export interface AdminUserListQuery {
  keyword?: string
  role?: string
  status?: string
  limit?: number
  offset?: number
}

export interface AdminUserUpdatePayload {
  nickname?: string | null
  avatar?: string | null
  email?: string | null
  phone?: string | null
  real_name?: string | null
  id_card_no?: string | null
  id_card_verified?: string | null
  member_level_id?: number | null
  member_level_locked?: boolean
  agent_tier?: AgentTier | null
  role?: "user" | "admin" | "super_admin"
  status?: "active" | "inactive" | "banned"
  is_email_verified?: boolean
  is_phone_verified?: boolean
}

export interface AdminInstanceBillingPayload {
  cycle?: string
  unit_price?: number
  next_renew_amount?: number
  expires_at?: string | null
  auto_renew?: boolean
}

export interface AdminBalanceAdjustPayload {
  delta: number
  reason?: string
}

export interface ImpersonateResult {
  access_token: string
  token_type: string
  expires_at: string
  user_id: number
  username: string
  audit_id: number
  read_only: true
}

export interface AdminInstanceNatAclItem {
  id: number | null
  name: string
  description: string
  ext_port: number | null
  int_port: number | null
  int_ip?: string | null
  protocol: number | null
}

export interface AdminInstanceNatAclMeta {
  total: number
  total_page: number
  page: number
  per_page: number
}

export interface AdminInstanceNatAclList {
  list: AdminInstanceNatAclItem[]
  meta: AdminInstanceNatAclMeta
  nat_host_ip: string | null
}

export interface AdminInstanceNatAclQuery {
  page?: number
  per_page?: number
  orderby?: "id" | "name" | "ext_port" | "int_port" | "protocol"
  sort?: "asc" | "desc"
  search?: string
  list_type?: "all" | "page"
}

export interface AdminInstanceNatAclPayload {
  name: string
  ext_port?: number | null
  int_port: number
  protocol: 1 | 2 | 3
}

const BASE = "/v1/admin/users"

export async function listUsers(q: AdminUserListQuery = {}) {
  const params = new URLSearchParams()
  if (q.keyword) params.set("keyword", q.keyword)
  if (q.role) params.set("role", q.role)
  if (q.status) params.set("status", q.status)
  if (q.limit != null) params.set("limit", String(q.limit))
  if (q.offset != null) params.set("offset", String(q.offset))
  const qs = params.toString()
  const url = qs ? `${BASE}?${qs}` : BASE
  const { data } = await adminClient.get<ApiResponse<AdminUser[] | PageResult<AdminUser>>>(url)
  return { ...data, data: pageResult<AdminUser>(data.data) }
}

export async function getUser(id: number) {
  const { data } = await adminClient.get<ApiResponse<AdminUser>>(`${BASE}/${id}`)
  return data
}

export async function updateUser(id: number, payload: AdminUserUpdatePayload) {
  const { data } = await adminClient.patch<ApiResponse<AdminUser>>(`${BASE}/${id}`, payload)
  return data
}

export async function resetUserPassword(id: number, newPassword: string) {
  const { data } = await adminClient.post<ApiResponse<null>>(`${BASE}/${id}/reset-password`, {
    new_password: newPassword,
  })
  return data
}

export async function adjustUserBalance(id: number, payload: AdminBalanceAdjustPayload) {
  const { data } = await adminClient.post<ApiResponse<AdminUser>>(
    `${BASE}/${id}/adjust-balance`,
    payload,
  )
  return data
}

export async function addUserRefundQuota(id: number, count: number, reason: string) {
  const { data } = await adminClient.post<ApiResponse<AdminUser>>(
    `${BASE}/${id}/refund-quota/add`,
    { count, reason },
  )
  return data
}

export async function reduceUserRefundQuota(id: number, count: number, reason: string) {
  const { data } = await adminClient.post<ApiResponse<AdminUser>>(
    `${BASE}/${id}/refund-quota/reduce`,
    { count, reason },
  )
  return data
}

export async function resetUserRefundQuota(id: number, reason: string) {
  const { data } = await adminClient.post<ApiResponse<AdminUser>>(
    `${BASE}/${id}/refund-quota/reset`,
    { reason },
  )
  return data
}

export async function addUserInviteCodeQuota(id: number, count: number, reason: string) {
  const { data } = await adminClient.post<ApiResponse<AdminUser>>(
    `${BASE}/${id}/invite-code-quota/add`,
    { count, reason },
  )
  return data
}

export async function resetUserInviteCodeQuota(id: number, reason: string) {
  const { data } = await adminClient.post<ApiResponse<AdminUser>>(
    `${BASE}/${id}/invite-code-quota/reset`,
    { reason },
  )
  return data
}

export async function addUserVerificationQuota(id: number, count: number, reason: string) {
  const { data } = await adminClient.post<ApiResponse<AdminUser>>(
    `${BASE}/${id}/verification-quota/add`,
    { count, reason },
  )
  return data
}

export async function reduceUserVerificationQuota(id: number, count: number, reason: string) {
  const { data } = await adminClient.post<ApiResponse<AdminUser>>(
    `${BASE}/${id}/verification-quota/reduce`,
    { count, reason },
  )
  return data
}

export async function resetUserVerificationFreeQuota(id: number, reason: string) {
  const { data } = await adminClient.post<ApiResponse<AdminUser>>(
    `${BASE}/${id}/verification-quota/reset-free`,
    { reason },
  )
  return data
}

export async function banUser(id: number) {
  const { data } = await adminClient.post<ApiResponse<AdminUser>>(`${BASE}/${id}/ban`)
  return data
}

export async function unbanUser(id: number) {
  const { data } = await adminClient.post<ApiResponse<AdminUser>>(`${BASE}/${id}/unban`)
  return data
}

export async function impersonateUser(id: number, reason: string) {
  const { data } = await adminClient.post<ApiResponse<ImpersonateResult>>(
    `${BASE}/${id}/impersonate`,
    { reason },
  )
  return data
}

export async function listUserInstances(userId: number) {
  const { data } = await adminClient.get<ApiResponse<AdminUserInstance[] | PageResult<AdminUserInstance>>>(
    `${BASE}/${userId}/instances`,
  )
  return { ...data, data: listResult<AdminUserInstance>(data.data) }
}

export async function getUserInstance(userId: number, instanceId: number) {
  const { data } = await adminClient.get<ApiResponse<AdminUserInstanceDetail>>(
    `${BASE}/${userId}/instances/${instanceId}`,
  )
  return data
}

export async function listUserInstanceNatAcl(
  userId: number,
  instanceId: number,
  params: AdminInstanceNatAclQuery = {},
) {
  const { data } = await adminClient.get<ApiResponse<AdminInstanceNatAclList>>(
    `${BASE}/${userId}/instances/${instanceId}/nat-acl`,
    { params },
  )
  return data
}

export async function createUserInstanceNatAcl(
  userId: number,
  instanceId: number,
  payload: AdminInstanceNatAclPayload,
) {
  const { data } = await adminClient.post<ApiResponse<AdminInstanceNatAclItem>>(
    `${BASE}/${userId}/instances/${instanceId}/nat-acl`,
    payload,
  )
  return data
}

export async function deleteUserInstanceNatAcl(userId: number, instanceId: number, natAclId: number) {
  const { data } = await adminClient.delete<ApiResponse<Record<string, unknown>>>(
    `${BASE}/${userId}/instances/${instanceId}/nat-acl/${natAclId}`,
  )
  return data
}

export type AdminInstancePowerAction = "power-on" | "shutdown" | "hard-shutdown" | "reboot"

export async function operateUserInstancePower(userId: number, instanceId: number, action: AdminInstancePowerAction) {
  const { data } = await adminClient.post<ApiResponse<{ taskid: number | null; instance_id: number }>>(
    `${BASE}/${userId}/instances/${instanceId}/power/${action}`,
  )
  return data
}

export async function suspendUserInstance(userId: number, instanceId: number) {
  const { data } = await adminClient.post<ApiResponse<{ taskid: number | null; instance_id: number }>>(
    `${BASE}/${userId}/instances/${instanceId}/suspend`,
    { type: "manual", free_gpu: 0 },
  )
  return data
}

export async function unsuspendUserInstance(userId: number, instanceId: number) {
  const { data } = await adminClient.post<ApiResponse<{ taskid: number | null; instance_id: number }>>(
    `${BASE}/${userId}/instances/${instanceId}/unsuspend`,
  )
  return data
}

export async function deleteUserInstance(userId: number, instanceId: number) {
  const { data } = await adminClient.delete<ApiResponse<{ taskid: number | null; instance_id: number }>>(
    `${BASE}/${userId}/instances/${instanceId}`,
  )
  return data
}

export async function updateUserInstanceAutoRenew(userId: number, instanceId: number, autoRenew: boolean) {
  const { data } = await adminClient.patch<ApiResponse<{ id: number; auto_renew: number }>>(
    `${BASE}/${userId}/instances/${instanceId}/auto-renew`,
    { auto_renew: autoRenew },
  )
  return data
}

export async function updateUserInstanceBilling(
  userId: number,
  instanceId: number,
  payload: AdminInstanceBillingPayload,
) {
  const { data } = await adminClient.patch<ApiResponse<AdminUserInstance>>(
    `${BASE}/${userId}/instances/${instanceId}/billing`,
    payload,
  )
  return data
}

export async function provisionUserInstance(userId: number, instanceId: number) {
  const { data } = await adminClient.post<ApiResponse<{ instance_id: number }>>(
    `${BASE}/${userId}/instances/${instanceId}/provision`,
  )
  return data
}
