import {
  app,
  BrowserWindow,
  ipcMain,
  shell,
  Tray,
  Menu,
  nativeImage,
} from "electron";
import { join } from "path";
import { PhpManager } from "./services/PhpManager";
import { MysqlManager } from "./services/MysqlManager";
import { NginxManager } from "./services/NginxManager";
import { RedisManager } from "./services/RedisManager";
import { NodeManager } from "./services/NodeManager";
import { ServiceManager } from "./services/ServiceManager";
import { HostsManager } from "./services/HostsManager";
import { GitManager } from "./services/GitManager";
import { PythonManager } from "./services/PythonManager";
import { GoManager } from "./services/GoManager";
import { LogManager } from "./services/LogManager";
import { ConfigStore } from "./services/ConfigStore";

// 获取图标路径
function getIconPath(filename: string): string {
  const { existsSync } = require("fs");

  // 打包后的路径
  if (app.isPackaged) {
    const paths = [
      join(process.resourcesPath, "public", filename),
      join(process.resourcesPath, filename),
      join(__dirname, "../public", filename),
    ];
    for (const p of paths) {
      if (existsSync(p)) return p;
    }
  }

  // 开发环境路径
  const devPaths = [
    join(__dirname, "../public", filename),
    join(__dirname, "../dist", filename),
  ];
  for (const p of devPaths) {
    if (existsSync(p)) return p;
  }

  return join(__dirname, "../public/icon.ico");
}

// 获取托盘图标路径
function getTrayIconPath(): string {
  return getIconPath("icon.ico");
}

// 获取窗口图标路径
function getWindowIconPath(): string {
  return getIconPath("icon.ico");
}

// 创建托盘图标
function createTrayIcon(): Electron.NativeImage {
  const iconPath = getTrayIconPath();
  console.log("Tray icon path:", iconPath);
  try {
    const icon = nativeImage.createFromPath(iconPath);
    if (!icon.isEmpty()) {
      // 托盘图标需要较小尺寸
      return icon.resize({ width: 16, height: 16 });
    }
  } catch (e) {
    console.error("Failed to load tray icon:", e);
  }
  return nativeImage.createEmpty();
}

// 创建窗口图标
function createWindowIcon(): Electron.NativeImage {
  const iconPath = getWindowIconPath();
  console.log("Window icon path:", iconPath);
  try {
    const icon = nativeImage.createFromPath(iconPath);
    if (!icon.isEmpty()) {
      return icon;
    }
  } catch (e) {
    console.error("Failed to load window icon:", e);
  }
  return nativeImage.createEmpty();
}

let mainWindow: BrowserWindow | null = null;
let tray: Tray | null = null;
let isQuitting = false;

// 发送下载进度到渲染进程
export function sendDownloadProgress(
  type: string,
  progress: number,
  downloaded: number,
  total: number
) {
  if (mainWindow && !mainWindow.isDestroyed()) {
    mainWindow.webContents.send("download-progress", {
      type,
      progress,
      downloaded,
      total,
    });
  }
}

// 初始化各服务管理器
const configStore = new ConfigStore();
const phpManager = new PhpManager(configStore);
const mysqlManager = new MysqlManager(configStore);
const nginxManager = new NginxManager(configStore);
const redisManager = new RedisManager(configStore);
const nodeManager = new NodeManager(configStore);
const serviceManager = new ServiceManager(configStore);
const hostsManager = new HostsManager();
const gitManager = new GitManager(configStore);
const pythonManager = new PythonManager(configStore);
const goManager = new GoManager(configStore);
const logManager = new LogManager(configStore);

