const { app, BrowserWindow, session, shell, desktopCapturer, autoUpdater, dialog, ipcMain, Notification } = require('electron');
const path = require('path');
const fs = require('fs');
const os = require('os');
const { setupAdBlocker } = require('./ad-blocker');

// Handle Squirrel events (Windows installer)
try {
  if (require('electron-squirrel-startup')) app.quit();
} catch {
  // electron-squirrel-startup not installed, skip
}

const HUB_URL = process.env.GAMING_HUB_URL || 'https://hub.daddelolymp.de';
// Auto-Updates laufen über HUB_URL — /downloads ist per Pangolin-Rule ohne Auth erreichbar
const APP_VERSION = app.getVersion();

// Sync IPC: preload reads app version from package.json
ipcMain.on('get-app-version', (event) => {
  event.returnValue = APP_VERSION;
});

function setupAutoUpdater() {
  if (process.platform !== 'win32') return;

  // Squirrel.Windows appends /RELEASES to the feed URL.
  // /downloads ist per Pangolin-Rule ohne Auth erreichbar (Squirrel hat keine Browser-Session).
  const updateURL = `${HUB_URL}/downloads`;
  try {
    autoUpdater.setFeedURL({ url: updateURL });
  } catch (e) {
    console.error('[AutoUpdater] setFeedURL failed:', e.message);
    return;
  }

  autoUpdater.on('update-available', () => {
    console.log('[AutoUpdater] Update available, downloading...');
    if (mainWindow) mainWindow.webContents.send('update-available');
  });

  autoUpdater.on('update-downloaded', (_event, releaseNotes, releaseName) => {
    console.log('[AutoUpdater] Update downloaded:', releaseName || 'new version');
    if (mainWindow) mainWindow.webContents.send('update-ready');
  });

  // Handle install-update request from renderer
  ipcMain.on('install-update', () => {
    autoUpdater.quitAndInstall();
  });

  autoUpdater.on('update-not-available', () => {
    console.log('[AutoUpdater] App is up to date.');
    if (mainWindow) mainWindow.webContents.send('update-not-available');
  });

  // Manual check from renderer
  ipcMain.on('check-for-updates', () => {
    try { autoUpdater.checkForUpdates(); } catch (e) { console.error('[AutoUpdater]', e.message); }
  });

  autoUpdater.on('error', (err) => {
    console.error('[AutoUpdater] Error:', err.message);
    if (mainWindow) mainWindow.webContents.send('update-error', err.message);
  });

  // Check for updates after 5 seconds, then every 30 minutes
  setTimeout(() => {
    try { autoUpdater.checkForUpdates(); } catch (e) { console.error('[AutoUpdater]', e.message); }
  }, 5000);

  setInterval(() => {
    try { autoUpdater.checkForUpdates(); } catch (e) { console.error('[AutoUpdater]', e.message); }
  }, 30 * 60 * 1000);
}

