import { apiClient } from "./client";
import type { ApiResponse } from "./types";

// 上传文件响应类型
export interface UploadResponse {
  url: string;
  filename: string;
  size: number;
  mimeType: string;
}

// 上传进度回调类型
export type UploadProgressCallback = (progressEvent: {
  loaded: number;
  total: number;
  percentage: number;
}) => void;

/**
 * 上传单个文件
 * @param file 要上传的文件
 * @param onProgress 上传进度回调函数
 * @returns 上传结果
 */
export const uploadFile = async (
  file: File,
  onProgress?: UploadProgressCallback
): Promise<ApiResponse<UploadResponse>> => {
  try {
    const formData = new FormData();
    formData.append('file', file);

    console.log('📤 开始上传文件:', file.name, `(${(file.size / 1024 / 1024).toFixed(2)}MB)`);

    const response = await apiClient.post('/common/upload/', formData, {
      headers: {
        'Content-Type': undefined as any, // Let axios/browser set multipart boundary automatically
      },
      onUploadProgress: (progressEvent) => {
        const { loaded, total } = progressEvent;
        const percentage = total ? Math.round((loaded * 100) / total) : 0;

        console.log(`📊 上传进度: ${percentage}% (${(loaded / 1024 / 1024).toFixed(2)}MB / ${((total || 0) / 1024 / 1024).toFixed(2)}MB)`);

        if (onProgress) {
          onProgress({
            loaded,
            total: total || 0,
            percentage,
          });
        }
      },
    });

    if (!response.data.success) {
      throw new Error(response.data.message || '文件上传失败');
    }

    console.log('✅ 文件上传成功:', response.data.data);
    return response.data;
  } catch (error) {
    console.error("文件上传失败:", error);
    throw error;
  }
};

/**
 * 上传多个文件
 * @param files 要上传的文件数组
 * @param onProgress 上传进度回调函数
 * @returns 上传结果数组
 */
export const uploadFiles = async (
  files: File[],
  onProgress?: UploadProgressCallback
): Promise<ApiResponse<UploadResponse[]>> => {
  try {
    const formData = new FormData();
    files.forEach((file, index) => {
      formData.append(`files`, file);
    });

    console.log('📤 开始批量上传文件:', files.length, '个文件');

    const response = await apiClient.post('/common/upload/', formData, {
      headers: {
        'Content-Type': undefined as any, // Let axios/browser set multipart boundary automatically
      },
      onUploadProgress: (progressEvent) => {
        const { loaded, total } = progressEvent;
        const percentage = total ? Math.round((loaded * 100) / total) : 0;

        console.log(`📊 批量上传进度: ${percentage}%`);

        if (onProgress) {
          onProgress({
            loaded,
            total: total || 0,
            percentage,
          });
        }
      },
    });

    if (!response.data.success) {
      throw new Error(response.data.message || '文件批量上传失败');
    }

    console.log('✅ 文件批量上传成功:', response.data.data);
    return response.data;
  } catch (error) {
    console.error("文件批量上传失败:", error);
    throw error;
  }
};

/**
 * 上传图片文件（带图片格式验证）
 * @param file 要上传的图片文件
 * @param onProgress 上传进度回调函数
 * @returns 上传结果
 */
export const uploadImage = async (
  file: File,
  onProgress?: UploadProgressCallback
): Promise<ApiResponse<UploadResponse>> => {
  // 验证文件类型
  const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
  if (!allowedTypes.includes(file.type)) {
    throw new Error('只支持 JPEG、PNG、GIF、WebP 格式的图片');
  }

  // 验证文件大小（限制10MB）
  const maxSize = 10 * 1024 * 1024; // 10MB
  if (file.size > maxSize) {
    throw new Error('图片文件大小不能超过 10MB');
  }

  return uploadFile(file, onProgress);
};

/**
 * 上传头像图片（带特殊限制）
 * @param file 要上传的头像图片
 * @param onProgress 上传进度回调函数
 * @returns 上传结果
 */
export const uploadAvatar = async (
  file: File,
  onProgress?: UploadProgressCallback
): Promise<ApiResponse<UploadResponse>> => {
  // 验证文件类型
  const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png'];
  if (!allowedTypes.includes(file.type)) {
    throw new Error('头像只支持 JPEG、PNG 格式');
  }

  // 验证文件大小（限制2MB）
  const maxSize = 2 * 1024 * 1024; // 2MB
  if (file.size > maxSize) {
    throw new Error('头像文件大小不能超过 2MB');
  }

  return uploadFile(file, onProgress);
};

/**
 * 上传动画文件
 * @param file 要上传的动画文件
 * @param onProgress 上传进度回调函数
 * @returns 上传结果
 */
export const uploadAnimation = async (
  file: File,
  onProgress?: UploadProgressCallback
): Promise<ApiResponse<UploadResponse>> => {
  // 验证文件类型
  const allowedTypes = [
    'video/mp4', 'video/avi', 'video/mov', 'video/wmv', 'video/flv',
    'image/gif', // GIF动画
    'application/x-lottie', // Lottie动画
    'text/json', // Lottie JSON格式
  ];
  
  const isValidType = allowedTypes.includes(file.type) || 
                     file.name.toLowerCase().endsWith('.json') || 
                     file.name.toLowerCase().endsWith('.lottie');

  if (!isValidType) {
    throw new Error('只支持 MP4、AVI、MOV、WMV、FLV、GIF、Lottie 格式的动画文件');
  }

  // 验证文件大小（限制50MB）
  const maxSize = 50 * 1024 * 1024; // 50MB
  if (file.size > maxSize) {
    throw new Error('动画文件大小不能超过 50MB');
  }

  console.log('📹 开始上传动画文件:', file.name, `(${(file.size / 1024 / 1024).toFixed(2)}MB)`);
  return uploadFile(file, onProgress);
};

