// PRE Web GUI — Integration connection routes (API keys, OAuth, service configs)
const { Router } = require('express');
const {
  listConnections, setApiKey, removeConnection,
  setGoogleCredentials, getGoogleAuthUrl, exchangeGoogleCode,
  setMicrosoftCredentials, getMicrosoftAuthUrl, exchangeMicrosoftCode,
  setTelegramChatId, testTelegramToken,
  setJiraConfig, setConfluenceConfig,
  setServiceNowBasicConfig, setServiceNowOAuthConfig, getServiceNowAuthUrl, exchangeServiceNowCode,
  setD365Config, setD365Credentials, getD365AuthUrl, exchangeD365Code,
  setZoomConfig,
} = require('../connections');
const telegramReceiver = require('../telegram-receiver');

// PORT is needed for OAuth redirect URIs
const PORT = parseInt(process.env.PRE_WEB_PORT || '7749', 10);

const router = Router();

// Note: OAuth callback routes are mounted at the app root (/oauth/*), not under /api/
// They are exported separately and mounted by server.js.

router.get('/connections', (_req, res) => {
  res.json(listConnections());
});

router.post('/connections/:service/key', (req, res) => {
  const service = req.params.service;
  const { key } = req.body || {};
  if (!key) return res.status(400).json({ error: 'key required' });
  const ok = setApiKey(service, key);
  if (!ok) return res.status(400).json({ error: 'Invalid service' });
  res.json({ service, active: true });
});

router.delete('/connections/:service', (req, res) => {
  const service = req.params.service;
  removeConnection(service);
  res.json({ service, active: false });
});

