'use strict'

import { app, protocol, globalShortcut, BrowserWindow, ipcMain, Menu, dialog } from 'electron'
import {
  createProtocol
} from 'vue-cli-plugin-electron-builder/lib'

import { autoUpdater } from 'electron-updater'

const contextMenu = require('electron-context-menu')

contextMenu({
  labels: {
    cut: '剪切',
    copy: '复制',
    paste: '粘贴',
    save: '保存',
    saveImageAs: '图片另存为'
  },
  prepend: () => [
    {
      type: 'separator'
    },
    {
      type: 'separator'
    },
    {
      label: 'Invisible',
      visible: false
    },
    {
      type: 'separator'
    },
    {
      type: 'separator'
    }
  ],
  append: () => {},
  showSearchWithGoogle: false,
  showCopyImageAddress: false,
  showSaveImageAs: true,
  showSaveImage: false,
  showCopyImage: false,
  showInspectElement: false
})

global.windows = {}

const Store = require('electron-store')
const localStore = new Store()
localStore.delete('token')

const log = require('electron-log')
log.transports.file.level = 'silly'

const isDevelopment = process.env.NODE_ENV !== 'production'
const path = require('path')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win
let canQuit = false
let workerWin

// Scheme must be registered before the app is ready
protocol.registerStandardSchemes(['app'], { secure: true })
const { download } = require('electron-dl')
function createWindow () {
  // Create the browser window.
  win = new BrowserWindow({
    width: 800,
    height: 600,
    show: false,
    icon: path.join(__static, process.env.VUE_APP_LOGO ? process.env.VUE_APP_LOGO + '.png' : 'icon.png'),
    webPreferences: { webSecurity: false, plugins: true }
  })

  global.windows.index = win.webContents.id

  win.maximize()
  win.show()

  log.info('当前软件版本号', app.getVersion())

  if (process.env.WEBPACK_DEV_SERVER_URL) {
    // Load the url of the dev server if in development mode
    win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
    if (!process.env.IS_TEST) win.webContents.openDevTools()
  } else {
    createProtocol('app')
    // Load the index.html when not in development
    win.loadURL('app://./index.html')
  }

  win.on('closed', () => {
    win = null
    workerWin && workerWin.close()
  })

  win.on('close', (e) => {
    if (canQuit) {
      app.quit()
    } else {
      e.preventDefault()
      dialog.showMessageBox({
        type: 'info',
        title: '提示',
        message: '确定退出软件吗？',
        buttons: ['是', '否']
      }, (index) => {
        if (index === 0) {
          canQuit = true
          app.quit()
        }
      })
    }
  })

  ipcMain.on('updateReady', (event, updateUrl) => {
    console.log('check update', updateUrl)
    checkForUpdates(updateUrl)
  })

  ipcMain.on('getPrinters', (event, updateUrl) => {
    win.webContents.send('sendPrinters', win.webContents.getPrinters())
  })

  ipcMain.on('open-directory-dialog', (event) => {
    dialog.showOpenDialog({
      properties: ['openDirectory'] // 'openFile', 'openDirectory'
    }, (files) => {
      if (files) event.sender.send('selected-directory', files)
    })
  })

  ipcMain.on('open-file-dialog', (event) => {
    dialog.showOpenDialog({
      properties: ['openFile'] // 'openFile', 'openDirectory'
    }, (files) => {
      if (files) event.sender.send('selected-file', files)
    })
  })

  ipcMain.on('download', async (event, args) => {
    log.info('下载', args)
    try {
      const file = await download(win, args, {
        saveAs: true,
        errorTitle: '下载出错'
      })

      event.sender.send('downloadSuccess', file)
    } catch (e) {
      console.log(JSON.stringify(e))
      event.sender.send('downloadError', e.message)
    }
  })

  globalShortcut.register('CommandOrControl+P', () => {
    localStore.openInEditor()
  })

  globalShortcut.register('F3', () => {
    BrowserWindow.getFocusedWindow().webContents.openDevTools()
  })
}

