import 'dart:convert';

import 'package:archive/archive.dart';
import 'package:dio/dio.dart';
import 'package:uuid/uuid.dart';
import '../../../utils/crypto.dart';
import '../../../utils/developer/ix_developer_tools.dart';
import '../../../utils/log/logger.dart';
import '../../constants/keys.dart';
import '../../data/models/api_exception.dart';
import '../../data/models/api_result.dart';
import '../../data/sp/ix_sp.dart';
import '../base/base_api.dart';

import '../core/api_core_paths.dart';

/// 核心API
class ApiFile extends BaseApi {
  static final _instance = ApiFile._internal();

  factory ApiFile() => _instance;

  ApiFile._internal() {
    _initDio();
  }

  /// 初始化Dio
  void _initDio() {
    // 此处可以设置默认的DIO参数
    final options = BaseOptions();
    options.connectTimeout = const Duration(seconds: 90);
    options.receiveTimeout = const Duration(seconds: 90);
    options.responseType = ResponseType.bytes;
    options.headers['content-type'] = 'multipart/form-data';

    dio = Dio(options);

    // 添加talker日志
    dio.interceptors.add(SimpleApiMonitorInterceptor());

    // 添加拦截器
    _setupInterceptors();
  }

  // bool _isRefreshing = false;

  void _setupInterceptors() {
    dio.interceptors.add(
      InterceptorsWrapper(
        onRequest: (options, handler) async {
          // 在请求发送前添加token
          final user = IXSP.getUser();
          if (user != null) {
            options.headers['Authorization'] = user.accessToken;
          }
          return handler.next(options);
        },
        onError: (DioException error, handler) async {
          return handler.next(error);
        },
      ),
    );
  }

  @override
  Map<String, dynamic>? getDefaultHeader() {
    // 可以设置自定义Header
    final headers = {
      'X-NL-Product-Code': 'flashlink',
      'X-NL-Content-Encoding': 'gzip',
    };
    return headers;
  }

  @override
  Map<String, dynamic>? getDefaultQuery() {
    // 可以设置自定义Query
    return null;
  }

  @override
  dynamic encrypt(dynamic input) {
    return input;
  }

  @override
  dynamic decrypt(dynamic input) {
    try {
      final decryptedBytes = Crypto.decryptBytes(
        base64Encode(input),
        Keys.aesKey,
        Keys.aesIv,
      );
      // 使用GZip解压
      final gzipDecoder = GZipDecoder();
      final decodeBytes = gzipDecoder.decodeBytes(decryptedBytes);
      final data = utf8.decode(decodeBytes);
      log('ApiCore', '<<:$data');
      return jsonDecode(data);
    } catch (error) {
      throw ApiException("-2", "decrypt error: $error");
    }
  }

  // 上传日志文件
  Future<ApiResult> uploadLogFile(
    String filePath,
    String fileName,
    String logType,
    String data,
  ) async {
    final fileData = await MultipartFile.fromFile(filePath, filename: fileName);
    const fileType = 'gzip';
    final timestamp = DateTime.now().millisecondsSinceEpoch;
    final sign = Crypto.encrypt(
      '$fileType$logType$timestamp',
      Keys.aesKey,
      Keys.aesIv,
    );
    if (logType == "App_NL_Log") {
      final logId = const Uuid().v4();
      final userInfo = Crypto.encrypt(data, Keys.aesKey, Keys.aesIv);
      final formData = FormData.fromMap({
        'file': fileData,
        'fileName': fileName,
        'fileType': fileType,
        'logType': logType,
        'timestamp': timestamp,
        'sign': sign,
        'userInfo': userInfo,
        'logId': logId,
      });
      return post(
        ApiCorePaths.uploadFile,
        data: formData,
        domainType: DomainType.file,
      );
    } else {
      final formData = FormData.fromMap({
        'file': fileData,
        'fileName': fileName,
        'fileType': fileType,
        'timestamp': timestamp,
        'logType': logType,
        'sign': sign,
      });
      return post(
        ApiCorePaths.uploadFile,
        data: formData,
        domainType: DomainType.file,
      );
    }
  }

  // 上传图片文件
  Future<ApiResult> uploadImageFile(String filePath, String fileName) async {
    final fileData = await MultipartFile.fromFile(filePath, filename: fileName);
    const fileType = 'image';
    final timestamp = DateTime.now().millisecondsSinceEpoch;
    final sign = Crypto.encrypt('$fileType$timestamp', Keys.aesKey, Keys.aesIv);
    final formData = FormData.fromMap({
      'file': fileData,
      'fileType': fileType,
      'timestamp': timestamp,
      'sign': sign,
    });
    return post(
      ApiCorePaths.uploadImage,
      data: formData,
      domainType: DomainType.file,
    );
  }

  // 上传视频文件
  Future<ApiResult> uploadVideoFile(String filePath, String fileName) async {
    final fileData = await MultipartFile.fromFile(filePath, filename: fileName);
    const fileType = 'video';
    final timestamp = DateTime.now().millisecondsSinceEpoch;
    final sign = Crypto.encrypt('$fileType$timestamp', Keys.aesKey, Keys.aesIv);
    final formData = FormData.fromMap({
      'file': fileData,
      'fileType': fileType,
      'timestamp': timestamp,
      'sign': sign,
    });
    return post(
      ApiCorePaths.uploadVideo,
      data: formData,
      domainType: DomainType.file,
    );
  }

  // 上传多个图片文件
  Future<ApiResult> uploadMultipleImageFiles(
    List<String> filePaths,
    List<String> fileNames,
  ) async {
    final List<MultipartFile> files = [];
    for (int i = 0; i < filePaths.length; i++) {
      final fileData = await MultipartFile.fromFile(
        filePaths[i],
        filename: fileNames[i],
      );
      files.add(fileData);
    }

    const fileType = 'image';
    final timestamp = DateTime.now().millisecondsSinceEpoch;
    final sign = Crypto.encrypt('$fileType$timestamp', Keys.aesKey, Keys.aesIv);

    final formData = FormData.fromMap({
      'file': files,
      'fileType': fileType,
      'timestamp': timestamp,
      'sign': sign,
    });

    return post(
      ApiCorePaths.uploadImage,
      data: formData,
      domainType: DomainType.file,
    );
  }

  // 上传多个视频文件
  Future<ApiResult> uploadMultipleVideoFiles(
    List<String> filePaths,
    List<String> fileNames,
  ) async {
    final List<MultipartFile> files = [];
    for (int i = 0; i < filePaths.length; i++) {
      final fileData = await MultipartFile.fromFile(
        filePaths[i],
        filename: fileNames[i],
      );
      files.add(fileData);
    }

    const fileType = 'video';
    final timestamp = DateTime.now().millisecondsSinceEpoch;
    final sign = Crypto.encrypt('$fileType$timestamp', Keys.aesKey, Keys.aesIv);

    final formData = FormData.fromMap({
      'file': files,
      'fileType': fileType,
      'timestamp': timestamp,
      'sign': sign,
    });

    return post(
      ApiCorePaths.uploadVideo,
      data: formData,
      domainType: DomainType.file,
    );
  }
}
