import { app, shell, BrowserWindow, ipcMain, Menu, session, screen, dialog } from 'electron'
import { electronApp, optimizer } from '@electron-toolkit/utils'
import Store from 'electron-store'
import { createWindow, createDrageWindow, unregisterAllShortcuts, getMainWindow } from './window.js'
import { setupIPC } from './ipc.js'
import { createTray, destroyTray,clearBrowserCache } from './tray.js'
import XEUtils from 'xe-utils'
import fs from 'fs'
import path from 'path'
import dayjs from 'dayjs'
import logger from './utils/logger'
import { clearAllSessionData } from './utils/cacheUtils.js'
import SingleInstanceManager from './utils/singleInstance.js'
import { setStoreValue, getStoreValue ,deleteStore} from './store.js'
import AutoLaunch from 'auto-launch'
import axios from 'axios'

import WebSocketClient from './utils/WebSocketClient';

let wsClient=null

// 延迟创建WebSocket连接，等待应用完全启动后再连接
function createWebSocketClient() {
  try {
    wsClient = new WebSocketClient({
      autoReconnect: true,
      autoReconnectAttempts: 9999,
      autoReconnectInterval: 5000,
      timeout: 30000,
    });

    wsClient.on('open', () => {
      logger.info('WebSocket连接已打开')
    });

    wsClient.on('error', (error) => {
      logger.error('WebSocket连接错误:', error)
    });

    wsClient.on('close', (data) => {
      logger.info('WebSocket连接已关闭:', data)
    });
  } catch (error) {
    logger.error('创建WebSocket客户端失败:', error)
  }
}


var minecraftAutoLauncher = new AutoLaunch({
  name: '百千万AI智能体共创平台',
  path: app.getPath('exe')
});

app.commandLine.appendSwitch('allow-insecure-localhost'); // 允许本地回环地址使用不安全连接
app.commandLine.appendSwitch('ignore-certificate-errors'); // 忽略证书错误（开发时可用）

const h5_client_url=getStoreValue("h5_client_url")
if(!XEUtils.isEmpty(h5_client_url)){
  logger.info("=======================h5_client_url 非空，设置 unsafely-treat-insecure-origin-as-secure的值为:"+h5_client_url)
  app.commandLine.appendSwitch('unsafely-treat-insecure-origin-as-secure', h5_client_url);
}

let difySite=getStoreValue("difySite")
if(!XEUtils.isEmpty(difySite)){
  difySite = XEUtils.parseUrl(difySite)
  logger.info("=======================h5_client_url 非空，设置 unsafely-treat-insecure-origin-as-secure的值为:"+h5_client_url+","+difySite.origin)
  app.commandLine.appendSwitch('unsafely-treat-insecure-origin-as-secure', h5_client_url+","+difySite.origin);
}


// 设置控制台编码为 UTF-8
logger.info(`当前运行平台: ${process.platform}`)
if (process.platform === 'win32') {
  logger.info('Windows 系统，设置控制台编码为 UTF-8')
  try {
    require('child_process').execSync('chcp 65001', { stdio: 'ignore' })
  } catch (error) {
    logger.error('设置控制台编码失败:', error)
  }
} else {
  logger.info('非 Windows 系统，使用默认编码')
}

logger.info('%cRed text. %cGreen text', 'color: red', 'color: green')

try {
  const store = new Store()
  logger.info('Store 初始化成功')
} catch (error) {
  logger.error('Store 初始化失败:', error)
}

app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors')
app.commandLine.appendSwitch('ignore-certificate-errors')

// 添加缓存相关配置，避免缓存错误
app.commandLine.appendSwitch('disable-http-cache')
app.commandLine.appendSwitch('disable-background-timer-throttling')
app.commandLine.appendSwitch('disable-renderer-backgrounding')

try {
  app.disableHardwareAcceleration()
  logger.info('硬件加速已禁用')
} catch (error) {
  logger.error('禁用硬件加速失败:', error)
}

logger.info(app.getPath('userData'))
logger.info('应用启动，日志文件路径:', logger.getLogPath())

// 添加更多启动信息
logger.info('开始初始化应用...')

