'use strict';

const _ = require('lodash');
const path = require('path');
const { Controller } = require('ee-core');
const {
  app: electronApp, dialog, shell, Notification,
  powerMonitor, screen, nativeTheme
} = require('electron');
const Conf = require('ee-core/config');
const Ps = require('ee-core/ps');
const Services = require('ee-core/services');
const Addon = require('ee-core/addon');
const { getNetworkIFaceOne, getMac, getAllMac, getAllPhysicsMac } = require('@lzwme/get-physical-address');
const os = require('os');
const shutdown = require('electron-shutdown-command');
// 终端命令
const { exec, execSync, execFile } = require("child_process");
// 声音控制库 https://github.com/LinusU/node-loudness
const loudness = require("loudness");
// 文件处理
const fs = require('fs');
/**
 * 操作系统 - 功能demo
 * @class
 */
class OsController extends Controller {

  constructor(ctx) {
    super(ctx);
  }

  /**
   * 所有方法接收两个参数
   * @param args 前端传的参数
   * @param event - ipc通信时才有值。详情见：控制器文档
   */


  // 获取所有的网卡-无参数
  async getAllMac(args) {
    //  文档说明 https://github.com/lzwme/get-physical-address/blob/main/.github/README_zh-CN.md
    const list = getAllPhysicsMac();
    return list;
  }
  // 查找到指定进程并关闭? 注意 进程要全, 不然容易误杀
  deviceKillName(name) {
    // 最新 taskkill /F /IM program.exe  这个命令一句话能直接杀掉进程
    const self = this;
    let rebootShell = "tasklist|findstr " + name;
    let command = exec(rebootShell, function (err, stdout, stderr) {
      if (err || stderr) {
        console.log("tasklist failed" + err + stderr);
      } else {
        const lines = stdout.split('\n')
        console.log(lines);
        for (let index = 0; index < lines.length; index++) {
          const element = lines[index];
          const strs = element.split(' ')
          const firstNumber = strs.find(item => !isNaN(Number(item)) && item != '')
          console.log('jincheng id :' + firstNumber);
          self.deviceKillPid(firstNumber)
        }
      }
    });
    command.stdin.end();
    command.on("close", function (code) {
      console.log("tasklist", code);
    });
  }
  // 杀掉pid 进程
  deviceKillPid(pid) {
    let rebootShell = "tskill " + pid;
    let command = exec(rebootShell, function (err, stdout, stderr) {
      if (err || stderr) {
        console.log("tskill failed" + err + stderr);
      }
    })
    command.stdin.end();
    command.on("close", function (code) {
      console.log("tskill", code);
    });
  }

