import axios from 'axios';
import type { Work, WorkResponse, WorkFormData, BugReport, Discussion } from './otherType';

const API_BASE_URL = '/api';

class WorkAPI {
  /**
   * 获取作品列表（支持分页、分类筛选和搜索）
   */
  static getWorks(params?: {
    categoryId?: number;
    page?: number;
    size?: number;
    search?: string;
  }): Promise<WorkResponse> {
    return axios.get<WorkResponse>(`${API_BASE_URL}/works`, { params })
      .then(response => response.data);
  }

  /**
   * 获取单个作品详情
   */
  static getWorkById(id: number): Promise<Work> {
    return axios.get<Work>(`${API_BASE_URL}/works/${id}`)
      .then(response => response.data);
  }

  /**
   * 创建新作品
   */
  static createWork(data: WorkFormData): Promise<Work> {
    return axios.post<Work>(`${API_BASE_URL}/works`, data)
      .then(response => response.data);
  }

  /**
   * 更新作品信息
   */
  static updateWork(id: number, data: WorkFormData): Promise<Work> {
    return axios.put<Work>(`${API_BASE_URL}/works/${id}`, data)
      .then(response => response.data);
  }

  /**
   * 删除作品
   */
  static deleteWork(id: number): Promise<void> {
    return axios.delete(`${API_BASE_URL}/works/${id}`);
  }

  /**
   * 点赞作品
   */
  static likeWork(id: number): Promise<void> {
    return axios.post(`${API_BASE_URL}/works/${id}/like`);
  }

  /**
   * 根据作者查询作品
   */
  static getWorksByAuthor(author: string): Promise<Work[]> {
    return axios.get<Work[]>(`${API_BASE_URL}/works/byAuthor`, { params: { author } })
      .then(response => response.data);
  }

  /**
   * 获取作品Bug反馈列表
   */
  static getBugReports(workId: number): Promise<BugReport[]> {
    return axios.get<BugReport[]>(`${API_BASE_URL}/works/${workId}/bugs`)
      .then(response => response.data);
  }

  /**
   * 提交Bug反馈
   */
  static reportBug(workId: number, data: {
    title: string;
    description: string;
    severity: 'low' | 'medium' | 'high';
  }): Promise<void> {
    return axios.post(`${API_BASE_URL}/works/${workId}/bugs`, data);
  }

  /**
   * 获取作品讨论区列表
   */
  static getDiscussions(workId: number): Promise<Discussion[]> {
    return axios.get<Discussion[]>(`${API_BASE_URL}/works/${workId}/discussions`)
      .then(response => response.data);
  }

  /**
   * 创建新讨论
   */
  static createDiscussion(data: {
    workId: number;
    title: string;
    content: string;
  }): Promise<void> {
    return axios.post(`${API_BASE_URL}/discussions`, data);
  }
}

export default WorkAPI;