import { app, shell, BrowserWindow, ipcMain, Tray, Menu, nativeImage, WebContentsView, IpcMainEvent, dialog, screen } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import { mkdirSync, appendFileSync, existsSync, writeFileSync } from 'fs'
import { writeFile } from 'fs/promises'
import https from 'https'
import http from 'http'

// --- 日志管理 ---
let logDir: string = ''

function ensureLogDir(): void {
  if (!logDir) {
    logDir = join(app.getPath('userData'), 'logs')
  }
  if (!existsSync(logDir)) {
    mkdirSync(logDir, { recursive: true })
  }
}

function writeLog(message: string) {
  ensureLogDir()
  const date = new Date()
  const fileName = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}.log`
  const logPath = join(logDir, fileName)

  try {
    appendFileSync(logPath, message + '\n', 'utf-8')
  } catch (err) {
    console.error('Failed to write log:', err)
  }
}

ipcMain.on('log-message', (_, message) => {
  writeLog(message)
})

let mainWindow: BrowserWindow | null = null
let tray: Tray | null = null
let isQuitting = false
let blinkInterval: NodeJS.Timeout | null = null
let previewWindow: BrowserWindow | null = null
let videoPlayerWindow: BrowserWindow | null = null
let trayPopupWindow: BrowserWindow | null = null
let trayPopupHideTimer: NodeJS.Timeout | null = null
let trayHoverCheckTimer: NodeJS.Timeout | null = null

interface UnreadInfo {
  name: string
  content: string
  count: number
}
const unreadMap = new Map<number, UnreadInfo>()

// --- 浏览器视图管理器 ---
interface TabInfo {
  id: string
  url: string
  title: string
  view: WebContentsView
}

class ViewManager {
  private window: BrowserWindow
  private tabs: Map<string, TabInfo> = new Map()
  private activeTabId: string | null = null
  private bounds: Electron.Rectangle = { x: 0, y: 78, width: 1024, height: 600 }

  constructor(window: BrowserWindow) {
    this.window = window
  }

  createTab(url: string, active: boolean = true): string {
    const view = new WebContentsView({
      webPreferences: {
        sandbox: false,
        nodeIntegration: false,
        contextIsolation: true,
      }
    })

    const id = Date.now().toString() + Math.random().toString(36).substr(2, 9)

    view.webContents.on('did-start-loading', () => {
      if (!this.window.isDestroyed()) {
        this.window.webContents.send('tab-update', id, { isLoading: true })
      }
    })

    view.webContents.on('did-stop-loading', () => {
      if (!this.window.isDestroyed()) {
        this.window.webContents.send('tab-update', id, {
          isLoading: false,
          canGoBack: view.webContents.navigationHistory.canGoBack(),
          canGoForward: view.webContents.navigationHistory.canGoForward(),
          url: view.webContents.getURL(),
          title: view.webContents.getTitle()
        })
      }
    })

    view.webContents.on('page-title-updated', (_, title) => {
      if (!this.window.isDestroyed()) {
        this.window.webContents.send('tab-update', id, { title })
      }
    })

    view.webContents.on('did-navigate', (_, url) => {
      if (!this.window.isDestroyed()) {
        this.window.webContents.send('tab-update', id, { url })
      }
    })

    view.webContents.setWindowOpenHandler((details) => {
      const newId = this.createTab(details.url, true)
      if (!this.window.isDestroyed()) {
        this.window.webContents.send('tab-created', { id: newId, url: details.url, title: 'Loading...' })
      }
      return { action: 'deny' }
    })

    try {
      view.webContents.loadURL(url)
    } catch (e) {
      console.error('Failed to load URL:', url, e)
    }

    this.tabs.set(id, { id, url, title: 'Loading...', view })

    if (active) {
      this.switchTab(id)
    }

    return id
  }

  switchTab(id: string) {
    const tab = this.tabs.get(id)
    if (!tab) return

    if (this.activeTabId) {
      const currentTab = this.tabs.get(this.activeTabId)
      if (currentTab) {
        this.window.contentView.removeChildView(currentTab.view)
      }
    }

    this.window.contentView.addChildView(tab.view)
    tab.view.setBounds(this.bounds)

    this.activeTabId = id
  }

  closeTab(id: string) {
    const tab = this.tabs.get(id)
    if (!tab) return

    if (this.activeTabId === id) {
      this.window.contentView.removeChildView(tab.view)
      this.activeTabId = null
    } else {
      this.window.contentView.removeChildView(tab.view)
    }

    tab.view.webContents.close()
    this.tabs.delete(id)
  }

  setBounds(bounds: Electron.Rectangle) {
    this.bounds = bounds
    if (this.activeTabId) {
      const tab = this.tabs.get(this.activeTabId)
      if (tab) {
        tab.view.setBounds(bounds)
      }
    }
  }

  goBack() {
    if (this.activeTabId) this.tabs.get(this.activeTabId)?.view.webContents.navigationHistory.goBack()
  }

  goForward() {
    if (this.activeTabId) this.tabs.get(this.activeTabId)?.view.webContents.navigationHistory.goForward()
  }

  reload() {
    if (this.activeTabId) this.tabs.get(this.activeTabId)?.view.webContents.reload()
  }

  loadURL(id: string, url: string) {
    const tab = this.tabs.get(id)
    if (tab) {
      tab.view.webContents.loadURL(url)
    }
  }

  destroy() {
    this.tabs.forEach(tab => {
      try {
        this.window.contentView.removeChildView(tab.view)
        tab.view.webContents.close()
      } catch (e) { /* already destroyed */ }
    })
    this.tabs.clear()
  }
}

function getResourcePath(fileName: string): string {
  if (app.isPackaged) {
    return join(process.resourcesPath, fileName)
  }
  return join(__dirname, '../../resources', fileName)
}

// 获取图标路径的函数 - Windows 优先使用 ICO 文件
function getIconPath(): string {
  if (process.platform === 'win32') {
    // Windows 优先使用包含多尺寸的 ICO 文件
    const icoPath = getResourcePath('icon.ico')
    if (existsSync(icoPath)) {
      return icoPath
    }
  }
  // 其他平台或 Windows 没有 ICO 时使用 PNG
  return getResourcePath('logo.png')
}

function getTotalUnreadCount(): number {
  let total = 0
  for (const info of unreadMap.values()) {
    total += info.count
  }
  return total
}

function updateTrayMenu(): void {
  if (!tray) return
  const totalUnread = getTotalUnreadCount()
  const contextMenu = Menu.buildFromTemplate([
    { label: totalUnread > 0 ? `未读消息 (${totalUnread})` : '无未读消息', enabled: false },
    { type: 'separator' },
    { label: '显示主界面', click: () => mainWindow?.show() },
    { label: '退出', click: () => { isQuitting = true; app.quit() } }
  ])
  tray.setContextMenu(contextMenu)
  tray.setToolTip('韫珠IM')
}

// --- 托盘悬浮弹窗 ---

function getTrayPopupHTML(): string {
  return `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
