const path = require('path');
const { app, BrowserWindow, ipcMain, shell, dialog } = require('electron');
const { autoUpdater } = require('electron-updater');

const { startLocalServer, stopLocalServer } = require('./server.cjs');
const ollama = require('./ollama.cjs');

let mainWindow = null;
let serverHandle = null;
let pendingAuthCallbackUrl = null;
const DOWNLOADS_URL = 'https://downloads.orgboard.iacovici.it/releases/';
let updateStatus = {
  checking: false,
  available: false,
  downloaded: false,
  version: app.getVersion(),
  message: ''
};

function sendUpdateStatus() {
  if (!mainWindow || mainWindow.isDestroyed()) return;
  mainWindow.webContents.send('desktop:update-status', updateStatus);
}

function handleAuthCallback(url) {
  if (!url) return;
  pendingAuthCallbackUrl = url;
  if (mainWindow && !mainWindow.isDestroyed()) {
    mainWindow.webContents.send('desktop:auth-callback', url);
    if (mainWindow.isMinimized()) mainWindow.restore();
    mainWindow.focus();
  }
}

function configureAutoUpdates() {
  if (!app.isPackaged) return;

  autoUpdater.autoDownload = true;
  autoUpdater.autoInstallOnAppQuit = process.platform !== 'darwin';

  autoUpdater.on('checking-for-update', () => {
    updateStatus = { ...updateStatus, checking: true, message: 'Checking for updates...' };
    sendUpdateStatus();
  });

  autoUpdater.on('update-available', async (info) => {
    updateStatus = { ...updateStatus, checking: false, available: true, downloaded: false, version: info.version, message: `Downloading ${info.version}...` };
    sendUpdateStatus();
    if (mainWindow && !mainWindow.isDestroyed()) {
      await dialog.showMessageBox(mainWindow, {
        type: 'info',
        title: 'Update available',
        message: `Org Board AI ${info.version} is available.`,
        detail: 'The update is downloading in the background. You will be prompted to restart when it is ready.',
        buttons: ['OK']
      });
    }
  });

  autoUpdater.on('update-not-available', () => {
    updateStatus = { ...updateStatus, checking: false, available: false, downloaded: false, message: 'You are on the latest version.' };
    sendUpdateStatus();
  });

  autoUpdater.on('error', (error) => {
    updateStatus = { ...updateStatus, checking: false, message: error.message || 'Update check failed.' };
    sendUpdateStatus();
  });

  autoUpdater.on('update-downloaded', async (info) => {
    const requiresManualInstall = process.platform === 'darwin';
    updateStatus = {
      ...updateStatus,
      checking: false,
      available: true,
      downloaded: true,
      version: info.version,
      message: requiresManualInstall
        ? `Version ${info.version} is ready. This beta build requires a manual install on macOS.`
        : `Version ${info.version} is ready to install.`
    };
    sendUpdateStatus();
    if (mainWindow && !mainWindow.isDestroyed()) {
      if (requiresManualInstall) {
        const result = await dialog.showMessageBox(mainWindow, {
          type: 'info',
          title: 'Update ready',
          message: `Org Board AI ${info.version} is ready.`,
          detail: 'This beta build uses manual install on macOS. Open the downloads page, install the new DMG, then replace the app in Applications.',
          buttons: ['Open Downloads', 'Later'],
          defaultId: 0,
          cancelId: 1
        });
        if (result.response === 0) {
          await shell.openExternal(DOWNLOADS_URL);
        }
      } else {
        const result = await dialog.showMessageBox(mainWindow, {
          type: 'question',
          title: 'Install update',
          message: `Org Board AI ${info.version} is ready.`,
          detail: 'Restart now to install the update.',
          buttons: ['Restart Now', 'Later'],
          defaultId: 0,
          cancelId: 1
        });
        if (result.response === 0) {
          autoUpdater.quitAndInstall();
        }
      }
    }
  });
}

async function checkForUpdates(manual = false) {
  if (!app.isPackaged) {
    updateStatus = { ...updateStatus, checking: false, message: 'Auto-updates are available in packaged builds only.' };
    sendUpdateStatus();
    return updateStatus;
  }
  try {
    await autoUpdater.checkForUpdates();
    if (manual) {
      sendUpdateStatus();
    }
  } catch (error) {
    updateStatus = { ...updateStatus, checking: false, message: error.message || 'Update check failed.' };
    sendUpdateStatus();
  }
  return updateStatus;
}

async function createMainWindow() {
  const dataDir = path.join(app.getPath('userData'), 'workspace');
  if (!serverHandle) {
    serverHandle = await startLocalServer({
      appRoot: path.join(__dirname, '..'),
      dataDir
    });
  }

  mainWindow = new BrowserWindow({
    width: 1540,
    height: 980,
    minWidth: 1180,
    minHeight: 820,
    backgroundColor: '#0a0a0f',
    title: 'Org Board AI',
    icon: path.join(__dirname, '..', 'build', 'icon.png'),
    autoHideMenuBar: true,
    webPreferences: {
      preload: path.join(__dirname, 'preload.cjs'),
      contextIsolation: true,
      nodeIntegration: false,
      sandbox: false
    }
  });

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

  await mainWindow.loadURL(serverHandle.url);
}

const gotSingleInstanceLock = app.requestSingleInstanceLock();
if (!gotSingleInstanceLock) {
  app.quit();
}

app.on('open-url', (event, url) => {
  event.preventDefault();
  handleAuthCallback(url);
});

app.whenReady().then(async () => {
  app.setAsDefaultProtocolClient('orgboardai');

  app.on('second-instance', () => {
    if (!mainWindow) return;
    if (mainWindow.isMinimized()) mainWindow.restore();
    mainWindow.focus();
  });

  ipcMain.handle('desktop:getSystemStatus', () => ollama.getSystemStatus());
  ipcMain.handle('desktop:getAppVersion', () => app.getVersion());
  ipcMain.handle('desktop:getUpdateStatus', () => updateStatus);
  ipcMain.handle('desktop:checkForUpdates', () => checkForUpdates(true));
  ipcMain.handle('desktop:openExternal', (_event, url) => shell.openExternal(url));
  ipcMain.handle('desktop:getPendingAuthCallback', () => {
    const current = pendingAuthCallbackUrl;
    pendingAuthCallbackUrl = null;
    return current;
  });
  ipcMain.handle('desktop:openOllamaInstaller', async () => {
    await shell.openExternal('https://ollama.com/download');
    return { ok: true };
  });
  ipcMain.handle('desktop:startOllama', () => ollama.startOllama());
  ipcMain.handle('desktop:pullOllamaModel', (_event, model) => ollama.pullModel(model));

  configureAutoUpdates();

  await createMainWindow();
  if (process.defaultApp && process.argv.length >= 2) {
    const deepLinkArg = process.argv.find((arg) => typeof arg === 'string' && arg.startsWith('orgboardai://'));
    if (deepLinkArg) handleAuthCallback(deepLinkArg);
  }
  setTimeout(() => {
    checkForUpdates(false);
  }, 6000);
  setInterval(() => {
    checkForUpdates(false);
  }, 1000 * 60 * 60 * 6);

  app.on('activate', async () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      await createMainWindow();
    }
  });
});

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

app.on('before-quit', () => {
  stopLocalServer(serverHandle);
  serverHandle = null;
});
