import axios from 'axios';
import { toast } from 'react-toastify';

const COZE_API_TOKEN = 'pat_RiXRbDpm7UTfnXskaEhzRMJ2qEVclaNyX5dmhKhFS7ytX5W0LTK2acAhQx94fajw';
const COZE_WORKFLOW_ID = '7484196116684095488';

/**
 * 直接上传文件到Coze并获取可访问链接
 * @param {File} file - 要上传的文件对象（音频或视频）
 * @returns {Promise<string>} - 成功时返回可访问的文件链接，失败时返回null
 */
const uploadFileAndGetLink = async (file) => {
  try {
    // 第一步：上传文件
    const fileId = await uploadFileToCoze(file);
    if (!fileId) {
      throw new Error('文件上传失败');
    }

    // 第二步：通过工作流获取文件链接
    const fileUrl = await getFileLinkFromWorkflow(fileId);
    if (!fileUrl) {
      throw new Error('获取文件链接失败');
    }

    return fileUrl;
  } catch (error) {
    console.error('文件上传和处理失败:', error);
    toast.error(`文件上传和处理失败: ${error.message}`);
    return null;
  }
};

/**
 * 上传文件到Coze API
 * @param {File} file - 要上传的文件对象
 * @returns {Promise<string>} - 成功时返回文件ID，失败时返回null
 */
const uploadFileToCoze = async (file) => {
  try {
    const formData = new FormData();
    formData.append('file', file);

    const response = await axios.post('https://api.coze.cn/v1/files/upload', formData, {
      headers: {
        'Authorization': `Bearer ${COZE_API_TOKEN}`,
        'Content-Type': 'multipart/form-data'
      }
    });

    if (response.data.code === 0 && response.data.data && response.data.data.id) {
      console.log('文件上传成功，ID:', response.data.data.id);
      return response.data.data.id;
    } else {
      console.error('文件上传失败，返回数据:', response.data);
      throw new Error(response.data.msg || '上传失败');
    }
  } catch (error) {
    console.error('文件上传错误:', error);
    if (error.response) {
      console.error('API响应:', error.response.data);
    }
    throw new Error(`上传文件错误: ${error.message}`);
  }
};

/**
 * 通过Coze工作流获取文件的可访问链接
 * @param {string} fileId - 文件ID
 * @returns {Promise<string>} - 成功时返回文件链接，失败时返回null
 */
const getFileLinkFromWorkflow = async (fileId) => {
  try {
    const payload = {
      parameters: {
        input: JSON.stringify({ file_id: fileId })
      },
      workflow_id: COZE_WORKFLOW_ID
    };

    const response = await axios.post('https://api.coze.cn/v1/workflow/run', payload, {
      headers: {
        'Authorization': `Bearer ${COZE_API_TOKEN}`,
        'Content-Type': 'application/json'
      }
    });

    if (response.data.code === 0 && response.data.data) {
      try {
        const outputData = JSON.parse(response.data.data);
        if (outputData && outputData.output) {
          console.log('获取文件链接成功:', outputData.output);
          return outputData.output;
        }
      } catch (parseError) {
        console.error('解析返回数据失败:', parseError);
      }
    }
    
    console.error('工作流调用失败，返回数据:', response.data);
    throw new Error(response.data.msg || '获取链接失败');
  } catch (error) {
    console.error('调用工作流错误:', error);
    if (error.response) {
      console.error('API响应:', error.response.data);
    }
    throw new Error(`获取文件链接错误: ${error.message}`);
  }
};

/**
 * 从本地路径上传文件到Coze
 * 提示用户直接选择音频或视频文件上传
 * 
 * @returns {Promise<string>} - 成功时返回可访问链接，失败时返回null
 */
const uploadFileByDialog = async () => {
  try {
    // 创建一个input元素来选择文件
    const input = document.createElement('input');
    input.type = 'file';
    input.style.display = 'none';
    input.accept = 'audio/*,video/*'; // 接受音频和视频
    document.body.appendChild(input);
    
    // 返回一个Promise，在用户选择文件后解析
    return new Promise((resolve) => {
      input.onchange = async (event) => {
        if (event.target.files && event.target.files.length > 0) {
          const file = event.target.files[0];
          const url = await uploadFileAndGetLink(file);
          document.body.removeChild(input);
          resolve(url);
        } else {
          document.body.removeChild(input);
          resolve(null);
        }
      };
      
      // 点击文件选择器
      input.click();
    });

  } catch (error) {
    console.error('文件选择上传失败:', error);
    toast.error(`上传失败: ${error.message}`);
    return null;
  }
};

