import 'dart:ffi';

import 'package:classify_photo/classify_photo.dart';
import 'package:flutter/cupertino.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
import 'package:photo_manager/photo_manager.dart';

class FileSizeCalculatorUtil {
  static final Map<String, double> fileSizeCache = {};

  static Future<void> calculateTotalSizeByIOS({
    required Set<String> assetIds,
    required Function(double) updateValue,
  }) async {
    if (assetIds.isEmpty) {
      updateValue(0);
      return;
    }
    double totalSize = 0;
    totalSize = await ClassifyPhoto().calculatePhotosSize(assetIds.toList()) / 1024;
    updateValue(totalSize);
  }

  static Future<void> calculateTotalSize({
    required Set<String> assetIds,
    required Function(double) updateValue,
  }) async {
    if (assetIds.isEmpty) {
      updateValue(0);
      return;
    }
    double totalSize = 0;
    final uncasedIds =
        assetIds.where((id) => !fileSizeCache.containsKey(id)).toSet();
    // **1️⃣ 先处理缓存中的文件**
    totalSize = assetIds.fold(0, (prev, id) => prev + (fileSizeCache[id] ?? 0));
    updateValue(totalSize);

    // **2️⃣ 分批处理未缓存的文件**
    const batchSize = 20;
    for (int i = 0; i < uncasedIds.length; i += batchSize) {
      if (assetIds.isEmpty) {
        updateValue(0);
        return;
      }

      final batch = uncasedIds.skip(i).take(batchSize);
      final sizes =
          await Future.wait(batch.map(FileSizeCalculatorUtil.getFileSize));

      totalSize += sizes.fold(0, (sum, size) => sum + size);

      // **再检查一次是否被清空，避免无意义计算**
      if (assetIds.isEmpty) {
        updateValue(0);
        return;
      }

      await Future.delayed(Duration.zero);
      updateValue(totalSize);
    }
    updateValue(totalSize);
  }

  /// 获取文件大小
  static Future<double> getFileSize(String assetId) async {
    if (fileSizeCache.containsKey(assetId)) {
      return fileSizeCache[assetId]!;
    }

    final entity = await AssetEntity.fromId(assetId);
    if (entity == null) return 0;

    final file = await entity.file;
    if (file == null) return 0;

    if (!await file.exists()) {
      return 0;
    }
    try {
      final double size = (await file.length()) / 1024;
      fileSizeCache[assetId] = size;

      try {
        await file.delete();
      } catch (e) {
        debugPrint("Delete file error: $e");
      }

      if (size <= 0) {
        return 0;
      }
      return size;
    } catch (e) {
      return 0;
    }
  }
}
