const { app, BrowserWindow, ipcMain } = require("electron");
const path = require("path");
const https = require("https");
const http = require("http");
const fs = require("fs");
const os = require("os");
const ptp = require("pdf-to-printer");

let mainWindow = null;
const { Worker } = require("worker_threads");
const log = require("electron-log");

// 配置日志输出
log.transports.file.level = "info";
log.transports.file.resolvePath = () =>
  path.join(path.dirname(app.getPath("exe")), "logs", "main.log");
log.info("App starting...");

// 监听渲染进程日志
ipcMain.on("log-message", (event, { level, message }) => {
  if (log[level]) {
    log[level](`[Renderer] ${message}`);
  } else {
    log.info(`[Renderer] ${message}`);
  }
});

let idCardWorker = null;

function createIdCardWorker() {
  if (idCardWorker) return;

  log.info("Creating IDCard Worker...");
  idCardWorker = new Worker(path.join(__dirname, "idcard-worker.js"));

  idCardWorker.on("message", (msg) => {
    if (!mainWindow) return;

    if (msg.type === "data") {
      log.info("IDCard data received");
      mainWindow.webContents.send("idcard-data", { payload: msg.payload });
    } else if (msg.type === "error") {
      log.error("IDCard worker error message:", msg.payload);
      mainWindow.webContents.send("idcard-error", { payload: msg.payload });
    } else if (msg.type === "log") {
      log.info("[Worker]", msg.payload);
    }
  });

  idCardWorker.on("error", (err) => {
    log.error("Worker thread error:", err);
  });

  idCardWorker.on("exit", (code) => {
    if (code !== 0) log.error(`Worker stopped with exit code ${code}`);
    else log.info("Worker stopped gracefully");
    idCardWorker = null;
  });
}

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 1080,
    height: 1920,
    fullscreen: true, // 全屏
    frame: false, // 无边框
    icon: path.join(__dirname, "../resources/icon.ico"), // 设置窗口图标
    webPreferences: {
      preload: path.join(__dirname, "preload.js"),
      nodeIntegration: false,
      contextIsolation: true,
    },
  });

  // 启用触摸事件支持（Windows 触摸屏）
  mainWindow.webContents.on("did-finish-load", () => {
    // 注入触摸事件支持脚本
    mainWindow.webContents
      .executeJavaScript(
        `
      // 确保触摸事件可用
      if (navigator.maxTouchPoints === 0) {
        console.log('[Electron] 未检测到触摸设备，将使用鼠标事件模拟');
      } else {
        console.log('[Electron] 检测到触摸设备，触摸点数:', navigator.maxTouchPoints);
      }
    `
      )
      .catch((err) => log.error("Failed to inject touch support:", err));
  });

  const isDev = !app.isPackaged;

  if (isDev) {
    mainWindow.loadURL("http://localhost:5173");
    // 打开开发者工具
    mainWindow.webContents.openDevTools();
  } else {
    mainWindow.loadFile(path.join(__dirname, "../dist/index.html"));
  }
}

// 处理PDF获取请求（绕过CORS）
ipcMain.handle("fetch-pdf", async (event, pdfUrl) => {
  return new Promise((resolve, reject) => {
    const protocol = pdfUrl.startsWith("https") ? https : http;

    protocol
      .get(pdfUrl, (response) => {
        // 处理重定向
        if (response.statusCode === 301 || response.statusCode === 302) {
          const redirectUrl = response.headers.location;
          protocol
            .get(redirectUrl, (redirectResponse) => {
              const chunks = [];
              redirectResponse.on("data", (chunk) => chunks.push(chunk));
              redirectResponse.on("end", () => {
                const buffer = Buffer.concat(chunks);
                resolve({
                  success: true,
                  data: buffer.toString("base64"),
                });
              });
              redirectResponse.on("error", (error) => {
                reject({ success: false, error: error.message });
              });
            })
            .on("error", (error) => {
              reject({ success: false, error: error.message });
            });
        } else {
          const chunks = [];
          response.on("data", (chunk) => chunks.push(chunk));
          response.on("end", () => {
            const buffer = Buffer.concat(chunks);
            resolve({
              success: true,
              data: buffer.toString("base64"),
            });
          });
          response.on("error", (error) => {
            reject({ success: false, error: error.message });
          });
        }
      })
      .on("error", (error) => {
        reject({ success: false, error: error.message });
      });
  });
});

