// src/api/posts.js
const BASE = 'http://10.126.59.25:5714/'  // 如果有代理可以留空，否则填完整域名，如 'http://localhost:3000'

/**
 * 获取所有已发布的帖子列表
 * GET /posts
 */
export async function fetchPosts() {
  const res = await fetch(`${BASE}/posts`)
  if (!res.ok) throw new Error(`fetchPosts: ${res.status}`)
  console.log('fetchPosts response:', res)  // debug: inspect response
  return res.json()  // 返回 [ { id, title, heat, created_at }, … ]
}

/**
 * 查看单个帖子详情
 * GET /posts/{postId}
 */
export async function fetchPost(postId) {
  const res = await fetch(`${BASE}/posts/${postId}`)
  if (!res.ok) throw new Error(`fetchPost(${postId}): ${res.status}`)
  return res.json()  // 返回完整的帖子对象
}

/**
 * 发布新帖
 * POST /posts
 */
export async function createPost(payload) {
  const res = await fetch(`${BASE}/posts`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload)
  })
  if (!res.ok) {
    const err = await res.json().catch(() => null)
    throw new Error(err?.error || `createPost: ${res.status}`)
  }
  return res.json()  // { id }
}

/**
 * 修改帖子
 * PUT /posts/{postId}
 */
export async function updatePost(postId, payload) {
  const res = await fetch(`${BASE}/posts/${postId}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload)
  })
  if (!res.ok) throw new Error(`updatePost(${postId}): ${res.status}`)
  // 204 No Content
}

/**
 * 删除帖子
 * DELETE /posts/{postId}
 */
export async function deletePost(postId) {
  const res = await fetch(`${BASE}/posts/${postId}`, {
    method: 'DELETE'
  })
  if (!res.ok) throw new Error(`deletePost(${postId}): ${res.status}`)
}

/**
 * 点赞
 * POST /posts/{postId}/like
 */
export async function likePost(postId, userId) {
  const res = await fetch(`${BASE}/posts/${postId}/like`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ user_id: userId })
  })
  if (!res.ok) {
    const err = await res.json().catch(() => null)
    throw new Error(err?.error || `likePost: ${res.status}`)
  }
}

/**
 * 取消点赞
 * DELETE /posts/{postId}/like
 */
export async function unlikePost(postId, userId) {
  const res = await fetch(`${BASE}/posts/${postId}/like`, {
    method: 'DELETE',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ user_id: userId })
  })
  if (!res.ok) {
    const err = await res.json().catch(() => null)
    throw new Error(err?.error || `unlikePost: ${res.status}`)
  }
}

/**
 * 收藏、取消收藏、浏览、分享 等接口：
 * POST   /posts/{postId}/favorite
 * DELETE /posts/{postId}/favorite
 * POST   /posts/{postId}/view
 * POST   /posts/{postId}/share
 * 用法同上，替换路径即可
 */

/**
 * 添加评论
 * POST /posts/{postId}/comments
 */
export async function addComment(postId, payload) {
  const res = await fetch(`${BASE}/posts/${postId}/comments`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload)
  })
  if (!res.ok) throw new Error(`addComment: ${res.status}`)
  return res.json()  // { id }
}

/**
 * 获取评论列表
 * GET /posts/{postId}/comments
 */
export async function fetchComments(postId) {
  const res = await fetch(`${BASE}/posts/${postId}/comments`)
  if (!res.ok) throw new Error(`fetchComments: ${res.status}`)
  return res.json()
}