/**
 * 从URL获取文件并上传到Coze
 * 
 * @param {string} url - 文件URL地址
 * @param {string} fileName - 文件名称（可选）
 * @returns {Promise<string>} - 成功时返回可访问链接，失败时返回null
 */
const uploadFromUrl = async (url, fileName = null) => {
  try {
    // 获取文件内容
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`获取文件失败: ${response.statusText}`);
    }
    
    // 获取文件类型和文件名
    const contentType = response.headers.get('content-type') || '';
    const blob = await response.blob();
    
    // 如果没有提供文件名，尝试从URL中提取
    if (!fileName) {
      const urlParts = url.split('/');
      fileName = urlParts[urlParts.length - 1].split('?')[0] || 'file';
    }
    
    // 创建文件对象并上传
    const file = new File([blob], fileName, { type: contentType });
    return await uploadFileAndGetLink(file);
    
  } catch (error) {
    console.error('从URL上传文件失败:', error);
    toast.error(`从URL上传失败: ${error.message}`);
    return null;
  }
};

/**
 * 使用Electron的文件对话框选择文件并上传
 * 
 * @returns {Promise<string>} - 成功时返回可访问链接，失败时返回null
 */
const uploadUsingElectronDialog = async () => {
  try {
    // 检查是否在Electron环境中
    if (typeof window.electron === 'undefined' || !window.electron.ipcRenderer) {
      throw new Error('此方法仅在Electron环境中可用');
    }
    
    // 打开文件选择对话框
    const result = await window.electron.ipcRenderer.invoke('open-file-dialog', {
      filters: [
        { name: '媒体文件', extensions: ['mp3', 'wav', 'ogg', 'mp4', 'avi', 'mov'] }
      ],
      properties: ['openFile']
    });
    
    if (result.canceled || !result.filePaths || result.filePaths.length === 0) {
      console.log('用户取消了选择');
      return null;
    }
    
    // 获取选择的文件路径
    const filePath = result.filePaths[0];
    console.log('选择的文件路径:', filePath);
    
    // 让用户再次选择文件通过浏览器上传
    // 因为我们不能直接从文件系统路径创建File对象
    toast.info('请在弹出的对话框中再次选择相同的文件进行上传');
    
    return await uploadFileByDialog();
    
  } catch (error) {
    console.error('使用Electron对话框选择文件失败:', error);
    toast.error(`选择文件失败: ${error.message}`);
    return null;
  }
};

/**
 * 使用项目中保存的绝对路径上传文件
 * 直接将绝对路径转为文件对象并上传，不需要用户交互
 * 
 * @param {string} filePath - 文件的绝对路径
 * @returns {Promise<string>} - 成功时返回可访问链接，失败时返回null
 */
const uploadProjectMedia = async (filePath) => {
  try {
    // 检查路径是否存在
    if (!filePath || typeof filePath !== 'string') {
      throw new Error('无效的文件路径');
    }

    // 优先检查是否为http/https链接，如果是则直接使用
    if (filePath.startsWith('http://') || filePath.startsWith('https://')) {
      return filePath; // 已经是URL，直接返回
    }

    // 如果是file://协议，则转换为本地路径
    let localPath = filePath;
    if (filePath.startsWith('file://')) {
      localPath = filePath.replace('file://', '');
    }

    // 检查Electron环境
    if (typeof window.electron === 'undefined' || !window.electron.ipcRenderer) {
      // 如果不在Electron环境，无法读取本地文件
      toast.error('当前环境不支持直接读取本地文件');
      return null;
    }

    try {
      // 直接读取文件内容
      const fileBuffer = await window.electron.files.readFileAsArrayBuffer(localPath);
      if (!fileBuffer) {
        throw new Error('读取文件内容失败');
      }
      
      // 从路径中提取文件名
      const fileName = localPath.split('/').pop() || 'file';
      
      // 创建文件对象
      const file = new File([fileBuffer], fileName);
      
      // 上传文件并获取链接
      return await uploadFileAndGetLink(file);
    } catch (error) {
      console.error('读取和上传文件失败:', error);
      throw new Error(`读取和上传文件失败: ${error.message}`);
    }
  } catch (error) {
    console.error('项目媒体文件上传失败:', error);
    toast.error(`上传失败: ${error.message}`);
    return null;
  }
};

export default {
  uploadFileAndGetLink,
  uploadFileByDialog,
  uploadFromUrl,
  uploadUsingElectronDialog,
  uploadProjectMedia,
  uploadFileToCoze,
  getFileLinkFromWorkflow
}; 