ipcMain.handle("get-printers", async (event) => {
  try {
    const webContents = event.sender;
    if (!webContents) {
      return { success: false, error: "No webContents available" };
    }

    if (typeof webContents.getPrintersAsync === "function") {
      const printers = await webContents.getPrintersAsync();
      return { success: true, printers };
    }

    const printers = webContents.getPrinters();
    return { success: true, printers };
  } catch (error) {
    log.error("Failed to get printers:", error);
    return { success: false, error: error.message };
  }
});

// 处理PDF打印请求
ipcMain.handle("print-pdf", async (event, pdfDataOrUrl, printOptions = {}) => {
  let tempFilePath = null;
  const targetPrinterName = printOptions?.printerName;

  try {
    let pdfFilePath = null;

    // 如果是 base64 data URI，转换为临时文件
    if (pdfDataOrUrl.startsWith("data:application/pdf;base64,")) {
      const base64Data = pdfDataOrUrl.replace(
        "data:application/pdf;base64,",
        ""
      );

      // 清理base64字符串中的空白字符
      const cleanBase64 = base64Data.replace(/\s/g, "");

      try {
        const buffer = Buffer.from(cleanBase64, "base64");

        // 验证PDF文件头（%PDF）
        if (buffer.length < 4 || buffer.toString("ascii", 0, 4) !== "%PDF") {
          throw new Error("无效的PDF数据：文件头不正确");
        }

        // 创建临时文件
        tempFilePath = path.join(
          os.tmpdir(),
          `print_${Date.now()}_${Math.random().toString(36).substring(7)}.pdf`
        );
        fs.writeFileSync(tempFilePath, buffer);
        pdfFilePath = tempFilePath;

        const fileSize = fs.statSync(tempFilePath).size;
        log.info(
          `PDF written to temp file: ${tempFilePath}, size: ${fileSize} bytes`
        );

        if (fileSize < 1024) {
          throw new Error(
            `PDF文件大小异常（${fileSize} bytes），可能数据不完整`
          );
        }
      } catch (err) {
        log.error("Base64解码或文件写入失败:", err);
        throw new Error(`PDF数据处理失败: ${err.message}`);
      }
    }
    // 如果是HTTP/HTTPS URL，先下载
    else if (
      pdfDataOrUrl.startsWith("http://") ||
      pdfDataOrUrl.startsWith("https://")
    ) {
      log.info("Downloading PDF from URL:", pdfDataOrUrl);
      const protocol = pdfDataOrUrl.startsWith("https") ? https : http;

      const buffer = await new Promise((resolve, reject) => {
        protocol
          .get(pdfDataOrUrl, (response) => {
            // 处理重定向
            if (response.statusCode === 301 || response.statusCode === 302) {
              const redirectUrl = response.headers.location;
              protocol
                .get(redirectUrl, (redirectResponse) => {
                  const chunks = [];
                  redirectResponse.on("data", (chunk) => chunks.push(chunk));
                  redirectResponse.on("end", () => {
                    resolve(Buffer.concat(chunks));
                  });
                  redirectResponse.on("error", reject);
                })
                .on("error", reject);
            } else {
              const chunks = [];
              response.on("data", (chunk) => chunks.push(chunk));
              response.on("end", () => {
                resolve(Buffer.concat(chunks));
              });
              response.on("error", reject);
            }
          })
          .on("error", reject);
      });

      // 验证PDF文件头
      if (buffer.length < 4 || buffer.toString("ascii", 0, 4) !== "%PDF") {
        throw new Error("下载的文件不是有效的PDF");
      }

      tempFilePath = path.join(
        os.tmpdir(),
        `print_${Date.now()}_${Math.random().toString(36).substring(7)}.pdf`
      );
      fs.writeFileSync(tempFilePath, buffer);
      pdfFilePath = tempFilePath;

      const fileSize = fs.statSync(tempFilePath).size;
      log.info(
        `PDF downloaded to temp file: ${tempFilePath}, size: ${fileSize} bytes`
      );
    }
    // 如果是本地文件路径
    else if (pdfDataOrUrl.startsWith("file://")) {
      pdfFilePath = pdfDataOrUrl.replace("file://", "");
    }
    // 如果是相对路径
    else if (pdfDataOrUrl.startsWith("/assets/")) {
      const isDev = !app.isPackaged;
      if (!isDev) {
        pdfFilePath = path.join(__dirname, "..", "dist", pdfDataOrUrl);
      } else {
        throw new Error("开发环境不支持相对路径PDF打印，请使用完整URL或base64");
      }
    }
    // 直接作为文件路径
    else {
      pdfFilePath = pdfDataOrUrl;
    }

    // 验证文件存在
    if (!pdfFilePath || !fs.existsSync(pdfFilePath)) {
      throw new Error(`PDF文件不存在: ${pdfFilePath}`);
    }

    // 验证文件大小
    const stats = fs.statSync(pdfFilePath);
    if (stats.size < 1024) {
      throw new Error(`PDF文件大小异常（${stats.size} bytes），可能文件损坏`);
    }

    const duplexMode = printOptions?.duplex;
    // pdf-to-printer 使用 side 选项，而不是 duplex
    // side 可选值: "simplex" | "duplex" | "duplexshort" | "duplexlong"
    const sideOption = duplexMode ? "duplex" : "simplex";
    log.info(
      `准备打印PDF: ${pdfFilePath}, 打印机: ${targetPrinterName || "默认打印机"
      }, 双面打印: ${duplexMode ? "是" : "否"}`
    );

    // 使用 pdf-to-printer 打印
    const printOptions_ptp = {
      printer: targetPrinterName || undefined,
      silent: true, // 静默打印
      side: sideOption, // 双面打印选项
    };

    await ptp.print(pdfFilePath, printOptions_ptp);

    log.info("PDF打印请求已发送成功");

    // 清理临时文件
    if (tempFilePath && fs.existsSync(tempFilePath)) {
      try {
        // 延迟删除，确保打印任务已提交
        setTimeout(() => {
          fs.unlinkSync(tempFilePath);
          log.info("Temp file deleted");
        }, 5000);
      } catch (err) {
        log.error("Failed to delete temp file:", err);
      }
    }

    return { success: true };
  } catch (error) {
    log.error("Print error:", error);

    // 清理临时文件
    if (tempFilePath && fs.existsSync(tempFilePath)) {
      try {
        fs.unlinkSync(tempFilePath);
      } catch (err) {
        log.error("Failed to delete temp file:", err);
      }
    }

    return { success: false, error: error.message || String(error) };
  }
});

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

  // IPC ����
  ipcMain.handle("start_idcard_listen", () => {
    if (idCardWorker) {
      idCardWorker.postMessage("start");
    } else {
      createIdCardWorker();
      idCardWorker.postMessage("start");
    }
    return "started";
  });

  ipcMain.handle("stop_idcard_listen", () => {
    if (idCardWorker) {
      idCardWorker.postMessage("stop");
    }
    return "stopped";
  });

  ipcMain.on("restart-app", () => {
    app.relaunch();
    app.exit(0);
  });
  ipcMain.on("quit-app", () => {
    try {
      app.quit();
    } catch (err) {
      // 最后手段：强制退出
      app.exit(0);
    }
  });

  // 读取本地文件并以 base64 返回（用于渲染进程获取 id card 照片）
  ipcMain.handle("read-local-file", async (event, filePath) => {
    try {
      if (!filePath || typeof filePath !== "string") {
        return { success: false, error: "invalid filePath" };
      }
      if (!fs.existsSync(filePath)) {
        return { success: false, error: `file not exists: ${filePath}` };
      }
      const buffer = fs.readFileSync(filePath);
      const base64 = buffer.toString("base64");
      const mime = "image/bmp";

      return { success: true, data: base64, mime };
    } catch (err) {
      log.error("read-local-file error:", err);
      return { success: false, error: err.message || String(err) };
    }
  });

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

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