import { BrowserWindow, ipcMain, screen } from "electron";
import { join } from "path";
import { ConfigService } from "../services/config";

// Linux D-Bus通知服务
const isLinux = process.platform === "linux";
let linuxNotificationService:
  | typeof import("../services/linuxNotificationService")
  | null = null;

// 用于处理通知点击的回调函数（在Linux上用于导航到会话）
let onNotificationNavigate: ((payload: unknown) => void) | null = null;

export function setNotificationNavigateHandler(
  callback: (payload: unknown) => void,
) {
  onNotificationNavigate = callback;
}

let notificationWindow: BrowserWindow | null = null;
let closeTimer: NodeJS.Timeout | null = null;

export function destroyNotificationWindow() {
  if (closeTimer) {
    clearTimeout(closeTimer);
    closeTimer = null;
  }
  lastNotificationData = null;

  // Linux:关闭通知服务并清理缓存（fire-and-forget，不阻塞退出）
  if (isLinux && linuxNotificationService) {
    linuxNotificationService.shutdownLinuxNotificationService().catch((error) => {
      console.warn("[NotificationWindow] Failed to shutdown Linux notification service:", error);
    });
    linuxNotificationService = null;
  }

  if (!notificationWindow || notificationWindow.isDestroyed()) {
    notificationWindow = null;
    return;
  }

  const win = notificationWindow;
  notificationWindow = null;

  try {
    win.destroy();
  } catch (error) {
    console.warn("[NotificationWindow] Failed to destroy window:", error);
  }
}

export function createNotificationWindow() {
  if (notificationWindow && !notificationWindow.isDestroyed()) {
    return notificationWindow;
  }

  const isDev = !!process.env.VITE_DEV_SERVER_URL;
  const iconPath = isDev
    ? join(__dirname, "../../public/icon.ico")
    : join(process.resourcesPath, "icon.ico");

  console.log("[NotificationWindow] Creating window...");
  const width = 344;
  const height = 114;

  // Update default creation size
  notificationWindow = new BrowserWindow({
    width: width,
    height: height,
    type: "toolbar", // 有助于在某些操作系统上保持置顶
    frame: false,
    transparent: true,
    resizable: false,
    show: false,
    alwaysOnTop: true,
    skipTaskbar: true,
    focusable: false, // 不抢占焦点
    icon: iconPath,
    webPreferences: {
      preload: join(__dirname, "preload.js"), // FIX: Use correct relative path (same dir in dist)
      contextIsolation: true,
      nodeIntegration: false,
      // devTools: true // Enable DevTools
    },
  });

  // notificationWindow.webContents.openDevTools({ mode: 'detach' }) // DEBUG: Force Open DevTools
  notificationWindow.setIgnoreMouseEvents(true, { forward: true }); // 初始点击穿透

  // 处理鼠标事件 (如果需要从渲染进程转发，但目前特定区域处理?)
  // 实际上，我们希望窗口可点击。
  // 我们将在显示时将忽略鼠标事件设为 false。

  const loadUrl = isDev
    ? `${process.env.VITE_DEV_SERVER_URL}#/notification-window`
    : `file://${join(__dirname, "../dist/index.html")}#/notification-window`;

  console.log("[NotificationWindow] Loading URL:", loadUrl);
  notificationWindow.loadURL(loadUrl);

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

  return notificationWindow;
}

export async function showNotification(data: any) {
  // 先检查配置
  const config = ConfigService.getInstance();
  const sessionId = typeof data.sessionId === "string" ? data.sessionId : "";
  const channel = typeof data.channel === "string" ? data.channel : "";
  const isAiInsightNotification = channel === "ai-insight";

  if (isAiInsightNotification) {
    const enabled = await config.get("aiInsightNotificationEnabled");
    if (enabled === false) return; // 默认为 true
  } else {
    const enabled = await config.get("notificationEnabled");
    if (enabled === false) return; // 默认为 true

    // 检查会话过滤
    const filterMode = config.get("notificationFilterMode") || "all";
    const filterList = config.get("notificationFilterList") || [];
    // 系统通知（如 "WeFlow 准备就绪"）不是聊天消息，不应受会话白/黑名单影响
    const isSystemNotification = sessionId.startsWith("weflow-");

    if (!isSystemNotification && filterMode !== "all") {
      const isInList = sessionId !== "" && filterList.includes(sessionId);
      if (filterMode === "whitelist" && !isInList) {
        // 白名单模式：不在列表中则不显示（空列表视为全部拦截）
        return;
      }
      if (filterMode === "blacklist" && isInList) {
        // 黑名单模式：在列表中则不显示
        return;
      }
    }
  }

  // Linux 使用 D-Bus 通知
  if (isLinux) {
    await showLinuxNotification(data);
    return;
  }

  let win = notificationWindow;
  if (!win || win.isDestroyed()) {
    win = createNotificationWindow();
  }

  if (!win) return;

  // 确保加载完成
  if (win.webContents.isLoading()) {
    win.once("ready-to-show", () => {
      showAndSend(win!, data);
    });
  } else {
    showAndSend(win, data);
  }
}

