import 'dart:io';
import 'dart:math';

import 'package:classify_photo/classify_photo.dart';
import 'package:clean/data/bean/photos_type.dart';
import 'package:clean/model/asset_group.dart';
import 'package:clean/module/locations_photo/locations_photo_controller.dart';
import 'package:clean/module/locations_photo/locations_single_photo_controller.dart';
import 'package:clean/module/people_photo/people_photo_controller.dart';
import 'package:clean/module/people_photo/photo_group.dart';
import 'package:clean/module/photo_preview/photo_preview_controller.dart';
import 'package:clean/module/screenshots_blurry/screenshots_controller.dart';
import 'package:clean/module/similar_photo/similar_photo_controller.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'package:photo_manager/photo_manager.dart';

import '../../handler/photo_scan_handler.dart';
import '../calendar/calendar_state.dart';
import '../home/home_controller.dart';

class ImagePickerUtil {
  ImagePickerUtil._();

  static const RequestType permissionType = RequestType.image;

  static final RxInt similarPhotoCount = 0.obs;

  // 全局存储不同类型的照片
  // 截图图片
  static final RxList<AssetEntity> screenshotPhotos = <AssetEntity>[].obs;

  // 模糊图片
  static final RxList<AssetEntity> blurryPhotos = <AssetEntity>[].obs;

  // 相似图片
  static final RxList<List<AssetEntity>> similarPhotos =
      <List<AssetEntity>>[].obs;

  // 地点图片
  static final RxMap<String, List<AssetEntity>> locationPhotos =
      <String, List<AssetEntity>>{}.obs;

  // 人物图片
  static final RxList<AssetEntity> peoplePhotos = <AssetEntity>[].obs;

  // android测试

  static late List<AssetEntity> androidPhotos = <AssetEntity>[];

  static final RxSet<String> selectedScreenshotPhotosIds = <String>{}.obs;
  static final RxSet<String> selectedSimilarPhotosIds = <String>{}.obs;
  static final RxSet<String> selectedLocationPhotosIds = <String>{}.obs;
  static final RxSet<String> selectedPeoplePhotosIds = <String>{}.obs;
  static final RxSet<String> selectedBlurryPhotosIds = <String>{}.obs;

  // 添加大小信息的变量
  static final Rx<int> screenshotsSize = 0.obs;
  static final Rx<int> blurrySize = 0.obs;
  static final Rx<int> locationsSize = 0.obs;
  static final Rx<int> peopleSize = 0.obs;
  static final Rx<int> similarPhotosSize = 0.obs;

  // // 用来缓存文件大小
  // static final Map<String, double> fileSizeCache = {};

  // 清除所有照片数据
  static void clearAllPhotos() {
    screenshotPhotos.clear();
    blurryPhotos.clear();
    similarPhotos.clear();
    locationPhotos.clear();
    peoplePhotos.clear();
  }