  // 启动指定目录的程序 可能有权限问题, 方案1 打包后管理员权限执行, 2 按照egg 的方案把需要执行的程序拷贝到安装包
  deviceStarExe(path) {

    let rebootShell = 'start ' + path;
    exec(rebootShell);

  }
  /**
  * 设备关机
  */
  deviceShutdown() {
    // 关机
    // let shutdownShell = "shutdown -s -t 00";
    console.log('deviceShutdown=============')
    shutdown.shutdown();
    return true;
  }
  deviceRestart(args) {
    // 重启
    let rebootShell = "shutdown -r -t 0";
    let command = exec(rebootShell, function (err, stdout, stderr) {
      if (err || stderr) {
        console.log("shutdown failed" + err + stderr);
      }
    });
    command.stdin.end();
    command.on("close", function (code) {
      console.log("shutdown", code);
    });
  }
  // 同步执行 声音设置 支持0-100
  async deviceLoudness(args) {
    const value = args.value;
    //操作系统平台
    const pf = os.platform();
    console.log("OS: " + pf)
    // 特殊处理以下
    if (pf == "linux") {
      let shellStr = "amixer -D pulse set Master " + value + "% unmute"
      if (value == 0) {
        shellStr = "amixer -D pulse set Master mute"

      }

      // else{
      //   shellStr = "amixer -c 0 set Master,0 100%,80% unmute"
      // }

      let command = exec(shellStr, function (err, stdout, stderr) {
        if (err || stderr) {
          console.log("amixer failed" + err + stderr);
        }
      });
      command.stdin.end();
      command.on("close", function (code) {
        console.log("amixer", code);
      });

      return;
    } else {
      /// 兼容模式, try catch 如果第一种方式报错, 在采用第二种
      try {
        //0 为静音
        if (value == 0) {
          await loudness.setMuted(true)
          return await loudness.getMuted()
        }
        // 设置声音改为不静音 且设置声音
        await loudness.setMuted(false)
        await loudness.setVolume(value)
        const newValue = await loudness.getVolume();
        return newValue;
      } catch {
        const maxVolume = 65535;
        let volumeValue = Math.round((value / 100) * maxVolume);

        // 确保音量值在有效范围内
        volumeValue = Math.max(0, Math.min(maxVolume, volumeValue));

        // 将音量值转换为字符串
        const valueStr = volumeValue.toString();

        let excPath = path.join(Ps.getExtraResourcesDir(), 'nircmd.exe');

        execFile(excPath, ['setsysvolume', valueStr], (error, stdout, stderr) => {
          if (error) {
            console.error(' Nircmd error: ', error);
            return;
          }
          console.log('Nircmd ok ');
        });

        return value;
      }


    }
  }
  // 获取电脑信息
  async getOSMessage(args) {
    var OSDic = {};
    var dealTime = (seconds) => {
      var seconds = seconds | 0;
      var day = (seconds / (3600 * 24)) | 0;
      var hours = ((seconds - day * 3600) / 3600) | 0;
      var minutes = ((seconds - day * 3600 * 24 - hours * 3600) / 60) | 0;
      var second = seconds % 60;
      (day < 10) && (day = '0' + day);
      (hours < 10) && (hours = '0' + hours);
      (minutes < 10) && (minutes = '0' + minutes);
      (second < 10) && (second = '0' + second);
      return [day, hours, minutes, second].join(':');
    };

    var dealMem = (mem) => {
      var G = 0,
        M = 0,
        KB = 0;
      (mem > (1 << 30)) && (G = (mem / (1 << 30)).toFixed(2));
      (mem > (1 << 20)) && (mem < (1 << 30)) && (M = (mem / (1 << 20)).toFixed(2));
      (mem > (1 << 10)) && (mem > (1 << 20)) && (KB = (mem / (1 << 10)).toFixed(2));
      return G > 0 ? G + 'G' : M > 0 ? M + 'M' : KB > 0 ? KB + 'KB' : mem + 'B';
    };

    //cpu架构
    const arch = os.arch();
    // console.log("cpu架构：" + arch);
    OSDic["arch"] = arch;

    //操作系统内核
    const kernel = os.type();
    // console.log("操作系统内核：" + kernel);
    OSDic["kernel"] = kernel;

    //操作系统平台
    const pf = os.platform();
    // console.log("平台：" + pf);
    OSDic["pf"] = pf;

    //系统开机时间
    const uptime = os.uptime();
    // console.log("开机时间：" + dealTime(uptime));
    OSDic["uptime"] = uptime;
    //主机名
    const hn = os.hostname();
    // console.log("主机名：" + hn);
    OSDic["hostname"] = hn;
    // //主目录
    // const hdir = os.homedir();
    // console.log("主目录：" + hdir);
    // OSDic["homedir"] = hdir;

    //内存
    const totalMem = os.totalmem();
    const freeMem = os.freemem();
    // console.log("内存大小：" + dealMem(totalMem) + ' 空闲内存：' + dealMem(freeMem));
    OSDic["totalmem"] = totalMem;
    OSDic["freeMem"] = freeMem;
    //cpu
    const cpus = os.cpus();
    OSDic["cpuModel"] = cpus[0]["model"];
    // OSDic["cpus"] = cpus;
    // console.log('*****cpu信息*******');
    // cpus.forEach((cpu, idx, arr) => {
    //   var times = cpu.times;
    //   console.log(`cpu${idx}：`);
    //   console.log(`型号：${cpu.model}`);
    //   console.log(`频率：${cpu.speed}MHz`);
    //   console.log(`使用率：${((1 - times.idle / (times.idle + times.user + times.nice + times.sys + times.irq)) * 100).toFixed(2)}%`);
    // });

    try {
      const volumeValue = await loudness.getVolume()

      OSDic["volume"] = volumeValue;
      console.log('volumeValue' + volumeValue);

    } catch (error) {
      console.log(error)
    }

    return OSDic;
  }
  //   const volume = await loudness.getVolume()
  //   OSDic["volume"] = volume;
  //   return OSDic;
  // }
  /**
       * 获取当前目录的配置
       * @param {*} name  配置文件名
       * @returns 
       */
  getCurrentDirectoryConfig(name) {
    let configPath = '';
    configPath = path.join(Ps.getExtraResourcesDir(), name);
    console.log(configPath)
    // let configJSON = null;
    let dataString = null;
    try {
      // 同步读取配置文件
      dataString = fs.readFileSync(configPath, 'utf8');

      // 解析 JSON 格式的配置数据
      // configJSON = JSON.parse(data);
      // console.log('读取到的配置:', configJSON);

      // 在这里可以根据需要使用配置数据进行操作
    } catch (err) {
      console.error('无法读取配置文件:', err);
    }
    return dataString;
  }
  /**
   * 消息提示对话框
   */
  messageShow() {
    dialog.showMessageBoxSync({
      type: 'info', // "none", "info", "error", "question" 或者 "warning"
      title: '自定义标题-message',
      message: '自定义消息内容',
      detail: '其它的额外信息'
    })

    return '打开了消息框';
  }

