import 'dart:io';
import 'package:injectable/injectable.dart';
import 'package:keyboard/utils/atmob_log.dart';
import 'package:keyboard/utils/upload/upload_scene_type.dart';
import 'package:keyboard/utils/upload/upload_state.dart';
import 'package:keyboard/utils/uuid_util.dart';

import '../../data/api/response/upload_result_bean.dart';
import '../../data/bean/upload_info.dart';
import '../../data/repository/file_upload_repository.dart';
import '../file_util.dart';

/// 上传信息更新回调
typedef OnUploadInfoUpdateCallback = void Function(UploadInfo uploadInfo);

/// 上传失败时回调
typedef OnUploadFailCallback = void Function(dynamic error);

/// 文件上传管理器
@lazySingleton
class UploadFileManager {
  final String _tag = "UploadFileManager";

  /// 文件上传Repository
  FileUploadRepository fileUploadRepository;

  /// 上传信息队列
  final List<UploadInfo> _uploadInfoQueue = <UploadInfo>[];

  UploadFileManager(this.fileUploadRepository);

  /// 上传文件
  UploadInfo uploadFile({
    required UploadSceneType sceneType,
    required File file,
    OnUploadInfoUpdateCallback? onUploadInfoUpdateCallback,
    OnUploadFailCallback? onUploadFailCallback,
  }) {
    // 创建一个上传记录，添加到队列中
    UploadInfo uploadInfo = UploadInfo(
      // 唯一id
      id: UuidUtil.generateUuid(),
      // 文件名称
      fileName: FileUtil.getFileName(file),
      // 文件路径
      filePath: FileUtil.getFilePath(file),
      // 上传场景类型
      uploadSceneType: sceneType.name,
      // 上传状态
      uploadState: UploadState.uploading.name,
    );
    _uploadInfoQueue.add(uploadInfo);

    // 执行上传任务
    _doUploadFile(
      uploadInfo,
      onUploadInfoUpdateCallback: onUploadInfoUpdateCallback,
      onUploadFailCallback: onUploadFailCallback,
    );

    return uploadInfo;
  }

  /// 根据场景类型，批量删除上传记录
  void deleteUploadInfoBySceneType(UploadSceneType uploadSceneType) {
    _uploadInfoQueue.removeWhere((item) {
      return item.uploadSceneType == uploadSceneType.type;
    });
  }

  /// 删除某一个上传记录
  void deleteUploadInfo(UploadInfo uploadInfo) {
    _uploadInfoQueue.remove(uploadInfo);
  }

  /// 根据场景类型，获取上传记录列表
  List<UploadInfo> findUploadInfoList(UploadSceneType sceneType) {
    return _uploadInfoQueue.where((uploadInfo) {
      return uploadInfo.uploadSceneType == sceneType.name;
    }).toList();
  }

  /// 通过id，查找上传记录
  UploadInfo? findUploadInfo(String id) {
    for (var uploadInfo in _uploadInfoQueue) {
      if (uploadInfo.id == id) {
        return uploadInfo;
      }
    }
    return null;
  }

  /// 执行，上传文件
  void _doUploadFile(
    UploadInfo uploadInfo, {
    OnUploadInfoUpdateCallback? onUploadInfoUpdateCallback,
    OnUploadFailCallback? onUploadFailCallback,
  }) {
    File file = File(uploadInfo.filePath ?? "");
    fileUploadRepository
        .uploadImage(file: file)
        .then((UploadResultBean result) {
          AtmobLog.d(
            _tag,
            "上传文件成功 => 访问地址：${result.cdnPrefix}${result.filePath}",
          );
          // 设置Cdn前缀和后端文件地址
          uploadInfo.fileUrlCdnPrefix = result.cdnPrefix;
          uploadInfo.fileBackendPath = result.filePath;
          // 拼接远程访问Url
          uploadInfo.fileUrl = "${result.cdnPrefix}${result.filePath}";
          // 上传成功，更新状态为成功
          uploadInfo.uploadState = UploadState.success.name;
          if (onUploadInfoUpdateCallback != null) {
            onUploadInfoUpdateCallback(uploadInfo);
          }
        })
        .catchError((error) {
          AtmobLog.d(_tag, "上传文件失败，原因： => $error");
          // 上传失败，更新状态为失败
          uploadInfo.uploadState = UploadState.fail.name;
          if (onUploadInfoUpdateCallback != null) {
            onUploadInfoUpdateCallback(uploadInfo);
          }
          if (onUploadFailCallback != null) {
            onUploadFailCallback(error);
          }
        });
  }
}