router.post('/connections/telegram/test', async (req, res) => {
  const { token } = req.body || {};
  if (!token) return res.status(400).json({ error: 'token required' });
  try {
    const bot = await testTelegramToken(token);
    res.json({ success: true, bot });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

router.post('/connections/telegram/chat-id', (req, res) => {
  const { chatId } = req.body || {};
  if (!chatId) return res.status(400).json({ error: 'chatId required' });
  setTelegramChatId(chatId);
  res.json({ success: true, chatId });
});

router.get('/telegram/receiver/status', (_req, res) => {
  res.json(telegramReceiver.getStatus());
});

router.post('/connections/jira/config', (req, res) => {
  const { url, token } = req.body || {};
  if (!url || !token) return res.status(400).json({ error: 'url and token required' });
  setJiraConfig(url, token);
  res.json({ success: true });
});

router.post('/connections/confluence/config', (req, res) => {
  const { url, token } = req.body || {};
  if (!url || !token) return res.status(400).json({ error: 'url and token required' });
  setConfluenceConfig(url, token);
  res.json({ success: true });
});

router.post('/connections/servicenow/basic', (req, res) => {
  const { url, username, password } = req.body || {};
  if (!url || !username || !password) {
    return res.status(400).json({ error: 'url, username, and password required' });
  }
  setServiceNowBasicConfig(url, username, password);
  res.json({ success: true });
});

router.post('/connections/servicenow/oauth', (req, res) => {
  const { url, clientId, clientSecret } = req.body || {};
  if (!url || !clientId || !clientSecret) {
    return res.status(400).json({ error: 'url, clientId, and clientSecret required' });
  }
  setServiceNowOAuthConfig(url, clientId, clientSecret);
  res.json({ success: true });
});

router.get('/connections/servicenow/auth-url', (_req, res) => {
  const url = getServiceNowAuthUrl(PORT);
  if (!url) return res.status(400).json({ error: 'ServiceNow OAuth credentials not configured' });
  res.json({ url });
});

router.post('/connections/dynamics365/config', (req, res) => {
  const { url, tenantId, clientId, clientSecret } = req.body || {};
  if (!url || !tenantId || !clientId || !clientSecret) {
    return res.status(400).json({ error: 'url, tenantId, clientId, and clientSecret required' });
  }
  setD365Config(url, tenantId, clientId, clientSecret);
  res.json({ success: true });
});

router.post('/connections/dynamics365/credentials', (req, res) => {
  const { url, tenantId, clientId, clientSecret } = req.body || {};
  if (!url || !tenantId || !clientId || !clientSecret) {
    return res.status(400).json({ error: 'url, tenantId, clientId, and clientSecret required' });
  }
  setD365Credentials(url, tenantId, clientId, clientSecret);
  res.json({ success: true });
});

router.get('/connections/dynamics365/auth-url', (_req, res) => {
  const url = getD365AuthUrl(PORT);
  if (!url) return res.status(400).json({ error: 'D365 credentials not configured' });
  res.json({ url });
});

router.post('/connections/zoom/config', (req, res) => {
  const { accountId, clientId, clientSecret } = req.body || {};
  if (!accountId || !clientId || !clientSecret) {
    return res.status(400).json({ error: 'accountId, clientId, and clientSecret required' });
  }
  setZoomConfig(accountId, clientId, clientSecret);
  res.json({ success: true });
});

router.post('/connections/google/credentials', (req, res) => {
  const { clientId, clientSecret } = req.body || {};
  if (!clientId || !clientSecret) return res.status(400).json({ error: 'clientId and clientSecret required' });
  setGoogleCredentials(clientId, clientSecret);
  res.json({ success: true });
});

router.get('/connections/google/auth-url', (_req, res) => {
  const url = getGoogleAuthUrl(PORT);
  if (!url) return res.status(400).json({ error: 'Google credentials not configured' });
  res.json({ url });
});

router.post('/connections/microsoft/credentials', (req, res) => {
  const { tenantId, clientId, clientSecret } = req.body || {};
  if (!tenantId || !clientId || !clientSecret) {
    return res.status(400).json({ error: 'tenantId, clientId, and clientSecret required' });
  }
  setMicrosoftCredentials(tenantId, clientId, clientSecret);
  res.json({ success: true });
});

router.get('/connections/microsoft/auth-url', (_req, res) => {
  const url = getMicrosoftAuthUrl(PORT);
  if (!url) return res.status(400).json({ error: 'Microsoft credentials not configured' });
  res.json({ url });
});

// ── OAuth callbacks (mounted at root, not /api/) ──

function oauthCallbackPage(title, message, color) {
  return `<html><body style="font-family:system-ui;background:#0a0a0a;color:#fff;display:flex;align-items:center;justify-content:center;height:100vh"><div style="text-align:center"><h2 style="color:${color}">${title}</h2><p>${message}</p><p>You can close this tab.</p>${color === '#4ade80' ? '<script>setTimeout(()=>window.close(),3000)</script>' : ''}</div></body></html>`;
}

const oauthRouter = Router();

oauthRouter.get('/dynamics365/callback', async (req, res) => {
  const { code, error, error_description } = req.query;
  if (error) return res.send(oauthCallbackPage('Authorization Failed', error_description || error, '#f87171'));
  if (!code) return res.status(400).send('Missing authorization code');
  try {
    await exchangeD365Code(code, PORT);
    res.send(oauthCallbackPage('Dynamics 365 Connected!', 'Accounts, contacts, cases, and all Dataverse entities are now available.', '#4ade80'));
  } catch (err) {
    res.send(oauthCallbackPage('Token Exchange Failed', err.message, '#f87171'));
  }
});

oauthRouter.get('/servicenow/callback', async (req, res) => {
  const { code, error, error_description } = req.query;
  if (error) return res.send(oauthCallbackPage('Authorization Failed', error_description || error, '#f87171'));
  if (!code) return res.status(400).send('Missing authorization code');
  try {
    await exchangeServiceNowCode(code, PORT);
    res.send(oauthCallbackPage('ServiceNow Connected!', 'Incidents, KB, changes, and the full ITSM surface are now available.', '#4ade80'));
  } catch (err) {
    res.send(oauthCallbackPage('Token Exchange Failed', err.message, '#f87171'));
  }
});

oauthRouter.get('/microsoft/callback', async (req, res) => {
  const { code, error, error_description } = req.query;
  if (error) return res.send(oauthCallbackPage('Authorization Failed', error_description || error, '#f87171'));
  if (!code) return res.status(400).send('Missing authorization code');
  try {
    await exchangeMicrosoftCode(code, PORT);
    res.send(oauthCallbackPage('Microsoft Connected!', 'SharePoint search, files, lists, and pages are now available.', '#4ade80'));
  } catch (err) {
    res.send(oauthCallbackPage('Token Exchange Failed', err.message, '#f87171'));
  }
});

oauthRouter.get('/callback', async (req, res) => {
  const { code, error } = req.query;
  if (error) return res.send(oauthCallbackPage('Authorization Failed', error, '#f87171'));
  if (!code) return res.status(400).send('Missing authorization code');
  try {
    await exchangeGoogleCode(code, PORT);
    res.send(oauthCallbackPage('Google Connected!', 'Gmail, Drive, and Docs are now available.', '#4ade80'));
  } catch (err) {
    res.send(oauthCallbackPage('Token Exchange Failed', err.message, '#f87171'));
  }
});

module.exports = { apiRouter: router, oauthRouter };
