import { ipcMain, BrowserWindow } from 'electron';
import { exec } from 'child_process';
import { promisify } from 'util';
import { getCachedAdbPath, loadConfig } from '../config.js';

const execAsync = promisify(exec);

// 获取主窗口引用（用于实时推送设备发现事件）
function getMainWindow() {
  const windows = BrowserWindow.getAllWindows();
  return windows.length > 0 ? windows[0] : null;
}

// 获取 ADB 设备列表（每次都重新扫描网络）
export async function getADBDevices() {
  try {
    // 每次都重新扫描网络设备，不记录已连接的设备
    return await scanNetworkDevices(null);
  } catch (error) {
    console.error('获取设备列表失败:', error);
    return [];
  }
}

// 网络扫描：从 192.168.0.1 开始扫描网段，尝试连接设备（实时推送结果）
export async function scanNetworkDevices(event) {
  const adbPath = getCachedAdbPath();
  const baseIP = '192.168.0';
  const port = 5555;
  const maxConcurrent = 50; // 限制并发数，避免过载
  const connectTimeout = 1500; // 连接超时时间（毫秒）
  
  const foundDevices = new Set(); // 使用 Set 避免重复
  
  // 生成 IP 地址列表
  const ipList = [];
  for (let i = 1; i <= 255; i++) {
    ipList.push(`${baseIP}.${i}`);
  }
  
  // 推送设备发现的辅助函数
  const pushDevice = (ipPort) => {
    if (!foundDevices.has(ipPort)) {
      foundDevices.add(ipPort);
      const device = {
        id: ipPort,
        status: 'device'
      };
      // 实时发送发现的设备
      if (event && event.sender) {
        event.sender.send('device-found', device);
      } else {
        const mainWindow = getMainWindow();
        if (mainWindow) {
          mainWindow.webContents.send('device-found', device);
        }
      }
      console.log('发现设备:', ipPort);
    }
  };
  
  // 分批并发扫描，扫描到一个显示一个
  for (let i = 0; i < ipList.length; i += maxConcurrent) {
    const batch = ipList.slice(i, i + maxConcurrent);
    const promises = batch.map(async (ip) => {
      const ipPort = `${ip}:${port}`;
      try {
        // 先尝试连接设备
        await execAsync(`${adbPath} connect ${ipPort}`, {
          timeout: connectTimeout,
          maxBuffer: 1024 * 1024
        });
        
        // 连接后稍等片刻，让设备注册到 ADB 服务器
        await new Promise(resolve => setTimeout(resolve, 500));
      } catch (error) {
        // 连接失败是正常的，继续检查设备列表
      }
      
      // 调用 adb devices 命令获取所有设备列表，检查是否包含端口 5555 的设备
      try {
        const { stdout } = await execAsync(`${adbPath} devices`, {
          timeout: 2000,
          maxBuffer: 1024 * 1024
        });
        
        // 检查输出中是否包含该 IP:PORT（匹配端口 5555）
        // 使用正则表达式匹配 IP:5555 格式
        const devicePattern = new RegExp(`${ip.replace(/\./g, '\\.')}:${port}\\s+device`, 'i');
        if (devicePattern.test(stdout)) {
          // 发现设备，立即推送显示（不等待整批完成）
          pushDevice(ipPort);
          return ipPort;
        }
        // 如果没有匹配到，说明没有设备
      } catch (checkError) {
        // 检查失败，忽略
      }
      return null;
    });
    
    // 并发执行当前批次，但不等待所有完成才推送
    // 每个 promise 一旦发现设备就会立即推送
    await Promise.all(promises);
  }
  
  // 返回所有发现的设备
  return Array.from(foundDevices).map(ipPort => ({
    id: ipPort,
    status: 'device'
  }));
}

// 连接 ADB 设备
export async function connectDevice(ipPort) {
  try {
    const adbPath = getCachedAdbPath();
    await execAsync(`${adbPath} connect ${ipPort}`);
    return { success: true };
  } catch (error) {
    console.error('连接设备失败:', error);
    return { success: false, error: error.message };
  }
}

// 注册 IPC 处理器
export function registerIpcHandlers() {
  // IPC 处理程序：获取 ADB 路径配置
  ipcMain.handle('get-adb-path-config', async () => {
    const config = loadConfig();
    return config ? config['adb-path'] : null;
  });

  // IPC 处理程序：获取 ADB 设备列表
  ipcMain.handle('get-adb-devices', async () => {
    return await getADBDevices();
  });

  // IPC 处理程序：扫描网络设备（支持实时推送）
  ipcMain.handle('scan-adb-devices', async (event) => {
    try {
      const devices = await scanNetworkDevices(event);
      return devices;
    } catch (error) {
      console.error('网络扫描失败:', error);
      return [];
    }
  });

  // IPC 处理程序：连接 ADB 设备
  ipcMain.handle('connect-adb-device', async (event, ipPort) => {
    return await connectDevice(ipPort);
  });
}

