import 'dart:ffi';
import 'dart:io';

import 'package:flutter/services.dart';
import 'package:process_run/shell.dart';
import 'package:path/path.dart' as path;

import 'package:naiyouwl/app/const/const.dart';
import 'package:naiyouwl/app/utils/logger.dart';
import 'package:wl_base_help/wl_base_help.dart';

Future<void> killProcess(String name) async {
  log.debug("kill: ", name);
  if (Platform.isWindows) {
    await Process.run('taskkill', ["/F", "/FI", "IMAGENAME eq $name"]);
  } else {
    await Process.run('bash', ["-c", "ps -ef | grep $name | grep -v grep | awk '{print \$2}' | xargs kill -9"]);
  }
}


Future<bool> isRunningAsAdmin() async {
  final Shell shell = Shell();

  try {
    if (Platform.isWindows) {
      // Windows: 使用 "net session" 检查管理员权限
      final List<ProcessResult> results = await shell.run('net session');
      if (results.isNotEmpty && results[0].exitCode == 0) {
        return true;
      }
    } else if (Platform.isMacOS || Platform.isLinux) {
      // macOS / Linux: 使用 "id -u" 检查管理员权限
      final List<ProcessResult> results = await shell.run('id -u');
      if (results.isNotEmpty && results[0].stdout.trim() == '0') {
        return true;
      }
    }
  } catch (e) {
    // 如果出现异常 (如 ShellException),默认认为没有管理员权限
    return false;
  }

  return false;
}


Future<bool> killCCoreProcess(int pid) async {
    return Process.killPid(pid);
}
Future<ProcessResult> runCCore(String executable, List<String> arguments) async {
  String executablePath = shellArgument(executable).replaceAll(' ', r'\\ ');
  if (Platform.isMacOS) {
    return await Process.run(
      path.join(Paths.assetsBin.path, executablePath),
      [executable, ...arguments],
    );
  } else if (Platform.isWindows) {
    return await Process.run(
      path.join(Paths.assetsBin.path, executablePath),
      [executable, ...arguments],
    );
  } else {
    // https://blog.csdn.net/weixin_49867936/article/details/109612918
    // https://askubuntu.com/questions/287845/how-to-configure-pkexec
    return await Process.run("pkexec", [executable, ...arguments]);
  }

}


Future<ProcessResult> runCCoreAsAdmin(String executable, List<String> arguments) async {
  // String executablePath = shellArgument(executable).replaceAll(' ', r'\\ ');
  return await Process.run(
    path.join(Paths.assetsBin.path, "run-as-admin.bat"),
    [executable, ...arguments],
  );
}
Future<ProcessResult> runAsAdmin(String executable, List<String> arguments) async {
  String executablePath = shellArgument(executable).replaceAll(' ', r'\\ ');
  //executablePath = executablePath.substring(1, executablePath.length - 1);
  if (Platform.isMacOS) {
    return await Process.run(
      'osascript',
      [
        '-e',
        shellArguments(['do', 'shell', 'script', '$executablePath ${shellArguments(arguments)}', 'with', 'administrator', 'privileges']),
      ],
    );
  } else if (Platform.isWindows) {

    return await Process.run(
      path.join(Paths.assetsBin.path, "run-as-admin.bat"),
      [executable, ...arguments],
    );
  } else {
    // https://blog.csdn.net/weixin_49867936/article/details/109612918
    // https://askubuntu.com/questions/287845/how-to-configure-pkexec
    return await Process.run("pkexec", [executable, ...arguments]);
  }
}


// Platform messages are asynchronous, so we initialize in an async method.
Future<String> platformState() async {
  String platformVersion;
  if(Platform.isWindows){
    try {
      final _wlBaseHelpPlugin = WlBaseHelp();
      platformVersion =
          await _wlBaseHelpPlugin.getPlatformVersion() ?? 'Unknown platform version';
      platformVersion = platformVersion + ClashName.architecture.name;
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }
    return platformVersion;
  }
  else {
   return ClashName.os.name + "-" + ClashName.architecture.name;
  }

}

Future<void> onRunAdmin() async {
  if(Platform.isWindows){

    try {
      final _wlBaseHelpPlugin = WlBaseHelp();
      await _wlBaseHelpPlugin.runAsAdministrator();
    } on PlatformException {

    }
  }

}

Future<bool> onIsRunAdmin() async {
  bool isAdmin;
  try {
    final _wlBaseHelpPlugin = WlBaseHelp();
    isAdmin = await _wlBaseHelpPlugin.isRunningAsAdmin() ?? false;
  } on PlatformException {
    isAdmin = false;
  }

  return isAdmin;
}

Future<bool> onIsProcessRunning(String passName) async {
  bool isRun = false;
  if(Platform.isWindows){

    try {
      final _wlBaseHelpPlugin = WlBaseHelp();
      isRun = await _wlBaseHelpPlugin.isProcessRunning(passName) ?? false;

      if (isRun){
        await onKillProcess(passName);
      }

    } on PlatformException {
      isRun = false;
    }
  }
  return isRun;
}

Future<void> onKillProcess(String passName) async {

  try {
    final _wlBaseHelpPlugin = WlBaseHelp();
    await _wlBaseHelpPlugin.killProcess(passName);
  } on PlatformException {

  }

}