  /**
   * 消息提示与确认对话框
   */
  messageShowConfirm() {
    const res = dialog.showMessageBoxSync({
      type: 'info',
      title: '自定义标题-message',
      message: '自定义消息内容',
      detail: '其它的额外信息',
      cancelId: 1, // 用于取消对话框的按钮的索引
      defaultId: 0, // 设置默认选中的按钮
      buttons: ['确认', '取消'], // 按钮及索引
    })
    let data = (res === 0) ? '点击确认按钮' : '点击取消按钮';

    return data;
  }

  /**
   * 选择目录
   */
  selectFolder() {
    const filePaths = dialog.showOpenDialogSync({
      properties: ['openDirectory', 'createDirectory']
    });

    if (_.isEmpty(filePaths)) {
      return null
    }

    return filePaths[0];
  }

  /**
   * 打开目录
   */
  openDirectory(args) {
    if (!args.id) {
      return false;
    }
    let dir = '';
    if (path.isAbsolute(args.id)) {
      dir = args.id;
    } else {
      dir = electronApp.getPath(args.id);
    }

    shell.openPath(dir);
    return true;
  }

  /**
   * 选择图片
   */
  selectPic() {
    const filePaths = dialog.showOpenDialogSync({
      title: 'select pic',
      properties: ['openFile'],
      filters: [
        { name: 'Images', extensions: ['jpg', 'png', 'gif'] },
      ]
    });
    if (_.isEmpty(filePaths)) {
      return null
    }

    return filePaths[0];
  }

  /**
   * 加载视图内容
   */
  loadViewContent(args) {
    const { type, content } = args;
    let contentUrl = content;
    if (type == 'html') {
      contentUrl = path.join('file://', electronApp.getAppPath(), content);
    }

    Services.get('os').createBrowserView(contentUrl);

    return true
  }

  /**
   * 移除视图内容
   */
  removeViewContent() {
    Services.get('os').removeBrowserView();
    return true
  }

  /**
   * 打开新窗口
   */
  createWindow(args) {
    const { type, content, windowName, windowTitle } = args;
    let contentUrl = null;
    if (type == 'html') {
      contentUrl = path.join('file://', electronApp.getAppPath(), content)
    } else if (type == 'web') {
      contentUrl = content;
    } else if (type == 'vue') {
      let addr = 'http://localhost:17680'
      if (Ps.isProd()) {
        const mainServer = Conf.getValue('mainServer');
        if (Conf.isFileProtocol(mainServer)) {
          addr = mainServer.protocol + path.join(Ps.getHomeDir(), mainServer.indexPath);
        } else {
          addr = mainServer.protocol + mainServer.host + ':' + mainServer.port;
        }
      }

      contentUrl = addr + content;
    } else {
      // some
    }

    console.log('contentUrl: ', contentUrl);
    let opt = {
      title: windowTitle
    }
    const win = Addon.get('window').create(windowName, opt);
    const winContentsId = win.webContents.id;

    // load page
    win.loadURL(contentUrl);

    return winContentsId;
  }

