import axios from 'axios';

const API_BASE = process.env.REACT_APP_API_BASE;


// 获取帖子详情
export const getPostDetail = async (post_id) => {
    const response = await axios.get(`${API_BASE}/echo/forum/posts/${post_id}/getPost`);
    return response.data;
};

// 获取帖子评论
export const getPostComments = async (post_id) => {
    const response = await axios.get(`${API_BASE}/echo/forum/posts/${post_id}/getAllComments`);
    return response.data;
};

// 点赞帖子
export const likePost = async (post_id, userId) => {
    try {
        const response = await axios.post(`${API_BASE}/echo/forum/posts/${post_id}/like`, {
            user_id: userId,  // 用户 ID
        });
        return response.data;
    } catch (error) {
        return handleApiError(error);
    }
};

// 取消点赞帖子
export const unlikePost = async (post_id) => {
    const response = await axios.delete(`${API_BASE}/echo/forum/posts/${post_id}/unlike`);
    return response.data;
};

// 添加评论
export const addCommentToPost = async (post_id, userId, content, isAnonymous, comCommentId = null) => {
    try {
        const response = await axios.post(`${API_BASE}/echo/forum/posts/${post_id}/comments`, {
            content,
            user_id: userId,
            is_anonymous: isAnonymous,
            com_comment_id: comCommentId, // 如果是回复评论，传递 com_comment_id
        });
        return response.data;
    } catch (error) {
        return handleApiError(error);
    }
};

// 点赞评论
export const likeComment = async (commentId) => {
    const response = await axios.post(`${API_BASE}/echo/forum/comments/${commentId}/like`);
    return response.data;
};

// 取消点赞评论
export const unlikeComment = async (commentId) => {
    const response = await axios.delete(`${API_BASE}/echo/forum/comments/${commentId}/unlike`);
    return response.data;
};

// 收藏帖子
export const collectPost = async (post_id, userId, action) => {
    try {
        const response = await axios.post(`${API_BASE}/echo/forum/posts/${post_id}/collect`, {
            user_id: userId,
            action: action,  // "collect" 或 "cancel"
        });
        return response.data;
    } catch (error) {
        return handleApiError(error);
    }
};

// // 取消收藏帖子
// export const uncollectPost = async (post_id, userId) => {
//     const response = await axios.post(`${API_BASE}/echo/forum/posts/${post_id}/uncollect`, {
//         user_id: userId,  // 用户 ID
//     });
//     return response.data;
// };

// 获取用户信息
export const getUserInfo = async (userId) => {
    const response = await axios.get(`${API_BASE}/user/${userId}/info`);
    return response.data;
};

// 错误处理
const handleApiError = (error) => {
    if (error.response) {
        return {
            success: false,
            message: error.response.data.error || '请求失败',
        };
    } else if (error.request) {
        return {
            success: false,
            message: '请求未得到响应，请稍后重试',
        };
    } else {
        return {
            success: false,
            message: error.message || '发生了未知错误',
        };
    }
};