// 创建人脸识别弹框，放在主窗口识别预热，会导致页面卡顿
function createWorker (devPath, prodPath) {
  // create hidden worker window
  workerWin = new BrowserWindow({
    show: true, // process.env.NODE_ENV !== 'production',
    alwaysOnTop: true,
    fullscreen: true, // process.env.NODE_ENV === 'production'
    webPreferences: { nodeIntegration: true, webSecurity: false }
  })

  workerWin.hide()

  global.windows.faceDetector = workerWin.webContents.id

  if (process.env.WEBPACK_DEV_SERVER_URL) {
    workerWin.loadURL(process.env.WEBPACK_DEV_SERVER_URL + devPath)
  } else {
    workerWin.loadURL(`app://./${prodPath}`)
  }

  workerWin.on('closed', () => { workerWin = null })
}

if (!isDevelopment) {
  // 单例应用，防止同时打开多个软件窗口
  const gotTheLock = app.requestSingleInstanceLock()

  if (!gotTheLock) {
    app.quit()
  } else {
    app.on('second-instance', (event, commandLine, workingDirectory) => {
    // Someone tried to run a second instance, we should focus our window.
      if (win) {
        if (win.isMinimized()) win.restore()
        win.focus()
      }
    })
  }
}

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (win === null) {
    createWindow()
    setMenu()
  }
})

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', async () => {
  if (isDevelopment && !process.env.IS_TEST) {
    // Install Vue Devtools
    try {
      // await installVueDevtools()
    } catch (e) {
      console.error('Vue Devtools failed to install:', e.toString())
    }
  }
  createWindow()
  setMenu()
  createWorker('worker', 'worker.html')
})

// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
  if (process.platform === 'win32') {
    process.on('message', data => {
      if (data === 'graceful-exit') {
        app.quit()
      }
    })
  } else {
    process.on('SIGTERM', () => {
      app.quit()
    })
  }
}

const sendUpdateMessage = (message, data) => {
  log.warn(message)
  win.webContents.send('message', { message, data })
}

export function checkForUpdates (url) {
  if (process.env.NODE_ENV !== 'production') return

  // 设置自动更新
  autoUpdater.setFeedURL(url)

  autoUpdater.on('error', function (message) {
    sendUpdateMessage('error', message)
  })
  autoUpdater.on('checking-for-update', function (message) {
    sendUpdateMessage('checking-for-update', message)
  })
  autoUpdater.on('update-available', function (message) {
    sendUpdateMessage('update-available', message)
  })
  autoUpdater.on('update-not-available', function (message) {
    sendUpdateMessage('update-not-available', message)
  })

  // 更新下载进度事件
  autoUpdater.on('download-progress', function (progressObj) {
    sendUpdateMessage('downloadProgress', progressObj)
  })

  autoUpdater.on('update-downloaded', function (event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
    log.info(`已下载${event.version}`)

    var fs = require('fs-extra')
    var path = require('path')

    var fileName = event.downloadedFile

    var sourceFile = path.join(fileName)
    var destPath = path.join('C://售票软件', event.path)

    fs.copySync(sourceFile, destPath)
    log.info(`安装包移动完成`)

    ipcMain.on('updateNow', (e, arg) => {
    // some code here to handle event
      autoUpdater.quitAndInstall()
    })
    sendUpdateMessage('isUpdateNow')
  })

  // 执行自动更新检查

  autoUpdater.checkForUpdates().catch(e => {
    sendUpdateMessage('error', e)
  })

  // 取消退出软件后的自动更新
  autoUpdater.autoInstallOnAppQuit = false
}

export function setMenu () {
  // const version = app.getVersion()
  let template = [
    {
      label: '工具',
      submenu: [
        {
          label: '强制刷新',
          role: 'forcereload'
        },
        {
          label: '开发者工具',
          role: 'toggledevtools'
        }
      ]
    },
    {
      label: '配置',
      role: 'config',
      click: function () {
        win.webContents.send('goConfig')
      }
    },
    {
      label: '刷新',
      role: 'reload'
    }
    // {
    //   label: '帮助',
    //   submenu: [
    //     {
    //       label: `Version ${version}`,
    //       enabled: false
    //     },
    //     {
    //       label: '检查更新',
    //       click: function () {

    //       // require('electron').autoUpdater.quitAndInstall()
    //       }
    //     }
    //   ]
    // }
  ]

  process.env.NODE_ENV === 'development' && (template.push(
    {
      label: 'Pos调试',
      click: function () {
        win.webContents.send('goPos')
      }
    }
  ))

  const menu = Menu.buildFromTemplate(template)
  Menu.setApplicationMenu(menu)
}