  static Future<void> updatePhotoGroupDate(
      PhotosType photosType, Set<String> selectedPhotosIds1) async {
    // 1. 统一移除相关的照片列表
    debugPrint(
        "updatePhotoGroupDate1 ScreenshotsController screenshotController $selectedPhotosIds1");
    // 2. 移除控制器中的数据
    Set<String> selectedPhotosIds = Set.from(selectedPhotosIds1);
    updatePhotoData(selectedPhotosIds);

    debugPrint(
        "updatePhotoGroupDate2 ScreenshotsController screenshotController $selectedPhotosIds");
    // 3. 根据photosType来处理不同的控制器和photoGroups
    switch (photosType) {
      case PhotosType.screenshots:
        ScreenShotsController screenshotController =
            Get.find<ScreenShotsController>();
        removeImagesAndEmptyGroups(screenshotController, selectedPhotosIds);
        selectedScreenshotPhotosIds
            .removeWhere((element) => selectedPhotosIds.contains(element));
        screenshotController.restoreSelections();
        break;

      case PhotosType.similarPhotos:
        SimilarPhotoController similarController =
            Get.find<SimilarPhotoController>();
        removeImagesAndEmptyGroups(similarController, selectedPhotosIds);
        selectedSimilarPhotosIds
            .removeWhere((element) => selectedPhotosIds.contains(element));
        similarController.restoreSelections();
        break;

      case PhotosType.locationPhotos:
        LocationsSinglePhotoController locationsSingleController =
            Get.find<LocationsSinglePhotoController>();
        LocationsPhotoController locationsPhotoController =
            Get.find<LocationsPhotoController>();
        removeImagesAndEmptyGroups(
            locationsSingleController, selectedPhotosIds);
        removeImagesAndEmptyGroups(locationsPhotoController, selectedPhotosIds);
        selectedLocationPhotosIds
            .removeWhere((element) => selectedPhotosIds.contains(element));
        locationsSingleController.restoreSelections();
        locationsPhotoController.restoreSelections();
        break;

      case PhotosType.peoplePhotos:
        PeoplePhotoController peoplePhotoController =
            Get.find<PeoplePhotoController>();
        removeImagesAndEmptyGroups(peoplePhotoController, selectedPhotosIds);
        selectedPeoplePhotosIds
            .removeWhere((element) => selectedPhotosIds.contains(element));
        peoplePhotoController.restoreSelections();
        break;

      case PhotosType.blurryPhotos:
        ScreenShotsController blurryController =
            Get.find<ScreenShotsController>();
        removeImagesAndEmptyGroups(blurryController, selectedPhotosIds);
        selectedBlurryPhotosIds
            .removeWhere((element) => selectedPhotosIds.contains(element));
        blurryController.restoreSelections();
        break;
    }
  }

  // 移除每组图片里面对应的元素并删除空的组
  static void removeImagesAndEmptyGroups(
      dynamic controller, Set<String> selectedPhotosIds) {
    // 创建photoGroups的副本进行遍历，避免遍历过程中修改photoGroups
    for (var group in List.from(controller.photoGroups)) {
      // 移除所有与selectedPhotosIds匹配的图片
      group.images.removeWhere((image) => selectedPhotosIds.contains(image.id));

      // 如果当前组内没有图片了，删除该组
      if (group.images.isEmpty) {
        controller.photoGroups.remove(group);
      }
    }
  }