function createWindow() {
  const appIcon = createWindowIcon();

  mainWindow = new BrowserWindow({
    width: 1400,
    height: 900,
    minWidth: 1200,
    minHeight: 700,
    webPreferences: {
      preload: join(__dirname, "preload.js"),
      contextIsolation: true,
      nodeIntegration: false,
    },
    titleBarStyle: "hidden",
    titleBarOverlay: {
      color: "#1a1a2e",
      symbolColor: "#ffffff",
      height: 40,
    },
    frame: false,
    icon: appIcon,
    show: false, // 先不显示，等 ready-to-show
  });

  // 开发环境加载 Vite 开发服务器
  const VITE_DEV_SERVER_URL = process.env.VITE_DEV_SERVER_URL;
  if (VITE_DEV_SERVER_URL) {
    mainWindow.loadURL(VITE_DEV_SERVER_URL);
    mainWindow.webContents.openDevTools();
  } else {
    mainWindow.loadFile(join(__dirname, "../dist/index.html"));
  }

  // 窗口准备好后显示
  mainWindow.once("ready-to-show", () => {
    // 检查是否开机自启且静默启动
    const startMinimized = configStore.get("startMinimized");
    if (!startMinimized) {
      mainWindow?.show();
    }
  });

  // 关闭按钮改为最小化到托盘
  mainWindow.on("close", (event) => {
    if (!isQuitting) {
      event.preventDefault();
      mainWindow?.hide();
    }
  });

  mainWindow.on("closed", () => {
    mainWindow = null;
  });
}

// 创建系统托盘
function createTray() {
  // 创建托盘图标
  const trayIcon = createTrayIcon();

  tray = new Tray(trayIcon);
  tray.setToolTip("PHPer 开发环境管理器");

  // 创建托盘菜单
  const contextMenu = Menu.buildFromTemplate([
    {
      label: "显示主窗口",
      click: () => {
        if (mainWindow) {
          mainWindow.show();
          mainWindow.focus();
        } else {
          createWindow();
        }
      },
    },
    { type: "separator" },
    {
      label: "启动全部服务",
      click: async () => {
        const result = await serviceManager.startAll();
        if (mainWindow && !mainWindow.isDestroyed()) {
          mainWindow.webContents.send("service-status-changed");
        }
      },
    },
    {
      label: "停止全部服务",
      click: async () => {
        const result = await serviceManager.stopAll();
        if (mainWindow && !mainWindow.isDestroyed()) {
          mainWindow.webContents.send("service-status-changed");
        }
      },
    },
    { type: "separator" },
    {
      label: "退出",
      click: () => {
        isQuitting = true;
        app.quit();
      },
    },
  ]);

  tray.setContextMenu(contextMenu);

  // 双击托盘图标显示窗口
  tray.on("double-click", () => {
    if (mainWindow) {
      mainWindow.show();
      mainWindow.focus();
    } else {
      createWindow();
    }
  });
}

// 单实例锁定
const gotTheLock = app.requestSingleInstanceLock();

