// ignore_for_file: avoid_print

import 'dart:io';
import 'package:dio/dio.dart';
import 'package:archive/archive.dart';
import 'package:naiyouwl/app/const/const.dart';
import 'package:path/path.dart' as path;

final dio = Dio();

// https://github.com/dart-lang/sdk/issues/31610
final assetsPath = path.normalize(path.join(Platform.script.toFilePath(), '../../assets'));
final binDir = Directory(path.join(assetsPath, 'bin'));
final depDir = Directory(path.join(assetsPath, 'dep'));

Future downloadLatestClashCore() async {
  const version = "v1.16.0";
  final String clashCoreName = 'clash.meta-${ClashName.platform}-${ClashName.arch}-cgo-$version';

// Fetching release info from the GitHub API
  final info = await dio.get('https://api.github.com/repos/MetaCubeX/Clash.Meta/releases/tags/$version');

// Extracting the download URL from the API response based on the asset name
  final Map<String, dynamic> latest = (info.data['assets'] as List<dynamic>)
      .firstWhere((it) => (it['name'] as String).contains(clashCoreName));
  final String downloadUrl = latest['browser_download_url'];

  //final String newName = 'clash-${ClashName.platform}-${ClashName.arch}';
  final String name = latest['name'];
  final tempFile = File(path.join(binDir.path, '$name.temp'));
  print('Downloading $name');
  await dio.download(downloadUrl, tempFile.path); // Use the obtained download URL
  print('Download Success');

  print('Unarchiving $name');
  final tempBetys = await tempFile.readAsBytes();
  if (name.contains('.gz')) {
    final bytes = GZipDecoder().decodeBytes(tempBetys);
    final String filePath = path.join(binDir.path, ClashName.name);
    await File(filePath).writeAsBytes(bytes);
    await Process.run('chmod', ['+x', filePath]);
  } else {
    final file = ZipDecoder().decodeBytes(tempBetys).first;
    await File(path.join(binDir.path, ClashName.name)).writeAsBytes(file.content);
  }
  await tempFile.delete();
  print('Unarchiv Success');
}
Future<void> downloadAndUnarchiveService() async {
 // const String token = "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"; // 请确保不在公共代码中硬编码这个token

  final serviceName = 'ccore-service-${ClashName.platform}-${ClashName.arch}';
  // "name" -> "ccore-service-darwin-amd64-v1.0.0.gz"
  //final newSericeName = "$serviceName-v1.0.0.gz";
  // 获取GitHub release信息
 // dio.options.headers["Authorization"] = "token $token";
  final response = await dio.get('https://api.github.com/repos/alroyso/core-service/releases/latest');
  final Map<String, dynamic> latest = (response.data['assets'] as List<dynamic>)
      .firstWhere((it) => (it['name'] as String).contains(serviceName));

  final downloadUrl = latest['browser_download_url'];

  print('Downloading $downloadUrl');

  final tempFile = File(path.join(binDir.path, '${latest['name']}.temp'));
  try
  {
    print(dio.options.headers);
    await dio.download(downloadUrl, tempFile.path);
  } catch (e){
    print(e);
    return;
  }
  print('Download Success');
  print('Unarchiving ${latest['name']}');

  final tempBytes = await tempFile.readAsBytes();

  if (latest['name'].contains('.gz')) {
    final bytes = GZipDecoder().decodeBytes(tempBytes);
    await File(path.join(binDir.path, serviceName)).writeAsBytes(bytes);
    final filePath = path.join(binDir.path, serviceName);
    await Process.run('chmod', ['+x', filePath]);
  } else {
    final file = ZipDecoder().decodeBytes(tempBytes).first;
    await File(path.join(binDir.path, file.name)).writeAsBytes(file.content);
  }
  await tempFile.delete();

  print('Unarchive Success');
}

Future downloadLatestClashService() async {
    final String serviceName = 'ccore-service-${ClashName.platform}-${ClashName.arch}';
  // // final info = await dio.get('https://api.github.com/repos/alroyso/clash-for-flutter-service/releases/latest');
  // // final Map<String, dynamic> latest = (info.data['assets'] as List<dynamic>).firstWhere((it) => (it['name'] as String).contains(serviceName));
  // //https://github.com/alroyso/clash-for-flutter-service/releases/download/untagged-8273cca760b55d0725ab/naiyou-service-darwin-arm64-v1.0.1.gz
  // var verion = 'v1.0.1';
  // final String name = 'naiyou-service-${ClashName.platform}-${ClashName.arch}-$verion.gz';
  // final tempFile = File(path.join(binDir.path, '$name.temp'));
  // var url = "https://github.com/alroyso/clash-for-flutter-service/releases/tag/untagged-8273cca760b55d0725ab";
  // print('Downloading $url/$name');
  // dio.options.headers["Authorization"] = "token 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";
  // await dio.download('$url/$name', tempFile.path);
  // print('Download Success');
  //
  // print('Unarchiving $name');
  // final tempBetys = await tempFile.readAsBytes();
  // if (name.contains('.gz')) {
  //   final bytes = GZipDecoder().decodeBytes(tempBetys);
  //   final String filePath = path.join(binDir.path, serviceName);
  //   await File(filePath).writeAsBytes(bytes);
  //   await Process.run('chmod', ['+x', filePath]);
  // } else {
  //   final file = ZipDecoder().decodeBytes(tempBetys).first;
  //   await File(path.join(binDir.path, file.name)).writeAsBytes(file.content);
  // }
  final String filePath = path.join(binDir.path, serviceName);
  await Process.run('chmod', ['+x', filePath]);
  //await tempFile.delete();
  print('Unarchiv Success');
}

Future downloadCountryMmdb() async {
  print('Downloading Country.mmdb');
  final String geoipFilePath = path.join(depDir.path, 'Country.mmdb');
  await dio.download('https://github.com/Dreamacro/maxmind-geoip/releases/latest/download/Country.mmdb', geoipFilePath);
  print('Download Success');


  final String geositedat = path.join(depDir.path, 'geosite.dat');
  await dio.download('https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat', geositedat);
  print('Download Success');

  final String geoip = path.join(depDir.path, 'geoip.dat');
  await dio.download('https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat', geoip);
  print('Download Success');
}

Future downloadWintun() async {
  print('Downloading Wintun');
  final File wintunFile = File(path.join(depDir.path, 'wintun.zip.temp'));
  await dio.download('https://www.wintun.net/builds/wintun-0.14.1.zip', wintunFile.path);
  print('Download Success');
  print('Unarchiving wintun.zip');
  final files = ZipDecoder().decodeBytes(await wintunFile.readAsBytes());
  final file = files.firstWhere((it) => it.name == 'wintun/bin/${ClashName.arch}/wintun.dll');
  await File(path.join(depDir.path, 'wintun.dll')).writeAsBytes(file.content);
  await wintunFile.delete();
  print('Unarchiv Success');
}

void main() async {
  if (!(await binDir.exists())) await binDir.create();
  if (!(await depDir.exists())) await depDir.create();

  await downloadLatestClashCore();
  await downloadAndUnarchiveService();

  await downloadCountryMmdb();
  if (Platform.isWindows) await downloadWintun();
}
