import { app, dialog, ipcMain, shell, BrowserWindow } from 'electron'
import { exec } from 'child_process'
import { dirname, join } from 'path'
import {
  closeScreen,
  closeAllScreens,
  listScreens,
  publishScreen,
  setPages,
  startCarousel,
  stopCarousel,
  mainScreenIndex,
  publishMain,
  restoreMain,
  probeScreens,
  setKeyLock,
  isKeyLocked
} from './screens'
import type { CarouselPage } from './screens'
import { loadSettings, saveSettings } from './settings'
import type { AppSettings } from './settings'
import { readProjectFile, writeProjectFile } from './project'
import { createDesktopShortcut, chooseProjectFile } from './shortcuts'
import type { ShortcutKind } from './shortcuts'
import { consumePendingLoad } from './loader'

function beepSystem(): void {
  if (process.platform === 'darwin') {
    shell.beep()
    return
  }
  // Windows / Linux：调用系统终端提示音
  exec('powershell -NoProfile -NonInteractive -Command "[console]::beep(880,400)"', () => undefined)
}

export function registerIpc(): void {
  // ===== 窗口控制 =====
  ipcMain.on('win:minimize', () => BrowserWindow.getFocusedWindow()?.minimize())
  ipcMain.on('win:toggle-maximize', () => {
    const w = BrowserWindow.getFocusedWindow()
    if (!w) return
    if (w.isMaximized()) w.unmaximize()
    else w.maximize()
  })
  ipcMain.on('win:close', () => BrowserWindow.getFocusedWindow()?.close())

  // ===== 屏幕 / 多屏发布 =====
  ipcMain.handle('screens:list', () => listScreens())
  ipcMain.handle('screens:states', () => listScreens())
  ipcMain.handle('screen:publish', (_e, payload: { index: number; url: string; title: string }) =>
    publishScreen(payload.index, payload.url, payload.title)
  )
  ipcMain.handle('screen:close', (_e, index: number) => closeScreen(index))
  ipcMain.handle('screen:closeAll', () => {
    closeAllScreens()
    return listScreens()
  })
  ipcMain.handle('screens:mainIndex', () => mainScreenIndex())
  ipcMain.handle('screen:publishMain', (_e, payload: { url: string; title: string }) =>
    publishMain(payload.url, payload.title)
  )
  ipcMain.handle('screen:restoreMain', () => restoreMain())
  ipcMain.handle('screens:probe', () => probeScreens())

  // ===== 单屏轮播 =====
  ipcMain.handle(
    'carousel:start',
    (_e, payload: { index: number; pages: CarouselPage[] }) => startCarousel(payload.index, payload.pages)
  )
  ipcMain.handle('carousel:stop', (_e, index: number) => stopCarousel(index))

  // 渲染层页面同步（用于屏幕键盘切页）
  ipcMain.on('project:sync', (_e, pages: unknown) => {
    setPages(
      Array.isArray(pages)
        ? pages.map((p) => p as { id: string; title: string; url: string; screen: number; ctrl: number; display: boolean })
        : []
    )
  })

  // ===== 工程文件（带 JSON 读写密码）=====
  /** 记住用户最后一次选择/保存工程的文件夹 */
  const rememberDir = async (p: string): Promise<void> => {
    try {
      await saveSettings({ lastDir: dirname(p) })
    } catch {
      // 记录失败不影响主流程
    }
  }

  ipcMain.handle('project:saveAs', async (_e, payload: { data: string; password?: string }) => {
    const settings = await loadSettings()
    const pwd = payload.password ?? settings.jsonPassword
    const defaultPath = settings.lastDir
      ? join(settings.lastDir, settings.projectName + '.json')
      : settings.projectName + '.json'
    const r = await dialog.showSaveDialog({
      title: '保存工程文件',
      defaultPath,
      filters: [{ name: 'JSON 工程文件', extensions: ['json'] }]
    })
    if (r.canceled || !r.filePath) return null
    const res = await writeProjectFile(r.filePath, payload.data, pwd)
    if (res.ok) await rememberDir(r.filePath)
    return res.ok ? r.filePath : null
  })

  ipcMain.handle('project:save', async (_e, payload: { path: string; data: string; password?: string }) => {
    if (!payload.path) return null
    const settings = await loadSettings()
    const pwd = payload.password ?? settings.jsonPassword
    const res = await writeProjectFile(payload.path, payload.data, pwd)
    return res.ok ? payload.path : null
  })

  // 打开工程：先弹框选文件，用当前配置密码尝试解密
  ipcMain.handle('project:open', async (_e, password?: string) => {
    const settings = await loadSettings()
    const r = await dialog.showOpenDialog({
      title: '打开工程文件',
      defaultPath: settings.lastDir || undefined,
      filters: [{ name: 'JSON 工程文件', extensions: ['json'] }],
      properties: ['openFile']
    })
    if (r.canceled || !r.filePaths[0]) return null
    const pwd = password ?? settings.jsonPassword
    const res = await readProjectFile(r.filePaths[0], pwd)
    await rememberDir(r.filePaths[0])
    return res
  })

  // 打开指定路径工程（用于密码输入重试 / 快捷方式场景）
  ipcMain.handle('project:openAt', (_e, payload: { path: string; password?: string }) =>
    readProjectFile(payload.path, payload.password ?? '')
  )

  // ===== 应用设置 =====
  ipcMain.handle('settings:get', () => loadSettings())
  ipcMain.handle('settings:set', (_e, patch: Partial<AppSettings>) => saveSettings(patch))

  // ===== 应用信息 / 启动加载 =====
  ipcMain.handle('app:info', () => ({
    appVersion: app.getVersion(),
    electron: process.versions.electron,
    chrome: process.versions.chrome,
    node: process.versions.node,
    platform: process.platform + ' ' + process.arch
  }))
  ipcMain.handle('app:consumeLoad', () => consumePendingLoad())

  // ===== 页面截图（预览图）=====
  ipcMain.handle('page:snapshot', async (_e, url: string) => {
    if (!url || url === 'about:blank') return null
    const win = new BrowserWindow({
      width: 1280,
      height: 720,
      show: false,
      frame: false,
      webPreferences: {
        contextIsolation: true,
        nodeIntegration: false,
        sandbox: false,
        spellcheck: false
      }
    })
    try {
      win.webContents.setWindowOpenHandler(() => ({ action: 'deny' }))
      await win.loadURL(url)
      // 等待页面渲染完成（图表/动画）
      await new Promise((r) => setTimeout(r, 1600))
      const img = await win.webContents.capturePage()
      if (img.isEmpty()) return null
      return img.toDataURL()
    } catch {
      return null
    } finally {
      if (!win.isDestroyed()) win.destroy()
    }
  })

  // ===== 对话框 =====
  ipcMain.handle('dialog:confirm', async (_e, message: string) => {
    const r = await dialog.showMessageBox({
      type: 'question',
      title: '智慧农业大数据可视化控制中心',
      message,
      buttons: ['确定', '取消'],
      defaultId: 0,
      cancelId: 1
    })
    return r.response === 0
  })

  // ===== 工具 =====
  ipcMain.handle('beep', () => {
    beepSystem()
  })

  // 旧接口兼容：直接打开本工具
  ipcMain.handle('desktop:shortcut', () => createDesktopShortcut('app').ok)

  // 三类快捷方式；edit/publish 时先在主进程弹框选择工程文件
  ipcMain.handle('shortcut:create', async (_e, kind: ShortcutKind) => {
    if (kind === 'app') return createDesktopShortcut('app')
    const path = await chooseProjectFile()
    if (!path) return { ok: false, message: '未选择工程文件' }
    return createDesktopShortcut(kind, path)
  })

  // ===== 快捷键锁定（遥控设置）=====
  ipcMain.handle('screens:keyLock', (_e, locked: boolean) => setKeyLock(!!locked))
  ipcMain.handle('screens:keyLockState', () => isKeyLocked())

  // ===== 窗口关闭守卫（未保存提示）=====
  ipcMain.on('window:dirty', (_e, d: boolean) => {
    setDirtyFlag(!!d)
  })
}

let dirty = false
let forceQuit = false

function setDirtyFlag(d: boolean): void {
  dirty = d
}

export function installCloseGuard(win: BrowserWindow): void {
  win.on('close', (e) => {
    if (!dirty || forceQuit) return
    e.preventDefault()
    void dialog
      .showMessageBox(win, {
        type: 'warning',
        title: '工程尚未保存',
        message: '当前工程有未保存的修改，确定要关闭吗？',
        buttons: ['仍然关闭', '取消'],
        defaultId: 1,
        cancelId: 1
      })
      .then((r) => {
        if (r.response === 0) {
          forceQuit = true
          win.close()
        }
      })
  })
}
