import { getAuthToken } from '../utils/auth'
const BASE = 'http://10.126.59.25:5713'  // 后端地址



/**
 * 获取待审核的帖子列表
 * POST /apostlist
 * @param {number|string} userId 平台管理员的用户 ID
 * @returns Promise<[ {id, title, status}, … ]>
 */
export async function fetchPosts() {
  const userid = getAuthToken()
  const res = await fetch(`${BASE}/apostlist`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ userid })
  })
  if (!res.ok) throw new Error(`fetchPosts: ${res.status}`)
  
  const json = await res.json()
  console.log('fetchPosts response:', json)         // debug: inspect shape

  // handle unauthorized
  if (json.status === 'error' && json.message === 'Unauthorized') {
    throw new Error('Unauthorized')
  }
  
  // normalize response into an array
  let list
  if (Array.isArray(json)) {
    list = json
  } else if (Array.isArray(json.data)) {
    list = json.data
  } else if (Array.isArray(json.posts)) {
    list = json.posts
  } else if (Array.isArray(json.data?.posts)) {
    list = json.data.posts
  } else {
    list = []
  }
  console.log('Normalized post list:', list) // debug: check final shape
  return list
}

/**
 * 审核通过
 * POST /areview
 */
export async function approvePost(postId) {
  const userid = getAuthToken()
  const res = await fetch(`${BASE}/areview`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ userid, postid: postId, status: 'published' })
  })
  if (!res.ok) throw new Error(`approvePost: ${res.status}`)
  return res.json()
}

/**
 * 驳回
 * POST /areview
 */
export async function rejectPost(postId) {
  const userid = getAuthToken()
  const res = await fetch(`${BASE}/areview`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ userid, postid: postId, status: 'rejected' })
  })
  if (!res.ok) throw new Error(`rejectPost: ${res.status}`)
  return res.json()
}

/**
 * 获取单个帖子详情
 * POST /agetpost
 * @param {number|string} postId 帖子 ID
 * @param {number|string} userId 平台管理员的用户 ID
 * @returns Promise<{id, title, content, status}>
 */
export async function fetchPost(postId) {
  const userid = getAuthToken()
  const res = await fetch(`${BASE}/agetpost`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ userid, postid: postId })
  })
  if (!res.ok) throw new Error(`fetchPost: ${res.status}`)
  return res.json()
}

/**
 * 获取超级管理员用户列表
 * POST /sgetuserlist
 * @param {number|string} userId 平台管理员的用户 ID
 * @returns Promise<[ {id, name, role}, … ]>
 */
export async function fetchUserList() {
  const userid = getAuthToken()
  const res = await fetch(`${BASE}/sgetuserlist`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ userid })
  })
  if (!res.ok) throw new Error(`fetchUserList: ${res.status}`)
  
  const json = await res.json()
  console.log('fetchUserList response:', json)
  
  // handle unauthorized
  if (json.status === 'error' && json.message === 'Unauthorized') {
    throw new Error('Unauthorized')
  }
  
  return json
}

export async function giveAdmin(targetId) {
  const userid = getAuthToken()
  const res = await fetch(`${BASE}/sgiveadmin`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ userid, targetid: targetId })
  })
  if (!res.ok) throw new Error(`giveAdmin: ${res.status}`)
  return res.json()
}

export async function giveSuperAdmin(targetId) {
  const userid = getAuthToken()
  const res = await fetch(`${BASE}/sgivesuperadmin`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ userid, targetid: targetId })
  })
  if (!res.ok) throw new Error(`giveSuperAdmin: ${res.status}`)
  return res.json()
}

export async function giveUser(targetId) {
  const userid = getAuthToken()
  const res = await fetch(`${BASE}/sgiveuser`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ userid, targetid: targetId })
  })
  if (!res.ok) throw new Error(`giveUser: ${res.status}`)
  return res.json()
}

/**
 * 获取事务日志
 * POST /getrecordlog
 * @returns Promise<[ {id, user_id, type, content, ip, created_at}, … ]>
 */
export async function fetchRecordLog() {
  const userid = getAuthToken()
  const res = await fetch(`${BASE}/getrecordlog`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ userid })
  })
  if (!res.ok) throw new Error(`fetchRecordLog: ${res.status}`)
  const json = await res.json()
  console.log('fetchRecordLog response:', json)
  if (json.status === 'error' && json.message === 'Unauthorized') {
    throw new Error('Unauthorized')
  }
  let list
  if (Array.isArray(json)) {
    list = json
  } else if (Array.isArray(json.data)) {
    list = json.data
  } else {
    list = []
  }
  console.log('Normalized record log list:', list)
  return list
}

/**
 * 获取系统性能消耗数据
 * POST /getsyscost
 * @param {number|string} userId 平台管理员的用户 ID
 * @returns Promise<[ {id, record_time, endpoint, elapsed_time, cpu_user, cpu_system, memory_rss}, … ]>
 */
export async function fetchSysCost() {
  const userid = getAuthToken()
  const res = await fetch(`${BASE}/getsyscost`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ userid })
  })
  if (!res.ok) throw new Error(`fetchSysCost: ${res.status}`)
  const json = await res.json()
  console.log('fetchSysCost response:', json)
  if (json.status === 'error' && json.message === 'Unauthorized') {
    throw new Error('Unauthorized')
  }
  let list
  if (Array.isArray(json)) {
    list = json
  } else if (Array.isArray(json.data)) {
    list = json.data
  } else {
    list = []
  }
  console.log('Normalized sys cost list:', list)
  return list
}