const { app, BrowserWindow ,ipcMain} = require('electron')
const path = require('path')
const http = require('http')
const os = require('os')
const fs = require('fs')
const config = require('../configs/config.js')
const isDev = process.env.NODE_ENV === 'development' || !app.isPackaged

// 修复缓存权限问题：设置用户数据目录到有权限的位置
// 必须在 app.whenReady() 之前调用
if (process.platform === 'win32') {
  try {
    // 设置缓存目录到用户临时目录，避免权限问题
    const userDataPath = path.join(os.tmpdir(), 'electron-react-vite-app')
    
    // 确保目录存在
    if (!fs.existsSync(userDataPath)) {
      fs.mkdirSync(userDataPath, { recursive: true })
    }
    
    // 创建缓存子目录
    const cacheDir = path.join(userDataPath, 'cache')
    const gpuCacheDir = path.join(userDataPath, 'gpu-cache')
    if (!fs.existsSync(cacheDir)) {
      fs.mkdirSync(cacheDir, { recursive: true })
    }
    if (!fs.existsSync(gpuCacheDir)) {
      fs.mkdirSync(gpuCacheDir, { recursive: true })
    }
    
    // 设置用户数据路径（必须在 app.whenReady() 之前）
    app.setPath('userData', userDataPath)
    
    // 设置缓存目录到有权限的位置
    app.commandLine.appendSwitch('disk-cache-dir', cacheDir)
    app.commandLine.appendSwitch('gpu-disk-cache-dir', gpuCacheDir)
    
    console.log(`[OK] Cache directories set to: ${userDataPath}`)
  } catch (error) {
    console.warn('[WARN] Failed to set cache directories:', error.message)
    // 如果设置失败，尝试禁用 GPU 缓存作为备选方案
    app.commandLine.appendSwitch('disable-gpu-sandbox')
  }
}

/**
 * 检测 Vite 开发服务器实际使用的端口
 * 如果配置的端口被占用，Vite 会自动尝试下一个端口
 * 需要确认是 Vite 服务器，而不仅仅是端口响应
 */
async function findVitePort(startPort, maxAttempts = 10) {
  const viteHost = config.vite?.host || 'localhost'
  
  for (let offset = 0; offset < maxAttempts; offset++) {
    const port = startPort + offset
    const isViteServer = await new Promise((resolve) => {
      const req = http.get(`http://${viteHost}:${port}`, (res) => {
        // 检查状态码
        if (res.statusCode !== 200) {
          resolve(false)
          return
        }
        
        // 读取响应数据确认是否是 Vite 服务器
        let data = ''
        let resolved = false
        
        res.on('data', (chunk) => {
          if (resolved) return
          data += chunk.toString()
          // 如果响应包含 Vite 特征，立即确认
          if (data.length > 100 && (data.includes('/vite') || data.includes('Vite') || data.includes('vite/client'))) {
            resolved = true
            resolve(true)
          }
        })
        
        res.on('end', () => {
          if (resolved) return
          // 检查响应内容是否包含 Vite 特征
          if (data.includes('/vite') || data.includes('Vite') || data.includes('vite/client')) {
            resolve(true)
          } else {
            resolve(false)
          }
        })
      })
      
      req.on('error', () => {
        resolve(false)
      })
      
      req.setTimeout(2000, () => {
        req.destroy()
        resolve(false)
      })
    })
    
    if (isViteServer) {
      return port
    }
  }
  
  // 如果找不到，返回配置的端口
  return startPort
}

async function createWindow() {
  const mainWindow = new BrowserWindow({
    width: config.window.width,
    height: config.window.height,
    autoHideMenuBar: config.window.autoHideMenuBar, // 从配置文件读取
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      preload: path.join(__dirname, 'preload.js') 
    }
  })

  if (isDev) {
    // 从配置文件读取 Vite 开发服务器端口
    const configPort = config.vite?.port || 5173
    // 检测实际使用的端口（如果配置端口被占用，Vite 会自动尝试下一个）
    const vitePort = await findVitePort(configPort)
    const viteHost = config.vite?.host || 'localhost'
    
    console.log(`Loading Vite dev server at http://${viteHost}:${vitePort}`)
    mainWindow.loadURL(`http://${viteHost}:${vitePort}`)
    
    // 根据配置文件决定是否打开调试侧边栏
    if (config.devTools.enabled) {
      mainWindow.webContents.openDevTools()
    }
  } else {
    mainWindow.loadFile(path.join(__dirname, '../dist/index.html'))
  }
}

const { spawn } = require('child_process')

// Execute Node.js script
ipcMain.handle('run-nodejs-script', async (event, scriptName, ...parameters) => {
  return new Promise((resolve, reject) => {
    const scriptPath = path.join(__dirname, '../nodejs', `${scriptName}.js`)
    const nodeProcess = spawn('node', [scriptPath, ...parameters])
    
    let stdout = ''
    let stderr = ''
    
    nodeProcess.stdout.on('data', (data) => {
      stdout += data.toString()
    })
    
    nodeProcess.stderr.on('data', (data) => {
      stderr += data.toString()
    })
    
    nodeProcess.on('close', (code) => {
      resolve({
        success: code === 0,
        stdout: stdout.trim(),
        stderr: stderr.trim(),
        exitCode: code
      })
    })
    
    nodeProcess.on('error', (error) => {
      reject(error)
    })
  })
})

// Execute Python script
ipcMain.handle('run-python-script', async (event, scriptName, ...parameters) => {
  return new Promise((resolve, reject) => {
    let pythonPath = 'python'
    
    if (config.pythonPath?.path) {
      const configPythonPath = path.join(config.pythonPath.path, 'python.exe')
      if (fs.existsSync(configPythonPath)) {
        pythonPath = configPythonPath
      }
    }
    
    const scriptPath = path.join(__dirname, '../python/scripts', `${scriptName}.py`)
    
    if (!fs.existsSync(scriptPath)) {
      reject({
        success: false,
        error: `Script file not found: ${scriptPath}`,
        stderr: `Script file not found: ${scriptPath}`
      })
      return
    }
    
    const pythonProcess = spawn(pythonPath, [scriptPath, ...parameters])
    
    let stdout = ''
    let stderr = ''
    
    pythonProcess.stdout.on('data', (data) => {
      stdout += data.toString()
    })
    
    pythonProcess.stderr.on('data', (data) => {
      stderr += data.toString()
    })
    
    pythonProcess.on('close', (code) => {
      resolve({
        success: code === 0,
        stdout: stdout.trim(),
        stderr: stderr.trim(),
        exitCode: code
      })
    })
    
    pythonProcess.on('error', (error) => {
      reject({
        success: false,
        error: error.message,
        stderr: error.message
      })
    })
  })
})

app.whenReady().then(() => {
  createWindow()

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

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