/**
 * 上传音频文件
 * @param file 要上传的音频文件
 * @param onProgress 上传进度回调函数
 * @returns 上传结果
 */
export const uploadAudio = async (
  file: File,
  onProgress?: UploadProgressCallback
): Promise<ApiResponse<UploadResponse>> => {
  // 验证文件类型
  const allowedTypes = [
    'audio/mp3', 'audio/mpeg', 'audio/wav', 'audio/ogg', 
    'audio/aac', 'audio/flac', 'audio/wma', 'audio/m4a'
  ];
  
  const isValidType = allowedTypes.includes(file.type) || 
                     /\.(mp3|wav|ogg|aac|flac|wma|m4a)$/i.test(file.name);

  if (!isValidType) {
    throw new Error('只支持 MP3、WAV、OGG、AAC、FLAC、WMA、M4A 格式的音频文件');
  }

  // 验证文件大小（限制20MB）
  const maxSize = 20 * 1024 * 1024; // 20MB
  if (file.size > maxSize) {
    throw new Error('音频文件大小不能超过 20MB');
  }

  console.log('🎵 开始上传音频文件:', file.name, `(${(file.size / 1024 / 1024).toFixed(2)}MB)`);
  return uploadFile(file, onProgress);
};

/**
 * 通过URL上传文件
 * @param url 文件URL
 * @param filename 文件名
 * @returns 上传结果
 */
export const uploadFromUrl = async (
  url: string,
  filename?: string
): Promise<ApiResponse<UploadResponse>> => {
  try {
    console.log('📤 开始从URL上传文件:', url);

    const response = await apiClient.post('/common/upload/', {
      url,
      filename,
    });

    if (!response.data.success) {
      throw new Error(response.data.message || 'URL文件上传失败');
    }

    console.log('✅ URL文件上传成功:', response.data.data);
    return response.data;
  } catch (error) {
    console.error("URL文件上传失败:", error);
    throw error;
  }
};

/**
 * 删除上传的文件
 * @param url 文件URL或文件ID
 * @returns 删除结果
 */
export const deleteUploadedFile = async (url: string): Promise<ApiResponse<{ message: string }>> => {
  try {
    console.log('🗑️ 删除上传文件:', url);

    const response = await apiClient.delete('/common/upload/', {
      data: { url }
    });

    if (!response.data.success) {
      throw new Error(response.data.message || '文件删除失败');
    }

    console.log('✅ 文件删除成功');
    return response.data;
  } catch (error) {
    console.error("文件删除失败:", error);
    throw error;
  }
};

/**
 * 获取文件信息
 * @param url 文件URL
 * @returns 文件信息
 */
export const getFileInfo = async (url: string): Promise<ApiResponse<UploadResponse>> => {
  try {
    const response = await apiClient.get(`/common/upload/info/?url=${encodeURIComponent(url)}`);

    if (!response.data.success) {
      throw new Error(response.data.message || '获取文件信息失败');
    }

    return response.data;
  } catch (error) {
    console.error("获取文件信息失败:", error);
    throw error;
  }
};

// 文件类型检查工具函数
export const isImageFile = (file: File): boolean => {
  if (!file || !file.type) return false;
  return file.type.startsWith('image/');
};

export const isVideoFile = (file: File): boolean => {
  if (!file || !file.type) return false;
  return file.type.startsWith('video/');
};

export const isAudioFile = (file: File): boolean => {
  if (!file) return false;
  const hasAudioType = file.type && file.type.startsWith('audio/');
  const hasAudioExtension = file.name && /\.(mp3|wav|ogg|aac|flac|wma|m4a)$/i.test(file.name);
  return Boolean(hasAudioType || hasAudioExtension);
};

export const isAnimationFile = (file: File): boolean => {
  if (!file) return false;
  const hasVideoType = file.type && file.type.startsWith('video/');
  const hasGifType = file.type && file.type === 'image/gif';
  const hasLottieType = file.type && file.type === 'application/x-lottie';
  const hasJsonName = file.name && file.name.toLowerCase().endsWith('.json');
  const hasLottieName = file.name && file.name.toLowerCase().endsWith('.lottie');
  
  return Boolean(hasVideoType || hasGifType || hasLottieType || hasJsonName || hasLottieName);
};

export const isPdfFile = (file: File): boolean => {
  if (!file || !file.type) return false;
  return file.type === 'application/pdf';
};

// 文件大小格式化工具函数
export const formatFileSize = (bytes: number): string => {
  // 处理无效值
  if (typeof bytes !== 'number' || isNaN(bytes) || bytes < 0) {
    return '未知大小';
  }
  
  if (bytes === 0) return '0 Bytes';
  
  const k = 1024;
  const sizes = ['Bytes', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  
  // 确保索引在有效范围内
  const sizeIndex = Math.min(i, sizes.length - 1);
  
  return parseFloat((bytes / Math.pow(k, sizeIndex)).toFixed(2)) + ' ' + sizes[sizeIndex];
};