// 显示Linux通知
async function showLinuxNotification(data: any) {
  if (!linuxNotificationService) {
    try {
      linuxNotificationService =
        await import("../services/linuxNotificationService");
    } catch (error) {
      console.error(
        "[NotificationWindow] Failed to load Linux notification service:",
        error,
      );
      return;
    }
  }

  const { showLinuxNotification: showNotification } = linuxNotificationService;

  const notificationData = {
    title: data.title,
    content: data.content,
    avatarUrl: data.avatarUrl,
    sessionId: data.sessionId,
    channel: data.channel,
    insightRecordId: data.insightRecordId,
    targetRoute: data.targetRoute,
    expireTimeout: 5000,
  };

  showNotification(notificationData);
}

let lastNotificationData: any = null;

async function showAndSend(win: BrowserWindow, data: any) {
  lastNotificationData = data;
  const config = ConfigService.getInstance();
  const position = (await config.get("notificationPosition")) || "top-right";

  // 更新位置
  const { width: screenWidth, height: screenHeight } =
    screen.getPrimaryDisplay().workAreaSize;
  const winWidth = position === "top-center" ? 280 : 344;
  const winHeight = 114;
  const padding = 20;

  let x = 0;
  let y = 0;

  switch (position) {
    case "top-center":
      x = (screenWidth - winWidth) / 2;
      y = padding;
      break;
    case "top-right":
      x = screenWidth - winWidth - padding;
      y = padding;
      break;
    case "bottom-right":
      x = screenWidth - winWidth - padding;
      y = screenHeight - winHeight - padding;
      break;
    case "top-left":
      x = padding;
      y = padding;
      break;
    case "bottom-left":
      x = padding;
      y = screenHeight - winHeight - padding;
      break;
  }

  win.setPosition(Math.floor(x), Math.floor(y));
  win.setSize(winWidth, winHeight); // 确保尺寸

  // 设为可交互
  win.setIgnoreMouseEvents(false);
  win.showInactive(); // 显示但不聚焦
  win.setAlwaysOnTop(true, "screen-saver"); // 最高层级

  win.webContents.send("notification:show", { ...data, position });

  // 自动关闭计时器通常由渲染进程管理
  // 渲染进程发送 'notification:close' 来隐藏窗口
}

// 注册通知处理
export async function registerNotificationHandlers() {
  // Linux: 初始化D-Bus服务
  if (isLinux) {
    try {
      const linuxNotificationModule =
        await import("../services/linuxNotificationService");
      linuxNotificationService = linuxNotificationModule;

      // 初始化服务
      await linuxNotificationModule.initLinuxNotificationService();

      // 在Linux上注册通知点击回调
      linuxNotificationModule.onNotificationAction((payload: unknown) => {
        console.log(
          "[NotificationWindow] Linux notification clicked, sessionId:",
          payload,
        );
        // 如果设置了导航处理程序，则使用该处理程序；否则，回退到ipcMain方法。
        if (onNotificationNavigate) {
          onNotificationNavigate(payload);
        } else {
          // 如果尚未设置处理程序，则通过ipcMain发出事件
          // 正常流程中不应该发生这种情况，因为我们在初始化之前设置了处理程序。
          console.warn(
            "[NotificationWindow] onNotificationNavigate not set yet",
          );
        }
      });

      console.log(
        "[NotificationWindow] Linux notification service initialized",
      );
    } catch (error) {
      console.error(
        "[NotificationWindow] Failed to initialize Linux notification service:",
        error,
      );
    }
  }

  ipcMain.handle("notification:show", (_, data) => {
    showNotification(data);
  });

  ipcMain.handle("notification:close", () => {
    if (isLinux && linuxNotificationService) {
      // 注册通知点击回调函数。Linux通知通过D-Bus自动关闭，但我们可以根据需要进行跟踪
      return;
    }
    if (notificationWindow && !notificationWindow.isDestroyed()) {
      notificationWindow.hide();
      notificationWindow.setIgnoreMouseEvents(true, { forward: true });
    }
  });

  // Handle renderer ready event (fix race condition)
  ipcMain.on("notification:ready", (event) => {
    if (isLinux) {
      // Linux不需要通知窗口，拦截通知窗口渲染
      return;
    }
    console.log("[NotificationWindow] Renderer ready, checking cached data");
    if (
      lastNotificationData &&
      notificationWindow &&
      !notificationWindow.isDestroyed()
    ) {
      console.log("[NotificationWindow] Re-sending cached data");
      notificationWindow.webContents.send(
        "notification:show",
        lastNotificationData,
      );
    }
  });

  // Handle resize request from renderer
  ipcMain.on("notification:resize", (event, { width, height }) => {
    if (isLinux) {
      // Linux 通知通过D-Bus自动调整大小
      return;
    }
    if (notificationWindow && !notificationWindow.isDestroyed()) {
      // Enforce max-height if needed, or trust renderer
      // Ensure it doesn't go off screen bottom?
      // Logic in showAndSend handles position, but we need to keep anchor point (top-right usually).
      // If we resize, we should re-calculate position to keep it anchored?
      // Actually, setSize changes size. If it's top-right, x/y stays same -> window grows down. That's fine for top-right.
      // If bottom-right, growing down pushes it off screen.

      // Simple version: just setSize. For V1 we assume Top-Right.
      // But wait, the config supports bottom-right.
      // We can re-call setPosition or just let it be.
      // If bottom-right, y needs to prevent overflow.

      // Ideally we get current config position
      const bounds = notificationWindow.getBounds();
      // Check if we need to adjust Y?
      // For now, let's just set the size as requested.
      notificationWindow.setSize(Math.round(width), Math.round(height));
    }
  });

  // 'notification-clicked' 在 main.ts 中处理 (导航)
}