  static void updatePhotoData(Set<String> selectedPhotosIds1) {
    debugPrint("ImagePickerUtil1 updatePhotoData  $selectedPhotosIds1");
    Set<String> selectedPhotosIds = Set.from(selectedPhotosIds1);
    screenshotPhotos
        .removeWhere((element) => selectedPhotosIds.contains(element.id));
    for (var group in similarPhotos) {
      group.removeWhere((element) => selectedPhotosIds.contains(element.id));
    }
    locationPhotos.forEach((key, group) =>
        group.removeWhere((element) => selectedPhotosIds.contains(element.id)));
    peoplePhotos
        .removeWhere((element) => selectedPhotosIds.contains(element.id));
    blurryPhotos
        .removeWhere((element) => selectedPhotosIds.contains(element.id));
    // 2. 移除空的集合
    similarPhotos.removeWhere((element) => element.isEmpty);
    locationPhotos.removeWhere((key, value) => value.isEmpty);

    debugPrint("ImagePickerUtil2 updatePhotoData  $selectedPhotosIds");
    selectedScreenshotPhotosIds
        .removeWhere((element) => selectedPhotosIds.contains(element));
    selectedSimilarPhotosIds
        .removeWhere((element) => selectedPhotosIds.contains(element));
    selectedLocationPhotosIds
        .removeWhere((element) => selectedPhotosIds.contains(element));
    selectedPeoplePhotosIds
        .removeWhere((element) => selectedPhotosIds.contains(element));
    selectedBlurryPhotosIds
        .removeWhere((element) => selectedPhotosIds.contains(element));

    if (PhotoScanHandler.locationPhoto.value != null &&
        selectedPhotosIds.contains(PhotoScanHandler.locationPhoto.value!.id)) {
      PhotoScanHandler.locationPhoto.value = null;
      if (locationPhotos.isNotEmpty) {
        var asset = locationPhotos.values.first.first;
        PhotoScanHandler.locationPhoto.value = asset;
      }
    }
    if (PhotoScanHandler.screenshotPhoto.value != null &&
        selectedPhotosIds
            .contains(PhotoScanHandler.screenshotPhoto.value!.id)) {
      PhotoScanHandler.screenshotPhoto.value = null;
      if (screenshotPhotos.isNotEmpty) {
        var asset = screenshotPhotos.first;
        PhotoScanHandler.screenshotPhoto.value = asset;
      }
    }
    if (PhotoScanHandler.blurryPhoto.value != null &&
        selectedPhotosIds.contains(PhotoScanHandler.blurryPhoto.value!.id)) {
      PhotoScanHandler.blurryPhoto.value = null;
      if (blurryPhotos.isNotEmpty) {
        var asset = blurryPhotos.first;
        PhotoScanHandler.blurryPhoto.value = asset;
      }
    }
    PhotoScanHandler.similarPhotos
        .removeWhere((element) => selectedPhotosIds.contains(element.id));
    if (PhotoScanHandler.locationPhoto.value != null &&
        selectedPhotosIds.contains(PhotoScanHandler.locationPhoto.value!.id)) {
      PhotoScanHandler.locationPhoto.value = null;
    }
    if (similarPhotos.isNotEmpty) {
      for (var group in ImagePickerUtil.similarPhotos) {
        for (var asset in group) {
          PhotoScanHandler.similarPhotos.add(asset);
          if (PhotoScanHandler.similarPhotos.length == 4) {
            break;
          }
        }
      }
    }

    PhotoScanHandler.peoplePhotos
        .removeWhere((element) => selectedPhotosIds.contains(element.id));
    if (peoplePhotos.isNotEmpty) {
      for (var personPhotos in peoplePhotos) {
        PhotoScanHandler.peoplePhotos.add(personPhotos);
        if (PhotoScanHandler.peoplePhotos.length == 2) {
          break;
        }
      }
    }

    debugPrint("ImagePickerUtil3  updatePhotoData $selectedPhotosIds");
    CalendarState.removePhotosData(selectedPhotosIds);
  }

  // 更新照片数据
  static Future<void> updatePhotos(
      List<Map<String, dynamic>> photoGroups) async {
    // clearAllPhotos();

    for (var group in photoGroups) {
      String type = group['type'] as String;
      Map<dynamic, dynamic> groupData = group['group'] as Map<dynamic, dynamic>;
      List<dynamic> photos = groupData['photos'] as List<dynamic>;
      int totalSize = groupData['totalSize'] as int;
      int count = groupData['count'] as int;

      switch (type) {
        case 'screenshots':
          screenshotPhotos.clear();
          screenshotPhotos.value = await _convertToAssetEntities(photos);
          screenshotsSize.value = totalSize;
          break;
        case 'similar':
          similarPhotos.add(await _convertToAssetEntities(photos));
          similarPhotosSize.value = totalSize;
          similarPhotoCount.value = count;
          break;
        case 'location':
          String location = group['name'] as String;
          locationPhotos[location] = await _convertToAssetEntities(photos);
          locationsSize.value = totalSize;
          break;
        case 'people':
          peoplePhotos.clear();
          peoplePhotos.value = await _convertToAssetEntities(photos);
          peopleSize.value = totalSize;
          break;
        case 'blurry':
          blurryPhotos.clear();
          blurryPhotos.value = await _convertToAssetEntities(photos);
          blurrySize.value = totalSize;
          break;
      }
    }
  }

  // 将原始照片数据转换为 AssetEntity 列表
  static Future<List<AssetEntity>> _convertToAssetEntities(
      List<dynamic> photos) async {
    List<AssetEntity> entities = [];
    for (var photo in photos) {
      final entity = await AssetEntity.fromId(photo['id'] as String);
      if (entity != null) {
        entities.add(entity);
      }
    }
    return entities;
  }

