/**
 * Electron Main Process — Bradly Desktop App
 *
 * Responsibilities:
 * - Creates the BrowserWindow
 * - Starts the embedded Express server
 * - Pre-downloads Chrome Headless Shell for Remotion
 * - Manages IPC handlers for native features
 */
import { app, BrowserWindow, ipcMain, dialog } from 'electron';
import path from 'path';
import fs from 'fs';

// Signal to server.ts / renderQueue.ts that we're in Electron
process.env.BRADLY_ELECTRON = 'true';

const EXPRESS_PORT = 3000;
let mainWindow: BrowserWindow | null = null;

// ═══ Path Setup for Electron ═══

function setupPaths() {
  const userDataPath = app.getPath('userData');

  // Uploads and renders persist in the user's app data directory
  const uploadsDir = path.join(userDataPath, 'uploads');
  const rendersDir = path.join(userDataPath, 'renders');

  // Create directories if they don't exist
  for (const dir of [uploadsDir, rendersDir]) {
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }
  }

  process.env.BRADLY_UPLOADS_DIR = uploadsDir;
  process.env.BRADLY_RENDERS_DIR = rendersDir;

  // In packaged app, configure Remotion paths
  if (app.isPackaged) {
    const resourcesPath = process.resourcesPath;

    // Pre-built Remotion bundle (created during packaging)
    const remotionBundle = path.join(resourcesPath, 'remotion-bundle');
    if (fs.existsSync(remotionBundle)) {
      process.env.BRADLY_REMOTION_BUNDLE = remotionBundle;
    }

    // Compositor binaries (unpacked from asar)
    const platform = process.platform === 'darwin' ? 'darwin' : 'linux';
    const arch = process.arch;
    const compositorPath = path.join(
      resourcesPath,
      'app.asar.unpacked',
      'node_modules',
      `@remotion/compositor-${platform}-${arch}`,
    );
    if (fs.existsSync(compositorPath)) {
      process.env.BRADLY_BINARIES_DIR = compositorPath;
    }
  }

  console.log('📂 User data:', userDataPath);
  console.log('📂 Uploads:', uploadsDir);
  console.log('📂 Renders:', rendersDir);
}

// ═══ Express Server ═══

async function startExpressServer(): Promise<void> {
  const { createExpressApp } = await import('../../server');
  const expressApp = await createExpressApp();

  // In production Electron, serve the built renderer files
  if (!process.env.NODE_ENV || process.env.NODE_ENV !== 'development') {
    const { default: express } = await import('express');
    // electron-vite builds renderer to out/renderer/
    const rendererPath = app.isPackaged
      ? path.join(process.resourcesPath, 'renderer')
      : path.join(__dirname, '..', '..', 'out', 'renderer');

    if (fs.existsSync(rendererPath)) {
      expressApp.use(express.static(rendererPath));
      // SPA fallback — serve index.html for all non-API routes
      expressApp.get('*', (_req: any, res: any) => {
        res.sendFile(path.join(rendererPath, 'index.html'));
      });
      console.log('📦 Serving renderer from:', rendererPath);
    } else {
      console.warn('⚠️ Renderer build not found at:', rendererPath);
    }
  }

  return new Promise<void>((resolve, reject) => {
    const server = expressApp.listen(EXPRESS_PORT, '127.0.0.1', () => {
      console.log(`🚀 Express server on http://127.0.0.1:${EXPRESS_PORT}`);
      resolve();
    });
    server.on('error', reject);
  });
}

// ═══ Window Management ═══

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 1440,
    height: 900,
    minWidth: 1024,
    minHeight: 600,
    titleBarStyle: 'hiddenInset',
    trafficLightPosition: { x: 15, y: 15 },
    backgroundColor: '#0a0a0a',
    show: false, // Show when ready to prevent visual flash
    webPreferences: {
      preload: path.join(__dirname, '../preload/index.js'),
      contextIsolation: true,
      nodeIntegration: false,
      sandbox: false, // Required for preload to access Node APIs
    },
  });

  // Show window when content is ready
  mainWindow.once('ready-to-show', () => {
    mainWindow?.show();
  });

  // Load the app
  if (process.env.NODE_ENV === 'development') {
    // In dev, electron-vite serves the renderer on a dev server URL
    const rendererUrl = process.env.ELECTRON_RENDERER_URL || 'http://localhost:5173';
    mainWindow.loadURL(rendererUrl);
    // Open DevTools in dev mode
    mainWindow.webContents.openDevTools({ mode: 'detach' });
  } else {
    // In production, load from the embedded Express server
    // which serves the built renderer assets
    mainWindow.loadURL(`http://127.0.0.1:${EXPRESS_PORT}`);
  }

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

// ═══ IPC Handlers ═══

function setupIPC() {
  // Native save dialog
  ipcMain.handle('dialog:save', async (_event, options) => {
    if (!mainWindow) return null;
    const result = await dialog.showSaveDialog(mainWindow, options);
    return result;
  });

  // Native open dialog
  ipcMain.handle('dialog:open', async (_event, options) => {
    if (!mainWindow) return null;
    const result = await dialog.showOpenDialog(mainWindow, options);
    return result;
  });

  // App info
  ipcMain.handle('app:info', () => ({
    version: app.getVersion(),
    name: app.getName(),
    userData: app.getPath('userData'),
    isPackaged: app.isPackaged,
  }));
}

// ═══ Remotion Browser Pre-download ═══

async function predownloadBrowser() {
  try {
    const { ensureBrowser } = await import('@remotion/renderer');
    console.log('🌐 Ensuring Chrome Headless Shell is available...');
    await ensureBrowser();
    console.log('✅ Chrome Headless Shell ready');
  } catch (err) {
    console.warn('⚠️ Failed to pre-download browser (renders may download on first use):', err);
  }
}

// ═══ App Lifecycle ═══

app.whenReady().then(async () => {
  // 1. Configure paths
  setupPaths();

  // 2. Setup IPC handlers
  setupIPC();

  // 3. Start Express server
  try {
    await startExpressServer();
  } catch (err) {
    console.error('❌ Failed to start Express server:', err);
    app.quit();
    return;
  }

  // 4. Create the main window
  createWindow();

  // 5. Pre-download Chrome Headless Shell in background
  predownloadBrowser();

  // macOS: re-create window when dock icon is clicked
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow();
    }
  });
});

// Quit when all windows are closed
app.on('window-all-closed', () => {
  app.quit();
});
