// Persists BrowserWindow bounds + maximized state to userData/<filename>.
// Saves are debounced 500ms on move/resize, and fired synchronously on close.
// Validates loaded bounds against the current display layout to avoid
// restoring a window onto a display that no longer exists.

import { app, BrowserWindow, screen } from 'electron';
import { promises as fs } from 'node:fs';
import path from 'node:path';

interface State {
  x?: number;
  y?: number;
  width: number;
  height: number;
  maximized?: boolean;
}

const DEFAULT: State = { width: 1200, height: 800 };

function isOnAnyDisplay(bounds: { x: number; y: number; width: number; height: number }): boolean {
  for (const d of screen.getAllDisplays()) {
    const wa = d.workArea;
    if (
      bounds.x >= wa.x &&
      bounds.y >= wa.y &&
      bounds.x + bounds.width <= wa.x + wa.width + 8 &&
      bounds.y + bounds.height <= wa.y + wa.height + 8
    ) {
      return true;
    }
  }
  return false;
}

export async function loadState(filename: string): Promise<State> {
  const filePath = path.join(app.getPath('userData'), filename);
  try {
    const raw = await fs.readFile(filePath, 'utf8');
    const parsed = JSON.parse(raw) as Partial<State>;
    const width = typeof parsed.width === 'number' ? parsed.width : DEFAULT.width;
    const height = typeof parsed.height === 'number' ? parsed.height : DEFAULT.height;
    const state: State = { width, height };
    if (typeof parsed.x === 'number' && typeof parsed.y === 'number') {
      if (isOnAnyDisplay({ x: parsed.x, y: parsed.y, width, height })) {
        state.x = parsed.x;
        state.y = parsed.y;
      }
    }
    if (parsed.maximized) state.maximized = true;
    return state;
  } catch {
    return { ...DEFAULT };
  }
}

export function attach(win: BrowserWindow, filename: string): void {
  const filePath = path.join(app.getPath('userData'), filename);
  let saveTimer: NodeJS.Timeout | null = null;

  const writeNow = (): void => {
    if (win.isDestroyed()) return;
    const bounds = win.getNormalBounds();
    const state: State = {
      x: bounds.x,
      y: bounds.y,
      width: bounds.width,
      height: bounds.height,
      maximized: win.isMaximized(),
    };
    // Fire-and-forget; exceptions are logged but non-fatal.
    void fs
      .writeFile(filePath, JSON.stringify(state), 'utf8')
      .catch((err: unknown) => {
        console.warn('[window-state] write failed', err);
      });
  };

  const schedule = (): void => {
    if (saveTimer) clearTimeout(saveTimer);
    saveTimer = setTimeout(writeNow, 500);
  };

  win.on('move', schedule);
  win.on('resize', schedule);
  win.on('maximize', schedule);
  win.on('unmaximize', schedule);
  win.on('close', () => {
    if (saveTimer) clearTimeout(saveTimer);
    writeNow();
  });
}
