import 'dart:io';
import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:dio/io.dart';
import 'package:path/path.dart' as path;
import 'package:dio/dio.dart';

import 'developer/ix_developer_tools.dart';

class FileStreamUtils {
  static const int defaultBufferSize = 64 * 1024;

  static final Dio dio = Dio();

  static setProxy(String proxy) {
    dio.httpClientAdapter = IOHttpClientAdapter(
      createHttpClient: () {
        final client = HttpClient();
        client.findProxy = (uri) => proxy;
        client.badCertificateCallback =
            (X509Certificate cert, String host, int port) => true;
        return client;
      },
    );
  }

  /// 读取文件（支持本地文件和网络URL）
  /// [path] 文件路径或URL
  /// [encoding] 文件编码，默认UTF8
  /// [onProgress] 读取进度回调
  static Future<FileReadResult> readTextFile({
    required String path,
    Encoding encoding = utf8,
    void Function(double progress)? onProgress,
  }) async {
    if (path.startsWith('http://') || path.startsWith('https://')) {
      return _readFromUrl(
        url: path,
        encoding: encoding,
        onProgress: onProgress,
      );
    } else {
      return _readFromFile(
        filePath: path,
        encoding: encoding,
        onProgress: onProgress,
      );
    }
  }

  /// 从URL读取
  static Future<FileReadResult> _readFromUrl({
    required String url,
    required Encoding encoding,
    void Function(double progress)? onProgress,
  }) async {
    try {
      // 添加talker日志
      dio.interceptors.add(SimpleNoSignApiMonitorInterceptor());
      final response = await dio.get<List<int>>(
        url,
        options: Options(
          responseType: ResponseType.bytes,
          followRedirects: true,
        ),
        onReceiveProgress: (received, total) {
          if (total != -1 && onProgress != null) {
            onProgress(received / total);
          }
        },
      );

      if (response.data == null) {
        throw Exception('No data received');
      }

      final bytes = response.data!;
      final content = encoding.decode(bytes);
      final md5Hash = md5.convert(bytes).toString();

      return FileReadResult(
        content: content,
        md5Hash: md5Hash,
        fileName: path.basename(url),
        fileSize: bytes.length,
      );
    } catch (e) {
      throw Exception('Error downloading file: $e');
    }
  }

  /// 从本地文件读取
  static Future<FileReadResult> _readFromFile({
    required String filePath,
    required Encoding encoding,
    void Function(double progress)? onProgress,
  }) async {
    try {
      final file = File(filePath);
      if (!await file.exists()) {
        throw FileSystemException('File not found', filePath);
      }

      final fileSize = await file.length();
      var bytesRead = 0;
      final List<int> allBytes = [];
      final StringBuffer content = StringBuffer();

      final stream = file.openRead();
      await for (var data in stream) {
        allBytes.addAll(data);
        content.write(encoding.decode(data));

        bytesRead += data.length;
        if (onProgress != null) {
          onProgress(bytesRead / fileSize);
        }
      }

      final md5Hash = md5.convert(allBytes).toString();

      return FileReadResult(
        content: content.toString(),
        md5Hash: md5Hash,
        fileName: path.basename(filePath),
        fileSize: fileSize,
      );
    } catch (e) {
      throw FileSystemException('Error reading file: $e', filePath);
    }
  }

  /// 验证文件或URL的MD5
  static Future<bool> verifyMd5({
    required String path,
    required String expectedMd5,
    void Function(double progress)? onProgress,
  }) async {
    try {
      final result = await readTextFile(path: path, onProgress: onProgress);
      return result.md5Hash.toLowerCase() == expectedMd5.toLowerCase();
    } catch (e) {
      return false;
    }
  }

  /// 获取文件或URL的MD5
  static Future<String?> getMd5({
    required String path,
    void Function(double progress)? onProgress,
  }) async {
    try {
      final result = await readTextFile(path: path, onProgress: onProgress);
      return result.md5Hash;
    } catch (e) {
      return null;
    }
  }
}

/// 文件读取结果
class FileReadResult {
  final String content; // 文件内容
  final String md5Hash; // MD5值
  final String fileName; // 文件名
  final int fileSize; // 文件大小

  FileReadResult({
    required this.content,
    required this.md5Hash,
    required this.fileName,
    required this.fileSize,
  });

  @override
  String toString() {
    return 'FileReadResult{fileName: $fileName, fileSize: $fileSize, md5Hash: $md5Hash}';
  }
}