// 清理缓存目录
function cleanupCacheDirectories() {
  try {
    const userDataPath = app.getPath('userData')
    const cachePaths = [
      path.join(userDataPath, 'Cache'),
      path.join(userDataPath, 'Code Cache'),
      path.join(userDataPath, 'GPUCache'),
      path.join(userDataPath, 'Service Worker'),
      path.join(userDataPath, 'Session Storage')
    ]

    for (const cachePath of cachePaths) {
      if (fs.existsSync(cachePath)) {
        logger.info(`清理缓存目录: ${cachePath}`)
        try {
          // 递归删除目录
          const deleteRecursive = (dirPath) => {
            if (fs.existsSync(dirPath)) {
              const files = fs.readdirSync(dirPath)
              for (const file of files) {
                const curPath = path.join(dirPath, file)
                if (fs.lstatSync(curPath).isDirectory()) {
                  deleteRecursive(curPath)
                } else {
                  try {
                    fs.unlinkSync(curPath)
                  } catch (error) {
                    logger.warn(`无法删除缓存文件: ${curPath}`, error.message)
                  }
                }
              }
              try {
                fs.rmdirSync(dirPath)
              } catch (error) {
                logger.warn(`无法删除缓存目录: ${dirPath}`, error.message)
              }
            }
          }
          
          deleteRecursive(cachePath)
          logger.info(`缓存目录清理完成: ${cachePath}`)
        } catch (error) {
          logger.error(`清理缓存目录失败: ${cachePath}`, error)
        }
      }
    }
  } catch (error) {
    logger.error('清理缓存目录失败:', error)
  }
}

/**
 * 单应用启动实现
 * 请求单一实例锁，
 * 如果该方法返回`false`，
 * 则表示已经有一个实例在运行，
 * 可以通过`app.quit()`方法退出当前实例。
 */
const gotTheLock = app.requestSingleInstanceLock()

