import axios from 'axios';
import type { CategoryDTO, Category, WorkResponse } from './otherType';

const API_BASE_URL = '/api';

class CategoryAPI {
  /**
   * 获取全部分区（树形结构）
   * @returns 返回分区的树形结构数据
   */
  static getCategoryTree(): Promise<CategoryDTO[]> {
    return axios.get<CategoryDTO[]>(`${API_BASE_URL}/categories`)
      .then(response => response.data);
  }

  /**
   * 获取单个分区详情
   * @param id 分区ID
   * @returns 返回单个分区的详细信息
   */
  static getCategory(id: number): Promise<Category> {
    return axios.get<Category>(`${API_BASE_URL}/categories/${id}`)
      .then(response => response.data);
  }

  /**
   * 创建新分区
   * @param category 分区数据（不包含ID）
   * @returns 返回创建成功的消息
   */
  static createCategory(category: Omit<Category, 'id'>): Promise<string> {
    return axios.post<string>(`${API_BASE_URL}/categories`, category)
      .then(response => response.data);
  }

  /**
   * 更新分区信息
   * @param id 分区ID
   * @param category 更新后的分区数据
   * @returns 返回更新成功的消息
   */
  static updateCategory(id: number, category: Partial<Category>): Promise<string> {
    return axios.put<string>(`${API_BASE_URL}/categories/${id}`, category)
      .then(response => response.data);
  }

  /**
   * 删除分区
   * @param id 分区ID
   * @returns 返回删除成功的消息
   */
  static deleteCategory(id: number): Promise<string> {
    return axios.delete<string>(`${API_BASE_URL}/categories/${id}`)
      .then(response => response.data);
  }

  /**
   * 获取分区下的作品列表（带分页）
   * @param categoryId 分区ID
   * @param params 分页和排序参数
   * @returns 返回作品列表和分页信息
   */
  static getWorksByCategory(
    categoryId: number,
    params?: {
      page?: number;
      size?: number;
      sort?: string;
    }
  ): Promise<WorkResponse> {
    return axios.get<WorkResponse>(`${API_BASE_URL}/works`, {
      params: {
        categoryId,
        ...params
      }
    }).then(response => response.data);
  }

  /**
   * 获取子分区列表
   * @param parentId 父分区ID
   * @returns 返回子分区列表
   */
  static getSubCategories(parentId: number): Promise<CategoryDTO[]> {
    return axios.get<CategoryDTO[]>(`${API_BASE_URL}/categories/${parentId}/children`)
      .then(response => response.data);
  }
}

export default CategoryAPI;