// System tray + Windows taskbar overlay badge. Renderer pushes the
// current aggregate unread count via CHANNELS.TRAY_UNREAD; we update the
// tooltip and (on Windows) set an overlay icon on the main window's
// taskbar button.
//
// Overlay image is a pre-rendered 16x16 red dot embedded as base64 so
// the module is self-contained — no runtime canvas dependency.

import {
  app,
  BrowserWindow,
  ipcMain,
  Menu,
  nativeImage,
  type NativeImage,
  Tray,
} from 'electron';
import path from 'node:path';

import { CHANNELS } from '../ipc-types';

let trayRef: Tray | null = null;
let overlayImage: NativeImage | null = null;

function resolveIconPath(): string {
  return path.join(process.resourcesPath || app.getAppPath(), 'icon.ico');
}

function resolveIconPathDev(): string {
  return path.join(app.getAppPath(), 'resources', 'icon.ico');
}

function loadTrayIcon(): NativeImage {
  for (const p of [resolveIconPath(), resolveIconPathDev()]) {
    try {
      const img = nativeImage.createFromPath(p);
      if (!img.isEmpty()) return img;
    } catch {
      /* try next */
    }
  }
  return nativeImage.createEmpty();
}

function buildOverlay(): NativeImage {
  if (overlayImage) return overlayImage;
  // 16x16 PNG, solid red circle. Inline base64 so no external file lookup.
  const base64 =
    'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAPElEQVR42mNkYGD4z0AGYBxVSF2F//' +
    '//Z2BgYGD4/58kBYz4FDAxMDAwMDIwMDD8//+foArGUYWjCoc1AABTgwUBf3lZtAAAAABJRU5ErkJggg==';
  overlayImage = nativeImage.createFromBuffer(Buffer.from(base64, 'base64'));
  return overlayImage;
}

export function register(mainWindow: BrowserWindow): void {
  const icon = loadTrayIcon();
  trayRef = new Tray(icon.isEmpty() ? nativeImage.createEmpty() : icon);
  trayRef.setToolTip('Netralax');

  const menu = Menu.buildFromTemplate([
    {
      label: 'Open',
      click: (): void => {
        if (mainWindow.isDestroyed()) return;
        if (mainWindow.isMinimized()) mainWindow.restore();
        mainWindow.show();
        mainWindow.focus();
      },
    },
    { type: 'separator' },
    {
      label: 'Quit',
      click: (): void => {
        app.quit();
      },
    },
  ]);
  trayRef.setContextMenu(menu);
  trayRef.on('click', (): void => {
    if (mainWindow.isDestroyed()) return;
    if (mainWindow.isMinimized()) mainWindow.restore();
    if (mainWindow.isVisible()) mainWindow.focus();
    else mainWindow.show();
  });

  ipcMain.handle(
    CHANNELS.TRAY_UNREAD,
    async (_evt, count: number, badgeDataUrl?: string | null): Promise<void> => {
      const n = Math.max(0, Math.floor(Number(count) || 0));
      if (trayRef && !trayRef.isDestroyed()) {
        trayRef.setToolTip(n > 0 ? `Netralax — ${n} ungelesen` : 'Netralax');
      }
      if (mainWindow.isDestroyed()) return;
      if (process.platform !== 'win32') return;
      if (n <= 0) {
        mainWindow.setOverlayIcon(null, '');
        return;
      }
      // Discord-style: prefer the renderer-painted badge (red circle with
      // the actual unread number). Fall back to the static red dot only if
      // the renderer didn't supply one or decoding failed — keeps the
      // visual indicator alive even when the canvas pipeline is unavailable.
      let overlay: NativeImage | null = null;
      if (typeof badgeDataUrl === 'string' && badgeDataUrl.startsWith('data:image/')) {
        const decoded = nativeImage.createFromDataURL(badgeDataUrl);
        if (!decoded.isEmpty()) overlay = decoded;
      }
      mainWindow.setOverlayIcon(overlay ?? buildOverlay(), `${n} ungelesen`);
    },
  );

  app.on('before-quit', () => {
    try {
      trayRef?.destroy();
    } catch {
      /* already gone */
    }
    trayRef = null;
  });
}
