import 'dart:ffi';
import 'dart:io';
import 'package:ffi/ffi.dart';

class WindowsProxyManager {
  final DynamicLibrary _winInet = DynamicLibrary.open("wininet.dll");

  late final int Function(int, int, Pointer<Void>, Pointer<Uint32>) _internetQueryOption;
  late final int Function(int, int, Pointer<Void>, int) _internetSetOption;

  WindowsProxyManager() {
    _initializeFunctions();
  }

  void _initializeFunctions() {
    _internetQueryOption = _winInet
        .lookup<NativeFunction<Int32 Function(IntPtr, Uint32, Pointer<Void>, Pointer<Uint32>)>>(
        'InternetQueryOptionW')
        .asFunction();

    _internetSetOption = _winInet
        .lookup<NativeFunction<Int32 Function(IntPtr, Uint32, Pointer<Void>, Uint32)>>(
        'InternetSetOptionW')
        .asFunction();
  }

  bool isProxyEnabled() {
    final optionList = calloc<INTERNET_PER_CONN_OPTION_LIST>();
    optionList.ref.dwSize = sizeOf<INTERNET_PER_CONN_OPTION_LIST>();
    optionList.ref.dwOptionCount = 1;
    optionList.ref.dwOptionError = 0;

    final options = calloc<INTERNET_PER_CONN_OPTION>(1);
    options[0].dwOption = INTERNET_OPTION_PROXY_ENABLE;

    optionList.ref.pOptions = options;

    final optionSize = calloc<Uint32>()..value = sizeOf<INTERNET_PER_CONN_OPTION_LIST>();
    final result = _internetQueryOption(0, INTERNET_OPTION_PER_CONNECTION_OPTION, optionList.cast<Void>(), optionSize);

    bool isEnabled = false;
    if (result != 0) {
      isEnabled = options[0].Value.dwValue != 0;
    } else {
      print("检测代理状态失败。");
    }

    calloc.free(optionList);
    calloc.free(options);
    calloc.free(optionSize);

    return isEnabled;
  }

  void setSystemProxy(String proxyServer, {String bypassList = ""}) {
    final proxyInfo = calloc<INTERNET_PER_CONN_OPTION_LIST>();
    proxyInfo.ref.dwSize = sizeOf<INTERNET_PER_CONN_OPTION_LIST>();
    proxyInfo.ref.dwOptionCount = 3; // 设置为3个选项
    proxyInfo.ref.dwOptionError = 0;

    // 分配三个选项的空间
    final options = calloc<INTERNET_PER_CONN_OPTION>(3);

    // 启用代理
    options[0].dwOption = INTERNET_OPTION_PROXY_ENABLE;
    options[0].Value.dwValue = 1; // 1 表示启用代理

    // 设置代理服务器
    options[1].dwOption = INTERNET_OPTION_PROXY_SERVER;
    options[1].Value.pszValue = proxyServer.toNativeUtf16();

    // 设置绕过列表
    options[2].dwOption = INTERNET_OPTION_PROXY_BYPASS;
    options[2].Value.pszValue = bypassList.toNativeUtf16();

    proxyInfo.ref.pOptions = options;

    // 调用 API 设置代理
    final result = _internetSetOption(
      0,
      INTERNET_OPTION_PER_CONNECTION_OPTION,
      proxyInfo.cast<Void>(),
      proxyInfo.ref.dwSize,
    );

    if (result != 0) {
      _internetSetOption(0, INTERNET_OPTION_SETTINGS_CHANGED, nullptr, 0);
      _internetSetOption(0, INTERNET_OPTION_REFRESH, nullptr, 0);
      print("系统代理已设置为: $proxyServer");
    } else {
      print("设置代理失败。");
    }

    // 释放内存
    calloc.free(proxyInfo);
    calloc.free(options[1].Value.pszValue);  // 只释放字符串指针
    calloc.free(options[2].Value.pszValue);  // 只释放字符串指针
    calloc.free(options);
  }


  void disableSystemProxy() {
    final proxyInfo = calloc<INTERNET_PER_CONN_OPTION_LIST>();
    proxyInfo.ref.dwSize = sizeOf<INTERNET_PER_CONN_OPTION_LIST>();
    proxyInfo.ref.dwOptionCount = 1;
    proxyInfo.ref.dwOptionError = 0;

    final options = calloc<INTERNET_PER_CONN_OPTION>(1);

    // 禁用代理
    options[0].dwOption = INTERNET_OPTION_PROXY_ENABLE;
    options[0].Value.dwValue = 0;

    proxyInfo.ref.pOptions = options;

    final result = _internetSetOption(
      0,
      INTERNET_OPTION_SETTINGS_CHANGED,
      proxyInfo.cast<Void>(),
      proxyInfo.ref.dwSize,
    );

    if (result != 0) {
      _internetSetOption(0, INTERNET_OPTION_REFRESH, nullptr, 0);
      print("系统代理已禁用");
    } else {
      print("禁用代理失败。");
    }

    calloc.free(proxyInfo);
    calloc.free(options);
  }
}

// INTERNET_PER_CONN_OPTION_LIST 结构定义
base class INTERNET_PER_CONN_OPTION_LIST extends Struct {
  @Uint32()
  external int dwSize;
  @IntPtr()
  external int pszConnection;
  @Uint32()
  external int dwOptionCount;
  @Uint32()
  external int dwOptionError;
  external Pointer<INTERNET_PER_CONN_OPTION> pOptions;
}

base class INTERNET_PER_CONN_OPTION extends Struct {
  @Uint32()
  external int dwOption;
  external INTERNET_PER_CONN_OPTION_Union Value;
}

base class INTERNET_PER_CONN_OPTION_Union extends Union {
  @Uint32()
  external int dwValue;
  external Pointer<Utf16> pszValue;
}

// 常量定义
const INTERNET_OPTION_PROXY_ENABLE = 3;
const INTERNET_OPTION_PROXY_SERVER = 2;
const INTERNET_OPTION_PROXY_BYPASS = 3;
const INTERNET_OPTION_SETTINGS_CHANGED = 39;
const INTERNET_OPTION_REFRESH = 37;
const INTERNET_OPTION_PER_CONNECTION_OPTION = 75;

// void main() {
//   if (Platform.isWindows) {
//     final proxyManager = WindowsProxyManager();
//
//     // 检测当前系统代理状态
//     bool isProxyEnabled = proxyManager.isProxyEnabled();
//     print("系统代理启用状态: ${isProxyEnabled ? "已启用" : "未启用"}");
//
//     // 设置系统代理
//     proxyManager.setSystemProxy("http=127.0.0.1:8888;https=127.0.0.1:8888", bypassList: "<local>");
//
//     // 再次检测代理状态
//     isProxyEnabled = proxyManager.isProxyEnabled();
//     print("系统代理启用状态: ${isProxyEnabled ? "已启用" : "未启用"}");
//
//     // 禁用系统代理
//     proxyManager.disableSystemProxy();
//
//     // 最后检测代理状态
//     isProxyEnabled = proxyManager.isProxyEnabled();
//     print("系统代理启用状态: ${isProxyEnabled ? "已启用" : "未启用"}");
//   } else {
//     print("该代码仅支持 Windows 平台.");
//   }
// }