  //申请权限
  static Future<bool> requestPermissionExtend() async {
    final PermissionState ps = await PhotoManager.requestPermissionExtend(
        requestOption: const PermissionRequestOption(
            androidPermission: AndroidPermission(
      type: permissionType,
      mediaLocation: false,
    )));
    return ps.hasAccess;
  }

  //判断是否有权限
  static Future<bool> hasPermission() async {
    final PermissionState ps = await PhotoManager.getPermissionState(
        requestOption: const PermissionRequestOption(
            androidPermission: AndroidPermission(
      type: permissionType,
      mediaLocation: false,
    )));
    return ps.hasAccess;
  }

  static String formatFileSize(int bytes, {int decimals = 2}) {
    if (bytes <= 0) return '0 B';

    const suffixes = ['B', 'KB', 'MB', 'GB', 'TB'];
    var i = (log(bytes) / log(1024)).floor();

    // 确保不超过数组范围
    i = i < suffixes.length ? i : suffixes.length - 1;

    // 计算实际大小
    final size = bytes / pow(1024, i);

    // 格式化数字，处理小数点位数
    String sizeStr;
    if (size >= 100) {
      // 大于100的只保留整数
      sizeStr = size.round().toString();
    } else {
      // 小于100的保留指定小数位
      sizeStr = size.toStringAsFixed(decimals);
    }

    // 移除末尾的0和不必要的小数点
    sizeStr = sizeStr.replaceAll(RegExp(r'\.?0+$'), '');

    return '$sizeStr ${suffixes[i]}';
  }

  /// 直接转换为 GB 单位
  static String formatToGB(int bytes, {int decimals = 2}) {
    if (bytes <= 0) return '0 GB';

    final gb = bytes / pow(1024, 3); // 直接转换为 GB

    // 格式化数字，处理小数点位数
    String sizeStr;
    if (gb >= 100) {
      // 大于100的只保留整数
      sizeStr = gb.round().toString();
    } else {
      // 小于100的保留指定小数位
      sizeStr = gb.toStringAsFixed(decimals);
    }

    // 移除末尾的0和不必要的小数点
    sizeStr = sizeStr.replaceAll(RegExp(r'\.?0+$'), '');

    return '$sizeStr GB';
  }

  /// 格式化存储大小
  static String formatSize(double sizeInGB) {
    if (sizeInGB < 0.001) {
      // 小于 1MB
      return '${(sizeInGB * 1024 * 1024).toStringAsFixed(1)} ';
    } else if (sizeInGB < 1) {
      // 小于 1GB
      return '${(sizeInGB * 1024).toStringAsFixed(1)} ';
    } else if (sizeInGB < 1024) {
      // 小于 1TB
      return '${sizeInGB.toStringAsFixed(1)} ';
    } else {
      // 大于等于 1TB
      return '${(sizeInGB / 1024).toStringAsFixed(1)} ';
    }
  }

  // 加载图片资源
  static Future<List<AssetEntity>> loadAssets({bool sortByDate = true}) async {
    final PermissionState result = await PhotoManager.requestPermissionExtend();
    if (!result.hasAccess) return [];

    if (androidPhotos.isNotEmpty) return androidPhotos;
    // 选择相册
    final List<AssetPathEntity> albums = await PhotoManager.getAssetPathList(
      type: RequestType.common,
      filterOption: FilterOptionGroup(
        orders: [
          // 根据创建日期排序，降序（最新的在前）
          OrderOption(
            type: OrderOptionType.createDate,
            asc: !sortByDate, // 是否升序排列
          ),
        ],
      ),
    );

    int assetCount = await albums.first.assetCountAsync;

    debugPrint("ImagePickerUtil loadAssets assetCount $assetCount");
    androidPhotos = await albums.first.getAssetListPaged(
      page: 0,
      size: assetCount,
    );

    return androidPhotos;
  }
}