*{margin:0;padding:0;box-sizing:border-box;}
body{font-family:'Microsoft YaHei','PingFang SC',sans-serif;background:transparent;overflow:hidden;user-select:none;}
.popup{background:#fff;border-radius:8px;box-shadow:0 4px 24px rgba(0,0,0,0.18);overflow:hidden;display:flex;flex-direction:column;max-height:100vh;}
.list{overflow-y:auto;max-height:calc(100vh - 40px);flex:1;}
.list::-webkit-scrollbar{width:4px;}
.list::-webkit-scrollbar-thumb{background:#ccc;border-radius:2px;}
.msg-item{display:flex;align-items:center;padding:10px 14px;cursor:pointer;border-bottom:1px solid #f0f0f0;transition:background 0.15s;}
.msg-item:last-child{border-bottom:none;}
.msg-item:hover{background:#f5f5f5;}
.msg-avatar{width:40px;height:40px;border-radius:6px;background:#4a90d9;color:#fff;display:flex;align-items:center;justify-content:center;font-size:18px;font-weight:bold;flex-shrink:0;position:relative;overflow:visible;}
.badge{position:absolute;top:-5px;right:-5px;background:#ff3b30;color:#fff;border-radius:10px;padding:0 5px;font-size:10px;min-width:16px;height:16px;line-height:16px;text-align:center;font-weight:normal;}
.msg-info{margin-left:10px;overflow:hidden;flex:1;}
.msg-name{font-size:14px;color:#333;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:500;}
.msg-content{font-size:12px;color:#999;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:3px;}
.footer{text-align:center;padding:10px;color:#576b95;font-size:13px;cursor:pointer;border-top:1px solid #eee;flex-shrink:0;transition:background 0.15s;}
.footer:hover{background:#f5f5f5;}
.empty{padding:20px;text-align:center;color:#999;font-size:13px;}
</style>
</head>
<body>
<div class="popup">
  <div class="list" id="list"></div>
  <div class="footer" id="dismiss">暂不处理</div>
</div>
<script>
(function(){
  const list = document.getElementById('list');
  const dismiss = document.getElementById('dismiss');
  const ipc = window.electron && window.electron.ipcRenderer;

  if(ipc){
    ipc.on('update-unread', function(_, items){
      list.innerHTML = '';
      if(!items || items.length === 0){
        list.innerHTML = '<div class="empty">暂无未读消息</div>';
        return;
      }
      items.forEach(function(item){
        var div = document.createElement('div');
        div.className = 'msg-item';
        var initial = item.name ? item.name.charAt(0) : '?';
        var badgeText = item.count > 99 ? '99+' : String(item.count);
        div.innerHTML =
          '<div class="msg-avatar">' + initial +
            '<div class="badge">' + badgeText + '</div>' +
          '</div>' +
          '<div class="msg-info">' +
            '<div class="msg-name">' + escapeHtml(item.name) + '</div>' +
            '<div class="msg-content">' + escapeHtml(item.content) + '</div>' +
          '</div>';
        div.addEventListener('click', function(){ ipc.send('tray-popup-click', item.id); });
        list.appendChild(div);
      });
    });
  }

  dismiss.addEventListener('click', function(){
    if(ipc) ipc.send('tray-popup-dismiss');
  });

  document.addEventListener('mouseleave', function(){
    if(ipc) ipc.send('tray-popup-mouse-leave');
  });

  document.addEventListener('mouseenter', function(){
    if(ipc) ipc.send('tray-popup-mouse-enter');
  });

  function escapeHtml(str){
    if(!str) return '';
    return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
  }
})();
</script>
</body>
</html>`
}

function createTrayPopup(): void {
  if (trayPopupWindow && !trayPopupWindow.isDestroyed()) return

  trayPopupWindow = new BrowserWindow({
    width: 320,
    height: 200,
    frame: false,
    transparent: true,
    alwaysOnTop: true,
    skipTaskbar: true,
    resizable: false,
    show: false,
    focusable: false,
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false,
      nodeIntegration: false,
      contextIsolation: true,
    }
  })

  trayPopupWindow.loadURL(`data:text/html;charset=utf-8,${encodeURIComponent(getTrayPopupHTML())}`)

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

function getUnreadListForPopup(): { id: number, name: string, content: string, count: number }[] {
  const list: { id: number, name: string, content: string, count: number }[] = []
  for (const [id, info] of unreadMap.entries()) {
    list.push({ id, name: info.name, content: info.content, count: info.count })
  }
  return list
}

function showTrayPopup(): void {
  if (!tray || unreadMap.size === 0) return

  if (!trayPopupWindow || trayPopupWindow.isDestroyed()) {
    createTrayPopup()
  }
  if (!trayPopupWindow) return

  if (trayPopupHideTimer) {
    clearTimeout(trayPopupHideTimer)
    trayPopupHideTimer = null
  }

  if (trayPopupWindow.isVisible()) {
    trayPopupWindow.webContents.send('update-unread', getUnreadListForPopup())
    return
  }

  const trayBounds = tray.getBounds()
  const itemHeight = 61
  const footerHeight = 40
  const maxItems = 5
  const visibleItems = Math.min(unreadMap.size, maxItems)
  const popupHeight = visibleItems * itemHeight + footerHeight + 2
  const popupWidth = 320

  const display = screen.getDisplayNearestPoint({ x: trayBounds.x, y: trayBounds.y })
  const workArea = display.workArea

  let x = Math.round(trayBounds.x - popupWidth / 2 + trayBounds.width / 2)
  let y: number

  if (trayBounds.y < workArea.y + workArea.height / 2) {
    y = trayBounds.y + trayBounds.height + 4
  } else {
    y = trayBounds.y - popupHeight - 4
  }

  if (x + popupWidth > workArea.x + workArea.width) {
    x = workArea.x + workArea.width - popupWidth - 4
  }
  if (x < workArea.x) {
    x = workArea.x + 4
  }

  trayPopupWindow.setSize(popupWidth, popupHeight)
  trayPopupWindow.setPosition(x, y)

  trayPopupWindow.webContents.once('did-finish-load', () => {
    if (trayPopupWindow && !trayPopupWindow.isDestroyed()) {
      trayPopupWindow.webContents.send('update-unread', getUnreadListForPopup())
    }
  })

  if (trayPopupWindow.webContents.isLoading()) {
    // will send data in did-finish-load
  } else {
    trayPopupWindow.webContents.send('update-unread', getUnreadListForPopup())
  }

  trayPopupWindow.showInactive()
}

function hideTrayPopup(): void {
  if (trayPopupHideTimer) {
    clearTimeout(trayPopupHideTimer)
    trayPopupHideTimer = null
  }
  if (trayHoverCheckTimer) {
    clearInterval(trayHoverCheckTimer)
    trayHoverCheckTimer = null
  }
  if (trayPopupWindow && !trayPopupWindow.isDestroyed() && trayPopupWindow.isVisible()) {
    trayPopupWindow.hide()
  }
}

function scheduleTrayPopupHide(): void {
  if (trayPopupHideTimer) clearTimeout(trayPopupHideTimer)
  trayPopupHideTimer = setTimeout(() => {
    hideTrayPopup()
  }, 300)
}

function cancelTrayPopupHide(): void {
  if (trayPopupHideTimer) {
    clearTimeout(trayPopupHideTimer)
    trayPopupHideTimer = null
  }
}

function updateWindowTitle(): void {
  if (!mainWindow) return
  const totalUnread = getTotalUnreadCount()
  if (totalUnread > 0) {
    mainWindow.setTitle(`韫珠IM (${totalUnread} 条未读消息)`)
  } else {
    mainWindow.setTitle('韫珠IM')
  }
}

function updateTaskbarOverlay(): void {
  const totalUnread = getTotalUnreadCount()
  if (totalUnread > 0) {
    app.setBadgeCount(totalUnread)
  } else {
    app.setBadgeCount(0)
  }
}

function updateUnreadStatus(): void {
  updateTrayMenu()
  updateWindowTitle()
  updateTaskbarOverlay()
  if (unreadMap.size > 0) {
    startBlinking()
  } else {
    stopBlinking()
    hideTrayPopup()
  }
  if (trayPopupWindow && !trayPopupWindow.isDestroyed() && trayPopupWindow.isVisible()) {
    trayPopupWindow.webContents.send('update-unread', getUnreadListForPopup())
  }
}

function startBlinking(): void {
  if (blinkInterval) return
  let isEmpty = false
  const iconPath = getIconPath()
  const emptyIcon = nativeImage.createEmpty()
  const normalIcon = nativeImage.createFromPath(iconPath)
  
  blinkInterval = setInterval(() => {
    if (!tray) return
    if (isEmpty) {
      tray.setImage(normalIcon)
    } else {
      tray.setImage(emptyIcon)
    }
    isEmpty = !isEmpty
  }, 500)
}

function stopBlinking(): void {
  if (blinkInterval) {
    clearInterval(blinkInterval)
    blinkInterval = null
  }
  if (tray) {
    const iconPath = getIconPath()
    tray.setImage(nativeImage.createFromPath(iconPath))
  }
}

function createWindow(): void {
  // Create the browser window.
  const iconPath = getIconPath()
  mainWindow = new BrowserWindow({
    width: 1000,
    height: 700,
    show: false,
    resizable: false, // Prevent resizing on login screen
    title: '韫珠IM',
    icon: iconPath,
    autoHideMenuBar: true,
    titleBarStyle: 'hidden', // Hide title bar
    titleBarOverlay: {
      color: '#ffffff', // Match login background
      symbolColor: '#747474', // Match control color
      height: 30
    },
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false,
      nodeIntegration: false,
      contextIsolation: true,
      webSecurity: true
    }
  })

  mainWindow.on('ready-to-show', () => {
    mainWindow?.show()
  })

  mainWindow.on('close', (event) => {
    if (!isQuitting) {
      event.preventDefault()
      mainWindow?.hide()
      return false
    }
    return true
  })
  
  mainWindow.on('focus', () => {
    stopBlinking()
    // 主界面显示时清除任务栏徽章
    app.setBadgeCount(0)
  })

  mainWindow.on('show', () => {
    // 主界面显示时清除任务栏徽章
    app.setBadgeCount(0)
  })

  mainWindow.webContents.setWindowOpenHandler((details) => {
    // Intercept target="_blank" and open custom browser window
    if (details.url.startsWith('http')) {
      createInternalBrowserWindow(details.url)
      return { action: 'deny' }
    }
    return { action: 'allow' }
  })

  // HMR for renderer base on electron-vite cli.
  // Load the remote URL for development or the local html file for production.
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
  } else {
    mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
  }
}

let browserWindow: BrowserWindow | null = null
let viewManager: ViewManager | null = null

// Function to create the custom browser window
function createInternalBrowserWindow(targetUrl: string): void {
  if (browserWindow && !browserWindow.isDestroyed()) {
    if (browserWindow.isMinimized()) browserWindow.restore()
    browserWindow.show()
    browserWindow.focus()
    
    // 如果窗口已存在，且管理器存在，则新建标签
    if (viewManager) {
        const id = viewManager.createTab(targetUrl, true)
        browserWindow.webContents.send('tab-created', { id, url: targetUrl, title: 'Loading...' })
    }
    return
  }

  const iconPath = getIconPath()
  browserWindow = new BrowserWindow({
    width: 1024,
    height: 768,
    title: '应用中心', // Built-in Browser
    icon: iconPath,
    autoHideMenuBar: true, // Show menu bar for navigation
    titleBarStyle: 'hidden',
    titleBarOverlay: {
      color: '#e2e2e2',
      symbolColor: '#333',
      height: 38
    },
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false,
      nodeIntegration: false,
      contextIsolation: true
    }
  })

  browserWindow.maximize()

  viewManager = new ViewManager(browserWindow)

  // Load the browser route with initial URL
  // We use hash parameter to avoid Vite dev server 403 error with query params on root
  const hash = `browser` // No url param here, we load it via ViewManager
  
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    browserWindow.loadURL(`${process.env['ELECTRON_RENDERER_URL']}#${hash}`)
  } else {
    browserWindow.loadFile(join(__dirname, '../renderer/index.html'), { hash: hash })
  }

  browserWindow.on('closed', () => {
    viewManager?.destroy()
    viewManager = null
    browserWindow = null
  })

  browserWindow.webContents.on('did-finish-load', () => {
    browserWindow?.setTitle('应用中心')
    // 初始打开第一个标签
    if (viewManager) {
        const id = viewManager.createTab(targetUrl, true)
        browserWindow?.webContents.send('tab-created', { id, url: targetUrl, title: 'Loading...' })
    }
  })
}

// 创建图片预览窗口
function createImagePreviewWindow(imageUrl: string): void {
  // 如果窗口已存在，先关闭
  if (previewWindow && !previewWindow.isDestroyed()) {
    previewWindow.close()
  }

  const iconPath = getIconPath()
  
  // 获取主窗口的位置和大小，使预览窗口覆盖主窗口
  let x = 0, y = 0, width = 1000, height = 700
  if (mainWindow && !mainWindow.isDestroyed()) {
    const bounds = mainWindow.getBounds()
    x = bounds.x
    y = bounds.y
    width = bounds.width
    height = bounds.height
  }

  previewWindow = new BrowserWindow({
    width: width,
    height: height,
    x: x,
    y: y,
    frame: false, // 无边框窗口
    alwaysOnTop: true, // 始终置顶
    transparent: false,
    backgroundColor: '#000000',
    show: false,
    resizable: true,
    minimizable: false,
    maximizable: false,
    closable: true,
    skipTaskbar: false,
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false,
      nodeIntegration: false,
      contextIsolation: true
    }
  })

  // 创建预览页面的 HTML 内容
  const htmlContent = `
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>图片预览</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    body {
      width: 100vw;
      height: 100vh;
      background-color: rgba(0, 0, 0, 0.95);
      display: flex;
      align-items: center;
      justify-content: center;
      overflow: hidden;
      cursor: pointer;
    }
    .image-container {
      position: relative;
      max-width: 90%;
      max-height: 90%;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    img {
      max-width: 100%;
      max-height: 100%;
      object-fit: contain;
      cursor: default;
    }
    .toolbar {
      position: fixed;
      top: 20px;
      right: 20px;
      display: flex;
      gap: 10px;
      z-index: 1000;
    }
    .toolbar-btn {
      padding: 10px 20px;
      background-color: rgba(255, 255, 255, 0.2);
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 16px;
      transition: background-color 0.2s;
    }
    .toolbar-btn:hover {
      background-color: rgba(255, 255, 255, 0.3);
    }
    .toolbar-btn:active {
      background-color: rgba(255, 255, 255, 0.4);
    }
    .toast {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background-color: rgba(0, 0, 0, 0.8);
      color: white;
      padding: 15px 30px;
      border-radius: 8px;
      font-size: 16px;
      z-index: 10000;
      display: none;
      pointer-events: none;
    }
    .toast.show {
      display: block;
      animation: fadeInOut 2s ease-in-out;
    }
    @keyframes fadeInOut {
      0%, 100% { opacity: 0; }
      10%, 90% { opacity: 1; }
    }
  </style>
</head>
<body>
  <div class="image-container">
    <img id="preview-image" src="${imageUrl.replace(/"/g, '&quot;').replace(/'/g, '&#39;')}" alt="预览图片" />
    <div id="toast" class="toast"></div>
  </div>
  <div class="toolbar">
    <button id="save-btn" class="toolbar-btn">💾 保存</button>
    <button id="close-btn" class="toolbar-btn">✕ 关闭</button>
  </div>
  <script>
    (function() {
      const imageUrl = ${JSON.stringify(imageUrl)};
      
      // 保存按钮点击事件
      document.getElementById('save-btn').addEventListener('click', (e) => {
        e.stopPropagation();
        if (window.electron && window.electron.ipcRenderer) {
          window.electron.ipcRenderer.send('save-image-preview', imageUrl);
        }
      });
      
      // 关闭按钮点击事件
      document.getElementById('close-btn').addEventListener('click', (e) => {
        e.stopPropagation();
        if (window.electron && window.electron.ipcRenderer) {
          window.electron.ipcRenderer.send('close-image-preview');
        }
      });
      // 点击背景关闭
      document.body.addEventListener('click', (e) => {
        if (e.target === document.body || e.target.classList.contains('image-container')) {
          if (window.electron && window.electron.ipcRenderer) {
            window.electron.ipcRenderer.send('close-image-preview')
          }
        }
      })
      
      // 按 ESC 键关闭
      document.addEventListener('keydown', (e) => {
        if (e.key === 'Escape') {
          if (window.electron && window.electron.ipcRenderer) {
            window.electron.ipcRenderer.send('close-image-preview')
          }
        }
      })
      
      // 阻止图片点击事件冒泡
      const img = document.querySelector('img')
      if (img) {
        img.addEventListener('click', (e) => {
          e.stopPropagation()
        })
      }

      // 显示提示消息
      function showToast(message) {
        const toast = document.getElementById('toast')
        if (toast) {
          toast.textContent = message
          toast.classList.add('show')
          setTimeout(() => {
            toast.classList.remove('show')
          }, 2000)
        }
      }

      // 监听保存成功/失败消息
      if (window.electron && window.electron.ipcRenderer) {
        window.electron.ipcRenderer.on('save-image-success', (_, filePath) => {
          const fileName = filePath.split(/[/\\\\]/).pop()
          showToast('保存成功: ' + fileName)
        })
        
        window.electron.ipcRenderer.on('save-image-error', (_, error) => {
          showToast('保存失败: ' + error)
        })
      }
    })()
  </script>
</body>
</html>
  `

  previewWindow.loadURL(`data:text/html;charset=utf-8,${encodeURIComponent(htmlContent)}`)

  previewWindow.once('ready-to-show', () => {
    previewWindow?.show()
    previewWindow?.focus()
  })

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

// 创建视频播放器窗口
function createVideoPlayerWindow(videoUrl: string, videoTitle?: string): void {
  // 如果窗口已存在，先关闭
  if (videoPlayerWindow && !videoPlayerWindow.isDestroyed()) {
    videoPlayerWindow.close()
  }

  const iconPath = getIconPath()
  
  // 获取主窗口的位置和大小，使播放器窗口覆盖主窗口
  let x = 0, y = 0, width = 1000, height = 700
  if (mainWindow && !mainWindow.isDestroyed()) {
    const bounds = mainWindow.getBounds()
    x = bounds.x
    y = bounds.y
    width = bounds.width
    height = bounds.height
  }

  videoPlayerWindow = new BrowserWindow({
    width: width,
    height: height,
    x: x,
    y: y,
    frame: false, // 无边框窗口
    alwaysOnTop: false, // 不置顶，允许用户切换窗口
    transparent: false,
    backgroundColor: '#000000',
    show: false,
    resizable: true,
    minimizable: true,
    maximizable: true,
    closable: true,
    skipTaskbar: false,
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false,
      nodeIntegration: false,
      contextIsolation: true,
      webSecurity: true // 启用 Web 安全，支持跨域视频
    }
  })

  // 创建视频播放器页面的 HTML 内容
  const htmlContent = `
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${videoTitle || '视频播放'}</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    body {
      width: 100vw;
      height: 100vh;
      background-color: #000000;
      display: flex;
      align-items: center;
      justify-content: center;
      overflow: hidden;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    }
    .video-container {
      position: relative;
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    video {
      max-width: 100%;
      max-height: 100%;
      width: auto;
      height: auto;
      outline: none;
    }
    .toolbar {
      position: fixed;
      top: 20px;
      right: 20px;
      display: flex;
      gap: 10px;
      z-index: 1000;
      opacity: 0;
      transition: opacity 0.3s;
    }
    .toolbar.visible {
      opacity: 1;
    }
    .toolbar-btn {
      padding: 10px 20px;
      background-color: rgba(255, 255, 255, 0.2);
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 16px;
      transition: background-color 0.2s;
      backdrop-filter: blur(10px);
    }
    .toolbar-btn:hover {
      background-color: rgba(255, 255, 255, 0.3);
    }
    .toolbar-btn:active {
      background-color: rgba(255, 255, 255, 0.4);
    }
    .toast {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background-color: rgba(0, 0, 0, 0.8);
      color: white;
      padding: 15px 30px;
      border-radius: 8px;
      font-size: 16px;
      z-index: 10000;
      display: none;
      pointer-events: none;
    }
    .toast.show {
      display: block;
      animation: fadeInOut 2s ease-in-out;
    }
    @keyframes fadeInOut {
      0%, 100% { opacity: 0; }
      10%, 90% { opacity: 1; }
    }
    .loading {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      color: white;
      font-size: 18px;
      z-index: 999;
    }
    .error {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      color: #ff4444;
      font-size: 18px;
      text-align: center;
      z-index: 999;
    }
  </style>
</head>
<body>
  <div class="video-container">
    <video 
      id="video-player" 
      controls 
      preload="auto"
      playsinline
      webkit-playsinline
      style="width: 100%; height: 100%; object-fit: contain;"
    >
      您的浏览器不支持视频播放
    </video>
    <div id="loading" class="loading">加载中...</div>
    <div id="error" class="error" style="display: none;"></div>
    <div id="toast" class="toast"></div>
  </div>
  <div class="toolbar" id="toolbar">
    <button id="download-btn" class="toolbar-btn">⬇️ 下载</button>
    <button id="fullscreen-btn" class="toolbar-btn">⛶ 全屏</button>
    <button id="close-btn" class="toolbar-btn">✕ 关闭</button>
  </div>
  <script>
    (function() {
      const videoUrl = ${JSON.stringify(videoUrl)};
      const videoTitle = ${JSON.stringify(videoTitle || 'video.mp4')};
      const video = document.getElementById('video-player');
      const loading = document.getElementById('loading');
      const error = document.getElementById('error');
      const toolbar = document.getElementById('toolbar');
      
      // 设置视频源
      video.src = videoUrl;
      
      // 显示工具栏
      function showToolbar() {
        toolbar.classList.add('visible');
      }
      
      function hideToolbar() {
        toolbar.classList.remove('visible');
      }
      
      // 鼠标移动时显示/隐藏工具栏
      let toolbarTimeout;
      document.addEventListener('mousemove', () => {
        showToolbar();
        clearTimeout(toolbarTimeout);
        toolbarTimeout = setTimeout(hideToolbar, 3000);
      });
      
      // 视频加载事件
      video.addEventListener('loadedmetadata', () => {
        loading.style.display = 'none';
        showToolbar();
        setTimeout(hideToolbar, 3000);
      });
      
      video.addEventListener('loadstart', () => {
        loading.style.display = 'block';
        error.style.display = 'none';
      });
      
      video.addEventListener('error', (e) => {
        loading.style.display = 'none';
        error.style.display = 'block';
        error.textContent = '视频加载失败，请检查网络连接或视频链接是否有效';
        console.error('Video error:', e);
      });
      
      // 下载按钮
      document.getElementById('download-btn').addEventListener('click', (e) => {
        e.stopPropagation();
        if (window.electron && window.electron.ipcRenderer) {
          window.electron.ipcRenderer.send('download-video', { url: videoUrl, filename: videoTitle });
        }
      });
      
      // 全屏按钮
      document.getElementById('fullscreen-btn').addEventListener('click', (e) => {
        e.stopPropagation();
        if (video.requestFullscreen) {
          video.requestFullscreen();
        } else if (video.webkitRequestFullscreen) {
          video.webkitRequestFullscreen();
        } else if (video.mozRequestFullScreen) {
          video.mozRequestFullScreen();
        } else if (video.msRequestFullscreen) {
          video.msRequestFullscreen();
        }
      });
      
      // 关闭按钮
      document.getElementById('close-btn').addEventListener('click', (e) => {
        e.stopPropagation();
        if (window.electron && window.electron.ipcRenderer) {
          window.electron.ipcRenderer.send('close-video-player');
        }
      });
      
      // 点击背景关闭（仅在工具栏可见时）
      document.body.addEventListener('click', (e) => {
        if (e.target === document.body || e.target.classList.contains('video-container')) {
          if (toolbar.classList.contains('visible')) {
            if (window.electron && window.electron.ipcRenderer) {
              window.electron.ipcRenderer.send('close-video-player');
            }
          }
        }
      });
      
      // 按 ESC 键关闭
      document.addEventListener('keydown', (e) => {
        if (e.key === 'Escape') {
          if (window.electron && window.electron.ipcRenderer) {
            window.electron.ipcRenderer.send('close-video-player');
          }
        }
      });
      
      // 阻止视频点击事件冒泡
      video.addEventListener('click', (e) => {
        e.stopPropagation();
      });
      
      // 显示提示消息
      function showToast(message) {
        const toast = document.getElementById('toast');
        if (toast) {
          toast.textContent = message;
          toast.classList.add('show');
          setTimeout(() => {
            toast.classList.remove('show');
          }, 2000);
        }
      }
      
      // 监听下载成功/失败消息
      if (window.electron && window.electron.ipcRenderer) {
        window.electron.ipcRenderer.on('download-video-success', (_, filePath) => {
          const fileName = filePath.split(/[/\\\\]/).pop();
          showToast('下载成功: ' + fileName);
        });
        
        window.electron.ipcRenderer.on('download-video-error', (_, error) => {
          showToast('下载失败: ' + error);
        });
      }
    })();
  </script>
</body>
</html>
  `

  videoPlayerWindow.loadURL(`data:text/html;charset=utf-8,${encodeURIComponent(htmlContent)}`)

  videoPlayerWindow.once('ready-to-show', () => {
    videoPlayerWindow?.show()
    videoPlayerWindow?.focus()
  })

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

// 统一处理来自渲染进程的 Browser Action
ipcMain.on('browser-action', (event, action) => {
    if (!viewManager || !browserWindow || browserWindow.isDestroyed()) return
    // 简单的鉴权：只允许 browserWindow 发送控制指令
    if (event.sender.id !== browserWindow.webContents.id) return

    switch (action.type) {
      case 'create-tab':
        const id = viewManager.createTab(action.url || 'about:blank', true)
        event.reply('tab-created', { id, url: action.url, title: 'Loading...' })
        break
      case 'switch-tab':
        viewManager.switchTab(action.id)
        break
      case 'close-tab':
        viewManager.closeTab(action.id)
        break
      case 'go-back':
        viewManager.goBack()
        break
      case 'go-forward':
        viewManager.goForward()
        break
      case 'reload':
        viewManager.reload()
        break
      case 'load-url':
        viewManager.loadURL(action.id, action.url)
        break
      case 'resize-view':
        if (action.bounds) {
            viewManager.setBounds(action.bounds)
        }
        break
    }
})

const gotTheLock = app.requestSingleInstanceLock()

if (!gotTheLock) {
  app.quit()
} else {

app.on('second-instance', () => {
  if (mainWindow) {
    if (mainWindow.isMinimized()) mainWindow.restore()
    if (!mainWindow.isVisible()) mainWindow.show()
    mainWindow.focus()
  }
})

app.whenReady().then(() => {
  electronApp.setAppUserModelId('com.hnyunzhu.im')
  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })

  ipcMain.on('ping', () => console.log('pong'))
  
  ipcMain.on('login-success', () => {
    if (mainWindow) {
      mainWindow.setSize(1000, 700)
      mainWindow.setResizable(true)
      mainWindow.center()
      mainWindow.setTitleBarOverlay({
        color: '#f5f5f5',
        symbolColor: '#747474',
        height: 30
      })
    }
  })

  ipcMain.on('start-notification', (_, data: { id: number, name: string, content: string }) => {
    const { id, name, content } = data
    const existing = unreadMap.get(id)
    unreadMap.set(id, {
      name,
      content,
      count: existing ? existing.count + 1 : 1
    })
    updateUnreadStatus()
  })

  // 清除未读消息
  ipcMain.on('clear-unread', (_, contactId: number) => {
    if (unreadMap.has(contactId)) {
      unreadMap.delete(contactId)
      updateUnreadStatus()
    }
  })

  // 清除所有未读消息
  ipcMain.on('clear-all-unread', () => {
    unreadMap.clear()
    updateUnreadStatus()
  })

  // 处理打开 URL 请求（用于通知消息的 SSO 跳转）
  ipcMain.on('open-url', (_, url: string) => {
    if (url && (url.startsWith('http://') || url.startsWith('https://'))) {
      // 使用内部浏览器窗口打开
      if (viewManager) {
        viewManager.createTab(url, true)
      } else {
        // 如果浏览器窗口未初始化，使用系统默认浏览器
        shell.openExternal(url)
      }
    }
  })

  // 使用系统默认浏览器打开 URL（应用中心「用系统浏览器打开」选项）
  ipcMain.on('open-url-external', (_, url: string) => {
    if (url && (url.startsWith('http://') || url.startsWith('https://'))) {
      shell.openExternal(url)
    }
  })

  // 处理打开图片预览窗口
  ipcMain.on('open-image-preview', (_, imageUrl: string) => {
    createImagePreviewWindow(imageUrl)
  })

  // 处理关闭图片预览窗口
  ipcMain.on('close-image-preview', () => {
    if (previewWindow && !previewWindow.isDestroyed()) {
      previewWindow.close()
    }
  })

  // 处理打开视频播放器窗口
  ipcMain.on('open-video-player', (_, videoUrl: string, videoTitle?: string) => {
    createVideoPlayerWindow(videoUrl, videoTitle)
  })

  // 处理关闭视频播放器窗口
  ipcMain.on('close-video-player', () => {
    if (videoPlayerWindow && !videoPlayerWindow.isDestroyed()) {
      videoPlayerWindow.close()
    }
  })

  // 处理视频下载（使用 Electron 下载 API，不会被拦截）
  ipcMain.on('download-video', async (event, { url, filename }) => {
    try {
      if (videoPlayerWindow && !videoPlayerWindow.isDestroyed()) {
        // 使用视频播放器窗口的 webContents 来下载
        videoPlayerWindow.webContents.downloadURL(url)
        
        videoPlayerWindow.webContents.session.once('will-download', (event, item) => {
          const filePath = join(app.getPath('downloads'), filename)
          item.setSavePath(filePath)
          
          item.once('done', (event, state) => {
            if (state === 'completed') {
              if (videoPlayerWindow && !videoPlayerWindow.isDestroyed()) {
                videoPlayerWindow.webContents.send('download-video-success', filePath)
              }
            } else {
              if (videoPlayerWindow && !videoPlayerWindow.isDestroyed()) {
                videoPlayerWindow.webContents.send('download-video-error', '下载失败')
              }
            }
          })
        })
      } else if (mainWindow && !mainWindow.isDestroyed()) {
        // 如果视频播放器窗口不存在，使用主窗口
        mainWindow.webContents.downloadURL(url)
        
        mainWindow.webContents.session.once('will-download', (event, item) => {
          const filePath = join(app.getPath('downloads'), filename)
          item.setSavePath(filePath)
        })
      }
    } catch (error: any) {
      console.error('Failed to download video:', error)
      if (videoPlayerWindow && !videoPlayerWindow.isDestroyed()) {
        videoPlayerWindow.webContents.send('download-video-error', error.message || '下载失败')
      }
    }
  })


  // 处理保存图片
  ipcMain.on('save-image-preview', async (_, imageUrl: string) => {
    try {
      // 临时取消预览窗口的置顶状态，以便显示保存对话框
      if (previewWindow && !previewWindow.isDestroyed()) {
        previewWindow.setAlwaysOnTop(false)
      }

      // 推断文件扩展名
      let defaultExt = 'png'
      try {
        const urlObj = new URL(imageUrl)
        const pathname = urlObj.pathname.toLowerCase()
        if (pathname.endsWith('.jpg') || pathname.endsWith('.jpeg')) {
          defaultExt = 'jpg'
        } else if (pathname.endsWith('.gif')) {
          defaultExt = 'gif'
        } else if (pathname.endsWith('.webp')) {
          defaultExt = 'webp'
        } else if (pathname.endsWith('.png')) {
          defaultExt = 'png'
        }
      } catch (e) {
        // URL 解析失败，使用默认扩展名
      }

      // 显示保存对话框
      const result = await dialog.showSaveDialog({
        title: '保存图片',
        defaultPath: `image.${defaultExt}`,
        filters: [
          { name: '图片文件', extensions: ['png', 'jpg', 'jpeg', 'gif', 'webp'] },
          { name: '所有文件', extensions: ['*'] }
        ]
      })

      // 恢复预览窗口的置顶状态
      if (previewWindow && !previewWindow.isDestroyed()) {
        previewWindow.setAlwaysOnTop(true)
      }

      if (result.canceled || !result.filePath) {
        return
      }

      const filePath = result.filePath

      // 处理不同类型的图片 URL
      if (imageUrl.startsWith('data:')) {
        // Data URL
        const base64Data = imageUrl.split(',')[1]
        const buffer = Buffer.from(base64Data, 'base64')
        await writeFile(filePath, buffer)
      } else if (imageUrl.startsWith('blob:') || imageUrl.startsWith('file://')) {
        // Blob URL 或 file:// URL，需要通过预览窗口的 webContents 获取
        if (previewWindow && !previewWindow.isDestroyed()) {
          const image = await previewWindow.webContents.downloadURL(imageUrl)
          // 对于 blob URL，我们需要通过其他方式获取
          // 这里我们尝试从预览窗口的 webContents 获取图片数据
          const dataUrl = await previewWindow.webContents.executeJavaScript(`
            new Promise((resolve) => {
              const img = document.getElementById('preview-image');
              const canvas = document.createElement('canvas');
              canvas.width = img.naturalWidth;
              canvas.height = img.naturalHeight;
              const ctx = canvas.getContext('2d');
              ctx.drawImage(img, 0, 0);
              resolve(canvas.toDataURL('image/png'));
            })
          `)
          const base64Data = dataUrl.split(',')[1]
          const buffer = Buffer.from(base64Data, 'base64')
          await writeFile(filePath, buffer)
        }
      } else if (imageUrl.startsWith('http://') || imageUrl.startsWith('https://')) {
        // HTTP/HTTPS URL
        const protocol = imageUrl.startsWith('https') ? https : http
        
        await new Promise<void>((resolve, reject) => {
          protocol.get(imageUrl, (response) => {
            if (response.statusCode !== 200) {
              reject(new Error(`Failed to download image: ${response.statusCode}`))
              return
            }

            const chunks: Buffer[] = []
            response.on('data', (chunk: Buffer) => {
              chunks.push(chunk)
            })
            response.on('end', async () => {
              try {
                const buffer = Buffer.concat(chunks)
                await writeFile(filePath, buffer)
                resolve()
              } catch (error) {
                reject(error)
              }
            })
            response.on('error', reject)
          }).on('error', reject)
        })
      } else {
        throw new Error('不支持的图片 URL 格式')
      }

      // 显示成功提示
      if (previewWindow && !previewWindow.isDestroyed()) {
        previewWindow.webContents.send('save-image-success', filePath)
      }
    } catch (error: any) {
      console.error('Failed to save image:', error)
      // 恢复预览窗口的置顶状态（即使出错也要恢复）
      if (previewWindow && !previewWindow.isDestroyed()) {
        previewWindow.setAlwaysOnTop(true)
        previewWindow.webContents.send('save-image-error', error.message || '保存失败')
      }
    }
  })

  // Create tray
  const iconPath = getIconPath()
  const trayIcon = nativeImage.createFromPath(iconPath)
  
  // Windows 托盘图标设置
  if (process.platform === 'win32') {
    // 确保图标不是模板模式，这样图标会正常显示
    trayIcon.setTemplateImage(false)
  }
  
  tray = new Tray(trayIcon)
  tray.setToolTip('韫珠IM')
  tray.on('click', () => {
    hideTrayPopup()
    mainWindow?.show()
  })
  tray.on('mouse-move', () => {
    if (unreadMap.size > 0) {
      showTrayPopup()
      cancelTrayPopupHide()

      if (!trayHoverCheckTimer) {
        trayHoverCheckTimer = setInterval(() => {
          if (!tray) return
          const cursor = screen.getCursorScreenPoint()
          const tb = tray.getBounds()
          const isOverTray = cursor.x >= tb.x && cursor.x <= tb.x + tb.width &&
                            cursor.y >= tb.y && cursor.y <= tb.y + tb.height

          let isOverPopup = false
          if (trayPopupWindow && !trayPopupWindow.isDestroyed() && trayPopupWindow.isVisible()) {
            const pb = trayPopupWindow.getBounds()
            isOverPopup = cursor.x >= pb.x && cursor.x <= pb.x + pb.width &&
                         cursor.y >= pb.y && cursor.y <= pb.y + pb.height
          }

          if (!isOverTray && !isOverPopup) {
            hideTrayPopup()
          }
        }, 300)
      }
    }
  })
  updateTrayMenu()

  ipcMain.on('tray-popup-click', (_, contactId: number) => {
    hideTrayPopup()
    if (mainWindow) {
      mainWindow.show()
      mainWindow.focus()
      mainWindow.webContents.send('switch-contact', contactId)
    }
  })

  ipcMain.on('tray-popup-dismiss', () => {
    hideTrayPopup()
  })

  ipcMain.on('tray-popup-mouse-leave', () => {
    scheduleTrayPopupHide()
  })

  ipcMain.on('tray-popup-mouse-enter', () => {
    cancelTrayPopupHide()
  })

  createWindow()

  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

} // end of gotTheLock else
