import { fetchApi } from '@/lib/server-api-util';
import { defaultExifData, ExifData, ImagesuploaderProps, UploadUrlResponse } from '@/types/upload';
import * as ImageManipulator from 'expo-image-manipulator';
import * as ImagePicker from 'expo-image-picker';
import * as Location from 'expo-location';
import * as MediaLibrary from 'expo-media-library';
import React, { useEffect, useState } from 'react';
import { Alert, Button, Platform, TouchableOpacity, View } from 'react-native';
import UploadPreview from './preview';

// 在文件顶部添加这些类型
type UploadTask = {
  file: File;
  metadata: {
    isCompressed: string;
    type: string;
    isThumbnail?: string;
    [key: string]: any;
  };
};

type FileUploadItem = {
  id: string;
  name: string;
  progress: number;
  status: 'pending' | 'uploading' | 'done' | 'error';
  error: string | null;
  type: 'image' | 'video';
  thumbnail: string | null;
};

type ConfirmUpload = {
  file_id: string;
  upload_url: string;
  name: string;
  size: number;
  content_type: string;
  file_path: string;
};

type UploadResult = {
  originalUrl?: string;
  compressedUrl: string;
  file: File | null;
  exif: any;
  originalFile: ConfirmUpload;
  compressedFile: ConfirmUpload;
  thumbnail: string;
  thumbnailFile: File;
};
export const ImagesUploader: React.FC<ImagesuploaderProps> = ({
  children,
  style,
  compressQuality = 0.8,
  maxWidth = 2048,
  maxHeight = 2048,
  preserveExif = true,
  onUploadComplete,
  multipleChoice = false,
  showPreview = true,
  fileType = ['images'],
}) => {
  const [isLoading, setIsLoading] = useState(false);

  const [uploadQueue, setUploadQueue] = useState<FileUploadItem[]>([]);

  // 请求权限
  const requestPermissions = async () => {
    if (Platform.OS !== 'web') {
      const { status: mediaStatus } = await ImagePicker.requestMediaLibraryPermissionsAsync();
      if (mediaStatus !== 'granted') {
        Alert.alert('需要媒体库权限', '请允许访问媒体库以选择图片');
        return false;
      }

      const { status: locationStatus } = await Location.requestForegroundPermissionsAsync();;
      if (locationStatus !== 'granted') {
        Alert.alert('需要位置权限', '需要位置权限才能获取图片位置信息');
      }
    }
    return true;
  };

  // 获取上传URL
  const getUploadUrl = async (file: File, metadata: Record<string, any> = {}): Promise<UploadUrlResponse> => {
    const body = {
      filename: file.name,
      content_type: file.type,
      file_size: file.size,
      metadata: {
        ...metadata,
        originalName: file.name,
        fileType: 'image',
        isCompressed: metadata.isCompressed || 'false',
      },
    };
    return await fetchApi<UploadUrlResponse>("/file/generate-upload-url", {
      method: 'POST',
      body: JSON.stringify(body)
    });
  };

  // 向服务端confirm上传
  const confirmUpload = async (file_id: string): Promise<ConfirmUpload> => await fetchApi<ConfirmUpload>('/file/confirm-upload', {
    method: 'POST',
    body: JSON.stringify({
      file_id
    })
  });

  // 新增素材
  const addMaterial = async (file: string, compressFile: string) => {
    await fetchApi('/material', {
      method: 'POST',
      body: JSON.stringify([{
        "file_id": file,
        "preview_file_id": compressFile
      }])
    }).catch((error) => {
      // console.log(error);
    })
  }

  // 上传文件到URL
  const uploadFileToUrl = async (file: File, uploadUrl: string, onProgress: (progress: number) => void): Promise<void> => {
    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();

      xhr.open('PUT', uploadUrl);
      xhr.setRequestHeader('Content-Type', file.type);

      // 进度监听
      xhr.upload.onprogress = (event) => {
        if (event.lengthComputable) {
          const progress = Math.round((event.loaded / event.total) * 100);
          onProgress(progress);
        }
      };

      xhr.onload = () => {
        if (xhr.status >= 200 && xhr.status < 300) {
          resolve();
        } else {
          reject(new Error(`Upload failed with status ${xhr.status}`));
        }
      };

      xhr.onerror = () => {
        reject(new Error('Network error during upload'));
      };

      xhr.send(file);
    });
  };

  // 压缩并处理图片
  const processImage = async (uri: string, fileName: string, mimeType: string) => {
    try {
      // 压缩图片
      const manipResult = await ImageManipulator.manipulateAsync(
        uri,
        [
          {
            resize: {
              width: maxWidth,
              height: maxHeight,
            },
          },
        ],
        {
          compress: compressQuality,
          format: ImageManipulator.SaveFormat.JPEG,
          base64: false,
        }
      );

      // 获取压缩后的图片数据
      const response = await fetch(manipResult.uri);
      const blob = await response.blob();

      // 创建文件对象
      const file = new File([blob], `compressed_${Date.now()}_${fileName}`, {
        type: mimeType,
      });

      return { file, uri: manipResult.uri };
    } catch (error) {
      // console.error('图片压缩失败:', error);
      throw new Error('图片处理失败');
    }
  };
  const uploadWithProgress = async (file: File, metadata: any): Promise<ConfirmUpload> => {
    let timeoutId: number
    console.log("uploadWithProgress", metadata);

    try {
      console.log("Starting upload for file:", file.name, "size:", file.size, "type:", file.type);

      // 检查文件大小
      const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
      if (file.size > MAX_FILE_SIZE) {
        throw new Error(`文件大小超过限制 (${(MAX_FILE_SIZE / 1024 / 1024).toFixed(1)}MB)`);
      }

      const uploadUrlData = await getUploadUrl(file, { ...metadata, GPSVersionID: undefined });
      console.log("Got upload URL for:", file.name);

      return new Promise<ConfirmUpload>((resolve, reject) => {
        try {
          // 设置超时
          timeoutId = setTimeout(() => {
            reject(new Error('上传超时，请检查网络连接'));
          }, 30000);

          // 上传文件
          const xhr = new XMLHttpRequest();
          xhr.open('PUT', uploadUrlData.upload_url, true);
          xhr.setRequestHeader('Content-Type', file.type);

          xhr.upload.onprogress = (event) => {
            if (event.lengthComputable) {
              const progress = Math.round((event.loaded / event.total) * 100);
              console.log(`Upload progress for ${file.name}: ${progress}%`);
            }
          };

          xhr.onload = async () => {
            clearTimeout(timeoutId!);
            if (xhr.status >= 200 && xhr.status < 300) {
              try {
                const result = await confirmUpload(uploadUrlData.file_id);
                resolve({
                  ...result,
                  file_id: uploadUrlData.file_id,
                  upload_url: uploadUrlData.upload_url,
                });
              } catch (error) {
                reject(error);
              }
            } else {
              reject(new Error(`上传失败，状态码: ${xhr.status}`));
            }
          };

          xhr.onerror = () => {
            clearTimeout(timeoutId!);
            reject(new Error('网络错误，请检查网络连接'));
          };

          xhr.send(file);

        } catch (error) {
          clearTimeout(timeoutId!);
          reject(error);
        }
      });

    } catch (error) {
      console.error('Error in uploadWithProgress:', {
        error,
        fileName: file?.name,
        fileSize: file?.size,
        fileType: file?.type
      });
      throw error;
    }
  };

  // 处理单个资源
  const processSingleAsset = async (asset: ImagePicker.ImagePickerAsset): Promise<UploadResult | null> => {
    console.log("asset111111", asset);

    const fileId = `file_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    const isVideo = asset.type === 'video';
    const uploadResults: UploadResult = {
      originalUrl: undefined,
      compressedUrl: '',
      file: null,
      exif: {},
      originalFile: {} as ConfirmUpload,
      compressedFile: {} as ConfirmUpload,
      thumbnail: '',
      thumbnailFile: {} as File,
    };
    // 创建上传项
    const newFileItem: FileUploadItem = {
      id: fileId,
      name: asset.fileName || 'file',
      progress: 0,
      status: 'uploading' as const,
      error: null,
      type: isVideo ? 'video' : 'image',
      thumbnail: null,
    };

    setUploadQueue(prev => [...prev, newFileItem]);

    const updateProgress = (progress: number) => {
      setUploadQueue(prev =>
        prev.map(item =>
          item.id === fileId ? { ...item, progress } : item
        )
      );
    };

    try {
      let file: File;
      let thumbnailFile: File | null = null;
      let exifData: ExifData = { ...defaultExifData };

      if (isVideo) {
        // 处理视频文件
        file = new File(
          [await (await fetch(asset.uri)).blob()],
          `video_${Date.now()}.mp4`,
          { type: 'video/mp4' }
        );

        // 生成视频缩略图
        const thumbnailResult = await ImageManipulator.manipulateAsync(
          asset.uri,
          [{ resize: { width: 300 } }],
          { compress: 0.7, format: ImageManipulator.SaveFormat.JPEG }
        );

        thumbnailFile = new File(
          [await (await fetch(thumbnailResult.uri)).blob()],
          `thumb_${Date.now()}.jpg`,
          { type: 'image/jpeg' }
        );
      } else {
        // 处理图片
        const [originalResponse, compressedFileResult] = await Promise.all([
          fetch(asset.uri),
          ImageManipulator.manipulateAsync(
            asset.uri,
            [{ resize: { width: 800 } }],
            { compress: 0.7, format: ImageManipulator.SaveFormat.JPEG }
          )
        ]);

        // 如果保留 EXIF 数据，则获取
        if (preserveExif && asset.exif) {
          exifData = { ...exifData, ...asset.exif };

          if (asset.uri && Platform.OS !== 'web') {
            try {
              const mediaAsset = await MediaLibrary.getAssetInfoAsync(asset.uri);
              if (mediaAsset.exif) {
                exifData = { ...exifData, ...mediaAsset.exif };
              }
              if (mediaAsset.location) {
                exifData.GPSLatitude = mediaAsset.location.latitude;
                exifData.GPSLongitude = mediaAsset.location.longitude;
              }
            } catch (error) {
              console.warn('从媒体库获取 EXIF 数据失败:', error);
            }
          }
        }
        const originalBlob = await originalResponse.blob();
        const compressedBlob = await compressedFileResult.file;

        file = new File(
          [originalBlob],
          `original_${Date.now()}_${asset.fileName || 'photo.jpg'}`,
          { type: asset.mimeType || 'image/jpeg' }
        );

        thumbnailFile = new File(
          [compressedBlob],
          `compressed_${Date.now()}_${asset.fileName || 'photo.jpg'}`,
          { type: 'image/jpeg' }
        );
      }

      // 准备上传任务
      const uploadTasks: UploadTask[] = [
        {
          file,
          metadata: {
            isCompressed: 'false',
            type: isVideo ? 'video' : 'image',
            ...(isVideo ? {} : exifData)
          }
        }
      ];

      if (thumbnailFile) {
        uploadTasks.push({
          file: thumbnailFile,
          metadata: {
            isCompressed: 'true',
            type: 'image',
            isThumbnail: 'true'
          }
        });
      }

      // 顺序上传文件
      const uploadResultsList = [];
      for (const task of uploadTasks) {
        try {
          const result = await uploadWithProgress(task.file, task.metadata);
          uploadResultsList.push(result);
        } catch (error) {
          console.error('Upload failed:', error);
          throw error;
        }
      }

      // 处理上传结果
      const [mainUpload, thumbnailUpload] = uploadResultsList;
      uploadResults.originalFile = mainUpload;
      uploadResults.compressedFile = thumbnailUpload || mainUpload;
      uploadResults.thumbnail = thumbnailUpload?.upload_url || '';
      uploadResults.thumbnailFile = thumbnailFile;

      // 更新上传状态
      updateProgress(100);
      setUploadQueue(prev =>
        prev.map(item =>
          item.id === fileId
            ? {
              ...item,
              status: 'done' as const,
              progress: 100,
              thumbnail: uploadResults.thumbnail
            }
            : item
        )
      );

      // 添加到素材库
      if (uploadResults.originalFile?.file_id) {
        await addMaterial(
          uploadResults.originalFile.file_id,
          uploadResults.thumbnail
        );
      }

      return uploadResults;
    } catch (error) {
      console.error('Error processing file:', error);
      setUploadQueue(prev =>
        prev.map(item =>
          item.id === fileId
            ? {
              ...item,
              status: 'error' as const,
              error: error instanceof Error ? error.message : '上传失败'
            }
            : item
        )
      );
      return null;
    }
  };
  // 处理所有选中的图片
  const processAssets = async (assets: ImagePicker.ImagePickerAsset[]): Promise<UploadResult[]> => {
    // 设置最大并发数
    const CONCURRENCY_LIMIT = 3;
    const results: UploadResult[] = [];

    // 分批处理资源
    for (let i = 0; i < assets.length; i += CONCURRENCY_LIMIT) {
      const batch = assets.slice(i, i + CONCURRENCY_LIMIT);

      // 并行处理当前批次的所有资源
      const batchResults = await Promise.allSettled(
        batch.map(asset => processSingleAsset(asset))
      );

      // 收集成功的结果
      for (const result of batchResults) {
        if (result.status === 'fulfilled' && result.value) {
          results.push(result.value);
        }
      }

      // 添加小延迟，避免过多占用系统资源
      if (i + CONCURRENCY_LIMIT < assets.length) {
        await new Promise(resolve => setTimeout(resolve, 100));
      }
    }

    return results;
  };

  // 处理图片选择
  const pickImage = async () => {
    try {
      setIsLoading(true);
      const hasPermission = await requestPermissions();
      console.log("hasPermission", hasPermission);
      if (!hasPermission) return;

      const result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: fileType,
        allowsMultipleSelection: multipleChoice,
        quality: 1,
        exif: preserveExif,
      });
      console.log("result", result?.assets);

      if (result.canceled || !result.assets) {
        setIsLoading(false);
        return;
      }

      try {
        const uploadResults = await processAssets(result.assets);

        // 所有文件处理完成后的回调
        // @ts-ignore
        onUploadComplete?.(uploadResults?.map((item, index) => {
          return {
            ...item,
            preview: result?.assets?.[index]?.uri
          }
        }));
      } catch (error) {
        Alert.alert('错误', '部分文件处理失败，请重试');
      } finally {
        setIsLoading(false);
      }

    } catch (error) {
      Alert.alert('错误', '选择图片时出错，请重试');
    } finally {
      setIsLoading(false);
    }
  };

  // 在组件卸载时清理已完成的上传
  useEffect(() => {
    return () => {
      // 只保留未完成的上传项
      setUploadQueue(prev =>
        prev.filter(item =>
          item.status === 'uploading' || item.status === 'pending'
        )
      );
    };
  }, []);


  return (
    <View style={[style]}>
      {children ? (
        <TouchableOpacity onPress={pickImage} disabled={isLoading} activeOpacity={0.7}>
          {children}
        </TouchableOpacity>
      ) : (
        <Button
          title={isLoading ? '处理中...' : '选择图片'}
          onPress={pickImage}
          disabled={isLoading}
        />
      )}

      {/* 上传预览 */}
      {showPreview && <UploadPreview items={uploadQueue} />}
    </View>
  );
};

export default ImagesUploader;