// src/api/torrent.js
import { api } from './auth'; // 复用已有的axios实例

/**
 * 创建并上传一个种子
 * @param {File} file 种子文件 (.torrent)
 * @param {Object} bodyObj 包含种子信息的对象，格式如下：
 * {
 *   torrentName: "测试下载",
 *   description: "A high-quality 1080p version of Example Movie.",
 *   category: "电影",
 *   region: "USA",
 *   resolution: "1080p",
 *   subtitle: "English",
 *   filePath: "D:/大学/大三_下/torrentFrom/[电影天堂www.dytt89.com]两杆大烟枪BD中英双字.mp4.torrent"
 * }
 */
export async function createTorrent(file, bodyObj) {
  const formData = new FormData();
  formData.append('file', file);

  // 关键修改：将JSON字符串转换为Blob对象，并设置正确的Content-Type
  formData.append('body', new Blob([JSON.stringify(bodyObj)], {
    type: 'application/json'
  }));

  try {
    const response = await api.post('/torrent', formData, {
      headers: {
      }
    });
    return response.data;
  } catch (error) {
    console.error('上传种子失败:', error);
    throw error;
  }
};

/**
 * 下载种子文件
 * @param {number} torrentId 种子ID
 * @param {string} downloadPath 下载路径
 */
export async function downloadTorrent(torrentId, downloadPath) {
  try {
    const response = await api.get(`/torrent/downloadTorrent`, {
      params: {
        id: torrentId,
        downloadPath: downloadPath
      }
    });
    return response.data;
  } catch (error) {
    console.error('下载种子失败:', error);
    throw error;
  }
}

/**
 * 获取下载进度
 */
export async function getDownloadProgress() {
  try {
    const response = await api.get('/torrent/getProgress');
    return response.data;
  } catch (error) {
    console.error('获取下载进度失败:', error);
    throw error;
  }
}

export const getTorrents = (page = 1, size = 5) => {
  return api.get('/torrent', {
    params: { page, size }
  });
};

export const getTorrentDetail = (torrentId) => {
  return api.get(`/torrent/${torrentId}`).then(response => {
    // 确保数据结构一致
    if (response.data && response.data.data) {
      return {
        ...response,
        data: {
          ...response.data,
          data: {
            torrent: response.data.data.torrent, // 直接使用后端返回的格式化数据
            comments: response.data.data.comments || []
          }
        }
      };
    }
    return response;
  });
};

export const likeTorrent = (torrentId) => {
  return api.post(`/torrent/${torrentId}/like`);
};

export const addTorrentComment = (torrentId, commentData) => {
  return api.post(`/torrent/${torrentId}/comments`, commentData);
};

export const deleteTorrent = (torrentId) => {
  return api.delete(`/torrent/deleteTorrent/${torrentId}`);
};

// // 上传种子接口
// export const uploadTorrent = async (torrentFile, torrentData, onProgress) => {
//   // 1. 基础验证
//   if (!torrentFile || !torrentFile.name.endsWith('.torrent')) {
//     throw new Error('请选择有效的.torrent文件');
//   }

//   // 2. 构建FormData
//   const formData = new FormData();
//   formData.append('file', torrentFile);
  
//   // 确保JSON内容使用正确的Content-Type
//   const metadataBlob = new Blob(
//     [JSON.stringify(torrentData)], 
//     { type: 'application/json' }
//   );
//   formData.append('body', metadataBlob);

//   // 3. 获取认证token（根据你的实际存储方式调整）
//   const token = localStorage.getItem('token') || '';

//   try {
//     const response = await api.post('/api/torrents', formData, {
//       headers: {
//         'Authorization': `Bearer ${token}`,
//       },
//       onUploadProgress: (progressEvent) => {
//         if (onProgress && progressEvent.total) {
//           const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);
//           onProgress(percent);
//         }
//       }
//     });

//     return response.data;
//   } catch (error) {
//     console.error('上传失败:', error);
    
//     // 增强错误处理
//     let errorMessage = '上传失败';
//     if (error.response) {
//       errorMessage = error.response.data?.message || 
//                      `服务器错误: ${error.response.status}`;
//     } else if (error.request) {
//       errorMessage = '网络错误，请检查连接';
//     }

//     throw new Error(errorMessage);
//   }
// };

export const searchTorrents = (keyword, page = 1, size = 5) => {
  return api.get('/torrent/search', {
    params: { keyword, page, size }
  });
};