  /**
   * 获取窗口contents id
   */
  getWCid(args) {
    // 主窗口的name默认是main，其它窗口name开发者自己定义
    const name = args;
    const id = Addon.get('window').getWCid(name);

    return id;
  }

  /**
   * 加载扩展程序
   */
  // async loadExtension (args) {
  //   const crxFile = args[0];
  //   if (_.isEmpty(crxFile)) {
  //     return false;
  //   }
  //   const extensionId = path.basename(crxFile, '.crx');
  //   const chromeExtensionDir = chromeExtension.getDirectory();
  //   const extensionDir = path.join(chromeExtensionDir, extensionId);

  //   Log.info("[api] [example] [loadExtension] extension id:", extensionId);
  //   unzip(crxFile, extensionDir).then(() => {    
  //     Log.info("[api] [example] [loadExtension] unzip success!");
  //     chromeExtension.load(extensionId);
  //   });

  //   return true;
  // }

  /**
   * 创建系统通知
   */
  sendNotification(args, event) {
    const { title, subtitle, body, silent } = args;

    if (!Notification.isSupported()) {
      return '当前系统不支持通知';
    }

    let options = {};
    if (!_.isEmpty(title)) {
      options.title = title;
    }
    if (!_.isEmpty(subtitle)) {
      options.subtitle = subtitle;
    }
    if (!_.isEmpty(body)) {
      options.body = body;
    }
    if (!_.isEmpty(silent)) {
      options.silent = silent;
    }

    Services.get('os').createNotification(options, event);

    return true
  }

  /**
   * 电源监控
   */
  initPowerMonitor(args, event) {
    const channel = 'controller.os.initPowerMonitor';
    powerMonitor.on('on-ac', (e) => {
      let data = {
        type: 'on-ac',
        msg: '接入了电源'
      }
      event.reply(`${channel}`, data)
    });

    powerMonitor.on('on-battery', (e) => {
      let data = {
        type: 'on-battery',
        msg: '使用电池中'
      }
      event.reply(`${channel}`, data)
    });

    powerMonitor.on('lock-screen', (e) => {
      let data = {
        type: 'lock-screen',
        msg: '锁屏了'
      }
      event.reply(`${channel}`, data)
    });

    powerMonitor.on('unlock-screen', (e) => {
      let data = {
        type: 'unlock-screen',
        msg: '解锁了'
      }
      event.reply(`${channel}`, data)
    });

    return true
  }

  /**
   * 获取屏幕信息
   */
  getScreen(args) {
    let data = [];
    let res = {};
    if (args == 0) {
      let res = screen.getCursorScreenPoint();
      data = [
        {
          title: '横坐标',
          desc: res.x
        },
        {
          title: '纵坐标',
          desc: res.y
        },
      ]

      return data;
    }
    if (args == 1) {
      res = screen.getPrimaryDisplay();
    }
    if (args == 2) {
      let resArr = screen.getAllDisplays();
      // 数组，只取一个吧
      res = resArr[0];
    }
    // Log.info('[electron] [ipc] [example] [getScreen] res:', res);
    data = [
      {
        title: '分辨率',
        desc: res.bounds.width + ' x ' + res.bounds.height
      },
      {
        title: '单色显示器',
        desc: res.monochrome ? '是' : '否'
      },
      {
        title: '色深',
        desc: res.colorDepth
      },
      {
        title: '色域',
        desc: res.colorSpace
      },
      {
        title: 'scaleFactor',
        desc: res.scaleFactor
      },
      {
        title: '加速器',
        desc: res.accelerometerSupport
      },
      {
        title: '触控',
        desc: res.touchSupport == 'unknown' ? '不支持' : '支持'
      },
    ]

    return data;
  }

  /**
   * 获取系统主题
   */
  getTheme() {
    let theme = 'system';
    if (nativeTheme.shouldUseHighContrastColors) {
      theme = 'light';
    } else if (nativeTheme.shouldUseInvertedColorScheme) {
      theme = 'dark';
    }

    return theme;
  }

  /**
   * 设置系统主题
   */
  setTheme(args) {

    // TODO 好像没有什么明显效果
    nativeTheme.themeSource = args;

    return args;
  }
}

OsController.toString = () => '[class OsController]';
module.exports = OsController;