if (!gotTheLock) {
  logger.info('检测到已有实例运行，退出当前实例')
  app.quit()
} else {
  logger.info('这是第一个实例，继续启动')

  // 监听第二个实例被运行时
  app.on('second-instance', (event, commandLine, workingDirectory) => {
    logger.info('检测到第二个实例启动，激活现有实例')
    // 当有第二个实例被运行时，激活之前的实例并将焦点置于其窗口
    const windows = BrowserWindow.getAllWindows()
    if (windows.length > 0) {
      const mainWindow = windows[0]
      if (mainWindow.isMinimized()) {
        mainWindow.restore()
      }
      mainWindow.show()
      mainWindow.focus()
    }
  })

  app.whenReady().then(() => {
    logger.info('应用已准备就绪，开始初始化...');

    // 清理缓存目录
    cleanupCacheDirectories()

    // 获取默认会话并全局设置允许第三方 Cookie
    const defaultSession = session.defaultSession;

    // 设置 Cookie 策略以允许第三方 Cookie
    defaultSession.setPermissionRequestHandler((webContents, permission, callback) => {
      callback(true);
    });

    electronApp.setAppUserModelId('com.huashiai.dify-market-manager-gui')

    app.on('browser-window-created', (_, window) => {
      optimizer.watchWindowShortcuts(window)
    })

    // 根据存储的状态决定是否创建悬浮窗口
    if (getStoreValue('showDrageWindow')) {
       createDrageWindow()
    }

    createWindow()

    createTray()
    setupIPC()

    // exe退出三秒之后即认为关闭过exe程序，退出登录
    checkIsKeepAlive()

    // 延迟创建WebSocket连接
    setTimeout(() => {
      createWebSocketClient()
    }, 2000); // 延迟2秒创建WebSocket连接

    minecraftAutoLauncher.isEnabled()
      .then(function(isEnabled){
        if(isEnabled){
          return;
        }
        minecraftAutoLauncher.enable();
      })
      .catch(function(err){
        logger.info(err)
      });

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

    logger.info('应用初始化完成');
  })

  // 修改窗口关闭行为
  app.on('window-all-closed',  async (event) => {
    if (process.platform !== 'darwin') {
      event.preventDefault();
      // 如果是重启过程，不执行任何清理操作
      if (app.isRestarting) {
        logger.info('检测到重启过程，跳过窗口关闭处理')
        return;
      }
      
      if (!app.isQuiting) {
        logger.info('用户关闭窗口，隐藏应用')
        // 如果不是主动退出，则隐藏所有窗口
        BrowserWindow.getAllWindows().forEach(window => {
          window.hide()
        })

        // 清除所有会话数据
        try {
          await clearAllSessionData('window-all-closed');
        } catch (error) {
          logger.error('窗口关闭时清理缓存失败:', error);
        }
        
        // 销毁托盘并退出应用
        destroyTray()
        app.quit();

      } else {
        logger.info('主动退出，完全关闭应用')
        // 如果是主动退出，则销毁托盘并退出应用
        destroyTray()
        // 使用 exit 确保完全退出
        app.exit(0)
      }
    }
  })

  app.on('before-quit', async (event) => {
    // 如果是重启过程，不执行任何清理操作
    if (app.isRestarting) {
      logger.info('检测到重启过程，跳过before-quit处理')
      return;
    }
    
    logger.info('应用即将退出，开始清理资源')
    // 在应用程序即将退出时执行操作，例如保存数据
    event.preventDefault();

    // 清除所有会话数据
    try {
      await clearAllSessionData('before-quit');
    } catch (error) {
      logger.error('应用退出时清理缓存失败:', error);
    }
    
    // 销毁托盘并退出应用
    destroyTray()
    // 使用 exit 确保完全退出
    app.exit(0);
  });

  // 在应用退出时注销所有快捷键
  app.on('will-quit', async (event) => {
    // 如果是重启过程，不执行任何清理操作
    if (app.isRestarting) {
      logger.info('检测到重启过程，跳过will-quit处理')
      return;
    }

    logger.info('应用即将退出，注销快捷键')
    event.preventDefault();

    // 清除所有会话数据
    try {
      await clearAllSessionData('will-quit');
    } catch (error) {
      logger.error('应用退出时清理缓存失败:', error);
    }

    unregisterAllShortcuts()
    destroyTray()
    
    // 清理完成后退出应用，使用 exit 确保完全退出
    app.exit(0);
  })

  // 监听进程退出信号，确保在系统强制关闭时也能清理缓存
  process.on('SIGTERM', async () => {
    logger.info('收到 SIGTERM 信号，开始清理缓存');
    try {
      await clearAllSessionData('SIGTERM');
    } catch (error) {
      logger.error('SIGTERM 时清理缓存失败:', error);
    }
    destroyTray()
    process.exit(0);
  });

  process.on('SIGINT', async () => {
    logger.info('收到 SIGINT 信号，开始清理缓存');
    try {
      await clearAllSessionData('SIGINT');
    } catch (error) {
      logger.error('SIGINT 时清理缓存失败:', error);
    }
    destroyTray()
    process.exit(0);
  });

  // 监听未捕获的异常，确保应用崩溃时也能记录日志
  process.on('uncaughtException', (error) => {
    logger.error('未捕获的异常:', error);
    // 不要立即退出，给应用一个恢复的机会
    logger.error('应用遇到未捕获的异常，但将继续运行');
  });

  process.on('unhandledRejection', (reason, promise) => {
    logger.error('未处理的 Promise 拒绝:', reason);
    // 不要立即退出，给应用一个恢复的机会
    logger.error('应用遇到未处理的 Promise 拒绝，但将继续运行');
  });
}

export function checkIsKeepAlive(){

  const checkIsKeepAliveTimer=setInterval(async () => {

    const lastAliveTime = getStoreValue("lastAliveTime")||null

    if (lastAliveTime!=null){
       const nowTime=dayjs();
       const lastTime=dayjs(lastAliveTime);
       const diff=nowTime.diff(lastTime, 'second')


       // 上次在线事件在三秒之前，则认为关闭过exe程序
       if (diff>5){
        logger.info('上次在线事件在三秒之前，则认为关闭过exe程序')
        await clearAllSessionData('超时5秒');
        deleteStore("lastAliveTime")
       }else{
         setStoreValue("lastAliveTime",dayjs())
       }
    }
    
  }, 1000 * 2)

}