let mainWindow;

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 1400,
    height: 900,
    minWidth: 900,
    minHeight: 600,
    title: 'Gaming Hub',
    icon: path.join(__dirname, 'assets', 'icon.png'),
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true,
      nodeIntegration: false,
    },
    backgroundColor: '#1a1b1e',
    autoHideMenuBar: true,
  });

  // Setup ad blocker BEFORE loading URL
  setupAdBlocker(session.defaultSession);

  // Enable screen capture (getDisplayMedia) in Electron — always show picker
  // IPC channel for picker result
  const PICKER_CHANNEL = 'screen-picker-result';

  session.defaultSession.setDisplayMediaRequestHandler(async (_request, callback) => {
    const sources = await desktopCapturer.getSources({ types: ['screen', 'window'], thumbnailSize: { width: 320, height: 180 } });
    if (sources.length === 0) {
      callback({});
      return;
    }

    const sourceData = sources.map(s => ({
      id: s.id,
      name: s.name,
      thumbnail: s.thumbnail.toDataURL(),
    }));

    // Write picker HTML to a temp file (data: URLs are blocked in Electron)
    const pickerHtml = `<!DOCTYPE html>
<html><head><meta charset="utf-8"><style>
*{margin:0;padding:0;box-sizing:border-box}
body{background:#1a1b1e;color:#e0e0e0;font-family:system-ui,sans-serif;padding:16px;overflow-y:auto}
h2{font-size:16px;margin-bottom:12px;color:#ccc}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px}
.item{background:#2a2a3e;border:2px solid transparent;border-radius:10px;cursor:pointer;overflow:hidden;transition:border-color .15s,transform .15s}
.item:hover{border-color:#7c5cff;transform:scale(1.03)}
.item img{width:100%;height:120px;object-fit:cover;display:block;background:#111}
.item .label{padding:8px 10px;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cancel-row{text-align:center;margin-top:14px}
.cancel-btn{background:#3a3a4e;color:#e0e0e0;border:none;padding:8px 24px;border-radius:6px;cursor:pointer;font-size:14px}
.cancel-btn:hover{background:#4a4a5e}
</style></head><body>
<h2>Bildschirm oder Fenster w\\u00e4hlen</h2>
<div class="grid" id="grid"></div>
<div class="cancel-row"><button class="cancel-btn" id="cancelBtn">Abbrechen</button></div>
<script>
const sources = ${JSON.stringify(sourceData)};
const grid = document.getElementById('grid');
sources.forEach(s => {
  const div = document.createElement('div');
  div.className = 'item';
  const img = document.createElement('img');
  img.src = s.thumbnail;
  div.appendChild(img);
  const label = document.createElement('div');
  label.className = 'label';
  label.textContent = s.name;
  div.appendChild(label);
  div.addEventListener('click', () => {
    require('electron').ipcRenderer.send('${PICKER_CHANNEL}', s.id);
  });
  grid.appendChild(div);
});
document.getElementById('cancelBtn').addEventListener('click', () => {
  require('electron').ipcRenderer.send('${PICKER_CHANNEL}', null);
});
</script></body></html>`;

    const tmpFile = path.join(os.tmpdir(), 'gaming-hub-screen-picker.html');
    fs.writeFileSync(tmpFile, pickerHtml, 'utf-8');

    const picker = new BrowserWindow({
      width: 680,
      height: 520,
      parent: mainWindow,
      modal: true,
      resizable: false,
      minimizable: false,
      maximizable: false,
      title: 'Bildschirm / Fenster w\u00e4hlen',
      backgroundColor: '#1a1b1e',
      autoHideMenuBar: true,
      webPreferences: {
        contextIsolation: false,
        nodeIntegration: true,
      },
    });

    picker.loadFile(tmpFile);

    let resolved = false;

    const onPickerResult = (_event, selectedId) => {
      if (resolved) return;
      resolved = true;
      ipcMain.removeListener(PICKER_CHANNEL, onPickerResult);
      picker.close();
      try { fs.unlinkSync(tmpFile); } catch {}

      if (!selectedId) {
        callback({});
        return;
      }
      const chosen = sources.find(s => s.id === selectedId);
      if (chosen) {
        callback({ video: chosen, audio: 'loopback' });
      } else {
        callback({});
      }
    };

    ipcMain.on(PICKER_CHANNEL, onPickerResult);

    picker.on('closed', () => {
      try { fs.unlinkSync(tmpFile); } catch {}
      if (!resolved) {
        resolved = true;
        ipcMain.removeListener(PICKER_CHANNEL, onPickerResult);
        callback({});
      }
    });
  });

  // Custom User-Agent to identify Electron app
  const currentUA = mainWindow.webContents.getUserAgent();
  mainWindow.webContents.setUserAgent(currentUA + ` GamingHubDesktop/${APP_VERSION}`);

  mainWindow.loadURL(HUB_URL);

  // Open external links in default browser
  mainWindow.webContents.setWindowOpenHandler(({ url }) => {
    if (!url.startsWith(HUB_URL)) {
      shell.openExternal(url);
      return { action: 'deny' };
    }
    return { action: 'allow' };
  });

  // ── GOG OAuth: intercept the redirect in child windows ──
  mainWindow.webContents.on('did-create-window', (childWindow) => {
    childWindow.webContents.on('will-redirect', async (event, url) => {
      // GOG redirects to embed.gog.com/on_login_success?code=XXX after auth
      if (url.includes('on_login_success') && url.includes('code=')) {
        event.preventDefault();

        try {
          const parsed = new URL(url);
          const code = parsed.searchParams.get('code') || '';
          const state = parsed.searchParams.get('state') || '';

          if (code) {
            // Exchange code via renderer fetch (has Pangolin session cookie)
            const jsCode = `
              fetch('/api/game-library/gog/exchange', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ code: ${JSON.stringify(code)}, linkTo: ${JSON.stringify(state)} }),
              }).then(r => r.json()).then(result => {
                window.dispatchEvent(new Event('gog-connected'));
                return result;
              })
            `;
            const result = await mainWindow.webContents.executeJavaScript(jsCode);

            if (result && result.ok) {
              childWindow.loadURL(`data:text/html,${encodeURIComponent(`<!DOCTYPE html><html><head><style>body{background:#1a1a2e;color:#fff;font-family:sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0}div{text-align:center}h2{color:#a855f7}</style></head><body><div><h2>GOG verbunden!</h2><p>${result.profileName}: ${result.gameCount} Spiele geladen.</p></div></body></html>`)}`);
              setTimeout(() => { try { childWindow.close(); } catch {} }, 2500);
            } else {
              childWindow.loadURL(`data:text/html,${encodeURIComponent(`<!DOCTYPE html><html><head><style>body{background:#1a1a2e;color:#fff;font-family:sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0}div{text-align:center}h2{color:#e74c3c}</style></head><body><div><h2>Fehler</h2><p>${(result && result.error) || 'Unbekannter Fehler'}</p></div></body></html>`)}`);
            }
          }
        } catch (err) {
          console.error('[GOG] Exchange error:', err);
          childWindow.loadURL(`data:text/html,${encodeURIComponent('<!DOCTYPE html><html><head><style>body{background:#1a1a2e;color:#fff;font-family:sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;margin:0}div{text-align:center}h2{color:#e74c3c}</style></head><body><div><h2>Fehler</h2><p>GOG-Verbindung fehlgeschlagen.</p></div></body></html>')}`);
        }
      }
    });

    // Allow child windows to navigate to GOG auth (don't open in external browser)
    childWindow.webContents.on('will-navigate', (event, url) => {
      if (url.startsWith('https://auth.gog.com') || url.startsWith('https://login.gog.com') ||
          url.startsWith('https://embed.gog.com') || url.startsWith(HUB_URL)) {
        // Allow navigation within popup for GOG auth flow
        return;
      }
    });
  });

  // Handle navigation to external URLs
  mainWindow.webContents.on('will-navigate', (event, url) => {
    if (!url.startsWith(HUB_URL)) {
      event.preventDefault();
      shell.openExternal(url);
    }
  });

  // Track streaming status from renderer (synchronous — no async race)
  let isStreaming = false;
  ipcMain.on('streaming-status', (_event, active) => { isStreaming = active; });

  // Windows toast notifications from renderer
  ipcMain.on('show-notification', (_event, title, body) => {
    if (Notification.isSupported()) {
      const notif = new Notification({ title, body, icon: path.join(__dirname, 'assets', 'icon.png') });
      notif.show();
    }
  });

  // Warn before closing if a stream is active
  mainWindow.on('close', (event) => {
    if (!isStreaming) return;
    const result = dialog.showMessageBoxSync(mainWindow, {
      type: 'warning',
      buttons: ['Beenden', 'Abbrechen'],
      defaultId: 1,
      cancelId: 1,
      title: 'Stream laeuft noch!',
      message: 'Ein Stream ist noch aktiv.\nBeim Beenden wird der Stream gestoppt.',
    });
    if (result !== 0) event.preventDefault();
  });
}

app.whenReady().then(() => {
  createWindow();
  setupAutoUpdater();
});

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

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