if (!gotTheLock) {
  // 如果获取不到锁，说明已有实例在运行，退出当前实例
  app.quit();
} else {
  // 当第二个实例启动时，聚焦到第一个实例的窗口
  app.on("second-instance", () => {
    if (mainWindow) {
      if (mainWindow.isMinimized()) {
        mainWindow.restore();
      }
      mainWindow.show();
      mainWindow.focus();
    }
  });

  app.whenReady().then(async () => {
    createTray();
    createWindow();

    // 根据配置自动启动服务
    try {
      const result = await serviceManager.startAutoStartServices();
      if (result.details.length > 0) {
        console.log("自动启动服务:", result.details.join(", "));
      }
    } catch (error) {
      console.error("自动启动服务失败:", error);
    }

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

  // 不要在所有窗口关闭时退出，保持托盘运行
  app.on("window-all-closed", () => {
    // 什么都不做，保持后台运行
  });

  // 真正退出前清理
  app.on("before-quit", () => {
    isQuitting = true;
  });
}

// ==================== IPC 处理程序 ====================

// 窗口控制
ipcMain.handle("window:minimize", () => mainWindow?.minimize());
ipcMain.handle("window:maximize", () => {
  if (mainWindow?.isMaximized()) {
    mainWindow.unmaximize();
  } else {
    mainWindow?.maximize();
  }
});
ipcMain.handle("window:close", () => mainWindow?.close());

// 打开外部链接
ipcMain.handle("shell:openExternal", (_, url: string) =>
  shell.openExternal(url)
);
ipcMain.handle("shell:openPath", (_, path: string) => shell.openPath(path));

// 选择文件夹对话框
ipcMain.handle("dialog:selectDirectory", async () => {
  const { dialog } = await import("electron");
  const result = await dialog.showOpenDialog(mainWindow!, {
    properties: ["openDirectory"],
    title: "选择目录",
  });
  return result.canceled ? null : result.filePaths[0];
});

// ==================== PHP 管理 ====================
ipcMain.handle("php:getVersions", () => phpManager.getInstalledVersions());
ipcMain.handle("php:getAvailableVersions", () =>
  phpManager.getAvailableVersions()
);
ipcMain.handle("php:install", (_, version: string) =>
  phpManager.install(version)
);
ipcMain.handle("php:uninstall", (_, version: string) =>
  phpManager.uninstall(version)
);
ipcMain.handle("php:setActive", (_, version: string) =>
  phpManager.setActive(version)
);
ipcMain.handle("php:getExtensions", (_, version: string) =>
  phpManager.getExtensions(version)
);
ipcMain.handle("php:openExtensionDir", (_, version: string) =>
  phpManager.openExtensionDir(version)
);
ipcMain.handle(
  "php:getAvailableExtensions",
  (_, version: string, searchKeyword?: string) =>
    phpManager.getAvailableExtensions(version, searchKeyword)
);
ipcMain.handle("php:enableExtension", (_, version: string, ext: string) =>
  phpManager.enableExtension(version, ext)
);
ipcMain.handle("php:disableExtension", (_, version: string, ext: string) =>
  phpManager.disableExtension(version, ext)
);
ipcMain.handle(
  "php:installExtension",
  (
    _,
    version: string,
    ext: string,
    downloadUrl?: string,
    packageName?: string
  ) => phpManager.installExtension(version, ext, downloadUrl, packageName)
);
ipcMain.handle("php:getConfig", (_, version: string) =>
  phpManager.getConfig(version)
);
ipcMain.handle("php:saveConfig", (_, version: string, config: string) =>
  phpManager.saveConfig(version, config)
);

// ==================== Composer 管理 ====================
ipcMain.handle("composer:getStatus", () => phpManager.getComposerStatus());
ipcMain.handle("composer:install", () => phpManager.installComposer());
ipcMain.handle("composer:uninstall", () => phpManager.uninstallComposer());
ipcMain.handle("composer:setMirror", (_, mirror: string) =>
  phpManager.setComposerMirror(mirror)
);
ipcMain.handle(
  "composer:createLaravelProject",
  (_, projectName: string, targetDir: string) =>
    phpManager.createLaravelProject(projectName, targetDir)
);

// ==================== MySQL 管理 ====================
ipcMain.handle("mysql:getVersions", () => mysqlManager.getInstalledVersions());
ipcMain.handle("mysql:getAvailableVersions", () =>
  mysqlManager.getAvailableVersions()
);
ipcMain.handle("mysql:install", (_, version: string) =>
  mysqlManager.install(version)
);
ipcMain.handle("mysql:uninstall", (_, version: string) =>
  mysqlManager.uninstall(version)
);
ipcMain.handle("mysql:start", (_, version: string) =>
  mysqlManager.start(version)
);
ipcMain.handle("mysql:stop", (_, version: string) =>
  mysqlManager.stop(version)
);
ipcMain.handle("mysql:restart", (_, version: string) =>
  mysqlManager.restart(version)
);
ipcMain.handle("mysql:getStatus", (_, version: string) =>
  mysqlManager.getStatus(version)
);
ipcMain.handle(
  "mysql:changePassword",
  (_, version: string, newPassword: string, currentPassword?: string) =>
    mysqlManager.changeRootPassword(version, newPassword, currentPassword)
);
ipcMain.handle("mysql:getConfig", (_, version: string) =>
  mysqlManager.getConfig(version)
);
ipcMain.handle("mysql:saveConfig", (_, version: string, config: string) =>
  mysqlManager.saveConfig(version, config)
);
ipcMain.handle("mysql:reinitialize", (_, version: string) =>
  mysqlManager.reinitialize(version)
);

// ==================== Nginx 管理 ====================
ipcMain.handle("nginx:getVersions", () => nginxManager.getInstalledVersions());
ipcMain.handle("nginx:getAvailableVersions", () =>
  nginxManager.getAvailableVersions()
);
ipcMain.handle("nginx:install", (_, version: string) =>
  nginxManager.install(version)
);
ipcMain.handle("nginx:uninstall", (_, version: string) =>
  nginxManager.uninstall(version)
);
ipcMain.handle("nginx:start", () => nginxManager.start());
ipcMain.handle("nginx:stop", () => nginxManager.stop());
ipcMain.handle("nginx:restart", () => nginxManager.restart());
ipcMain.handle("nginx:reload", () => nginxManager.reload());
ipcMain.handle("nginx:getStatus", () => nginxManager.getStatus());
ipcMain.handle("nginx:getConfig", () => nginxManager.getConfig());
ipcMain.handle("nginx:saveConfig", (_, config: string) =>
  nginxManager.saveConfig(config)
);
ipcMain.handle("nginx:getSites", () => nginxManager.getSites());
ipcMain.handle("nginx:addSite", (_, site: any) => nginxManager.addSite(site));
ipcMain.handle("nginx:removeSite", (_, name: string) =>
  nginxManager.removeSite(name)
);
ipcMain.handle("nginx:updateSite", (_, originalName: string, site: any) =>
  nginxManager.updateSite(originalName, site)
);
ipcMain.handle("nginx:enableSite", (_, name: string) =>
  nginxManager.enableSite(name)
);
ipcMain.handle("nginx:disableSite", (_, name: string) =>
  nginxManager.disableSite(name)
);
ipcMain.handle("nginx:generateLaravelConfig", (_, site: any) =>
  nginxManager.generateLaravelConfig(site)
);
ipcMain.handle("nginx:requestSSL", (_, domain: string, email: string) =>
  nginxManager.requestSSLCertificate(domain, email)
);

// ==================== Redis 管理 ====================
ipcMain.handle("redis:getVersions", () => redisManager.getInstalledVersions());
ipcMain.handle("redis:getAvailableVersions", () =>
  redisManager.getAvailableVersions()
);
ipcMain.handle("redis:install", (_, version: string) =>
  redisManager.install(version)
);
ipcMain.handle("redis:uninstall", (_, version: string) =>
  redisManager.uninstall(version)
);
ipcMain.handle("redis:start", () => redisManager.start());
ipcMain.handle("redis:stop", () => redisManager.stop());
ipcMain.handle("redis:restart", () => redisManager.restart());
ipcMain.handle("redis:getStatus", () => redisManager.getStatus());
ipcMain.handle("redis:getConfig", () => redisManager.getConfig());
ipcMain.handle("redis:saveConfig", (_, config: string) =>
  redisManager.saveConfig(config)
);

// ==================== Node.js 管理 ====================
ipcMain.handle("node:getVersions", () => nodeManager.getInstalledVersions());
ipcMain.handle("node:getAvailableVersions", () =>
  nodeManager.getAvailableVersions()
);
ipcMain.handle("node:install", (_, version: string, downloadUrl: string) =>
  nodeManager.install(version, downloadUrl)
);
ipcMain.handle("node:uninstall", (_, version: string) =>
  nodeManager.uninstall(version)
);
ipcMain.handle("node:setActive", (_, version: string) =>
  nodeManager.setActive(version)
);
ipcMain.handle("node:getInfo", (_, version: string) =>
  nodeManager.getNodeInfo(version)
);

// ==================== 服务管理 ====================
ipcMain.handle("service:getAll", () => serviceManager.getAllServices());
ipcMain.handle("service:setAutoStart", (_, service: string, enabled: boolean) =>
  serviceManager.setAutoStart(service, enabled)
);
ipcMain.handle("service:getAutoStart", (_, service: string) =>
  serviceManager.getAutoStart(service)
);
ipcMain.handle("service:startAll", () => serviceManager.startAll());
ipcMain.handle("service:stopAll", () => serviceManager.stopAll());
// PHP-CGI 管理 - 支持多版本
ipcMain.handle("service:getPhpCgiStatus", () => serviceManager.getPhpCgiStatus());
ipcMain.handle("service:startPhpCgi", () => serviceManager.startPhpCgi());
ipcMain.handle("service:stopPhpCgi", () => serviceManager.stopPhpCgi());
ipcMain.handle("service:startAllPhpCgi", () => serviceManager.startAllPhpCgi());
ipcMain.handle("service:stopAllPhpCgi", () => serviceManager.stopAllPhpCgi());
ipcMain.handle("service:startPhpCgiVersion", (_, version: string) => serviceManager.startPhpCgiVersion(version));
ipcMain.handle("service:stopPhpCgiVersion", (_, version: string) => serviceManager.stopPhpCgiVersion(version));
ipcMain.handle("service:getPhpCgiPort", (_, version: string) => serviceManager.getPhpCgiPort(version));

// ==================== Hosts 管理 ====================
ipcMain.handle("hosts:get", () => hostsManager.getHosts());
ipcMain.handle("hosts:add", (_, domain: string, ip: string) =>
  hostsManager.addHost(domain, ip)
);
ipcMain.handle("hosts:remove", (_, domain: string) =>
  hostsManager.removeHost(domain)
);

// ==================== Git 管理 ====================
ipcMain.handle("git:getVersions", () => gitManager.getInstalledVersions());
ipcMain.handle("git:getAvailableVersions", () =>
  gitManager.getAvailableVersions()
);
ipcMain.handle("git:install", (_, version: string) =>
  gitManager.install(version)
);
ipcMain.handle("git:uninstall", () => gitManager.uninstall());
ipcMain.handle("git:checkSystem", () => gitManager.checkSystemGit());
ipcMain.handle("git:getConfig", () => gitManager.getGitConfig());
ipcMain.handle("git:setConfig", (_, name: string, email: string) =>
  gitManager.setGitConfig(name, email)
);

// ==================== Python 管理 ====================
ipcMain.handle("python:getVersions", () => pythonManager.getInstalledVersions());
ipcMain.handle("python:getAvailableVersions", () =>
  pythonManager.getAvailableVersions()
);
ipcMain.handle("python:install", (_, version: string) =>
  pythonManager.install(version)
);
ipcMain.handle("python:uninstall", (_, version: string) =>
  pythonManager.uninstall(version)
);
ipcMain.handle("python:setActive", (_, version: string) =>
  pythonManager.setActive(version)
);
ipcMain.handle("python:checkSystem", () => pythonManager.checkSystemPython());
ipcMain.handle("python:getPipInfo", (_, version: string) =>
  pythonManager.getPipInfo(version)
);
ipcMain.handle(
  "python:installPackage",
  (_, version: string, packageName: string) =>
    pythonManager.installPackage(version, packageName)
);

// ==================== Go 管理 ====================
ipcMain.handle("go:getVersions", () => goManager.getInstalledVersions());
ipcMain.handle("go:getAvailableVersions", () =>
  goManager.getAvailableVersions()
);
ipcMain.handle("go:install", (_, version: string, downloadUrl: string, expectedSha256?: string) =>
  goManager.install(version, downloadUrl, expectedSha256)
);
ipcMain.handle("go:uninstall", (_, version: string) =>
  goManager.uninstall(version)
);
ipcMain.handle("go:setActive", (_, version: string) =>
  goManager.setActive(version)
);
ipcMain.handle("go:validateInstallation", (_, version: string) =>
  goManager.validateInstallation(version)
);
ipcMain.handle("go:getInfo", (_, version: string) =>
  goManager.getGoInfo(version)
);
ipcMain.handle("go:detectSystemVersion", () =>
  goManager.detectSystemGoVersion()
);

// ==================== 配置管理 ====================
ipcMain.handle("config:get", (_, key: string) => configStore.get(key));
ipcMain.handle("config:set", (_, key: string, value: any) =>
  configStore.set(key, value)
);
ipcMain.handle("config:getBasePath", () => configStore.getBasePath());
ipcMain.handle("config:setBasePath", (_, path: string) =>
  configStore.setBasePath(path)
);

// ==================== 应用设置 ====================
// 设置开机自启（以管理员模式，使用任务计划程序，静默启动）
ipcMain.handle("app:setAutoLaunch", async (_, enabled: boolean) => {
  const { execSync, exec } = require("child_process");
  const { writeFileSync, unlinkSync, existsSync } = require("fs");
  const { join } = require("path");
  const exePath = app.getPath("exe");
  const taskName = "PHPerDevManager";

  // 开发模式下不支持
  if (!app.isPackaged) {
    return {
      success: false,
      message: "开发模式下不支持开机自启，请打包后使用",
    };
  }

  try {
    if (enabled) {
      // 先删除可能存在的旧任务
      try {
        execSync(`schtasks /delete /tn "${taskName}" /f`, {
          encoding: "buffer",
          windowsHide: true,
        });
      } catch (e) {
        // 忽略删除失败（可能任务不存在）
      }

      // 创建 VBS 启动脚本（确保静默启动）
      const appDir = require("path").dirname(exePath);
      const vbsPath = join(appDir, "silent_start.vbs");
      const vbsContent = `Set WshShell = CreateObject("WScript.Shell")\nWshShell.Run """${exePath.replace(/\\/g, "\\\\")}""", 0, False`;
      writeFileSync(vbsPath, vbsContent);

      // 创建任务计划程序任务，运行 VBS 脚本实现静默启动
      const command = `schtasks /create /tn "${taskName}" /tr "wscript.exe \\"${vbsPath}\\"" /sc onlogon /rl highest /f`;
      execSync(command, { encoding: "buffer", windowsHide: true });

      configStore.set("autoLaunch", true);
      return { success: true, message: "已启用开机自启（静默模式）" };
    } else {
      // 删除任务计划程序任务
      try {
        execSync(`schtasks /delete /tn "${taskName}" /f`, {
          encoding: "buffer",
          windowsHide: true,
        });
      } catch (e) {
        // 忽略删除失败
      }
      
      // 删除 VBS 脚本
      const appDir = require("path").dirname(exePath);
      const vbsPath = join(appDir, "silent_start.vbs");
      if (existsSync(vbsPath)) {
        try {
          unlinkSync(vbsPath);
        } catch (e) {
          // 忽略删除失败
        }
      }
      
      configStore.set("autoLaunch", false);
      return { success: true, message: "已禁用开机自启" };
    }
  } catch (error: any) {
    console.error("任务计划操作失败:", error);
    return {
      success: false,
      message: "操作失败，请确保应用以管理员身份运行",
    };
  }
});

// 获取开机自启状态
ipcMain.handle("app:getAutoLaunch", async () => {
  const { execSync } = require("child_process");
  const taskName = "PHPerDevManager";

  // 开发模式下返回 false
  if (!app.isPackaged) {
    return false;
  }

  try {
    execSync(`schtasks /query /tn "${taskName}"`, {
      encoding: "buffer",
      windowsHide: true,
    });
    return true;
  } catch (e) {
    return false;
  }
});

// 获取应用版本信息
ipcMain.handle("app:getVersion", async () => {
  const { existsSync, readFileSync } = require("fs");
  const { join } = require("path");
  
  const version = app.getVersion();
  let buildTime = "";
  let buildDate = "";
  
  // 尝试读取版本信息文件
  try {
    const versionFilePath = app.isPackaged
      ? join(process.resourcesPath, "public", "version.json")
      : join(__dirname, "..", "public", "version.json");
    
    if (existsSync(versionFilePath)) {
      const versionInfo = JSON.parse(readFileSync(versionFilePath, "utf-8"));
      buildTime = versionInfo.buildTime || "";
      buildDate = versionInfo.buildDate || "";
    }
  } catch (e) {
    // 忽略错误
  }
  
  return {
    version,
    buildTime,
    buildDate,
    isPackaged: app.isPackaged
  };
});

// 设置启动时最小化到托盘
ipcMain.handle("app:setStartMinimized", (_, enabled: boolean) => {
  configStore.set("startMinimized", enabled);
  return { success: true };
});

// 获取启动时最小化状态
ipcMain.handle("app:getStartMinimized", () => {
  return configStore.get("startMinimized") || false;
});

// 真正退出应用
ipcMain.handle("app:quit", () => {
  isQuitting = true;
  app.quit();
});

// ==================== 日志管理 ====================
ipcMain.handle("log:getFiles", () => logManager.getLogFiles());
ipcMain.handle("log:read", (_, logPath: string, lines?: number) =>
  logManager.readLog(logPath, lines)
);
ipcMain.handle("log:clear", (_, logPath: string) => logManager.clearLog(logPath));
ipcMain.handle("log:getDirectory", (_, type: 'nginx' | 'php' | 'mysql' | 'sites', version?: string) =>
  logManager.getLogDirectory(type, version)
);
