import type { Request, Response, NextFunction } from 'express';

function extractBearerOrQuery(req: Request, key: string): boolean {
  const auth = String(req.headers.authorization || '');
  const bearer = auth.startsWith('Bearer ') ? auth.slice(7).trim() : '';
  const q = String(req.query.access_token ?? '').trim();
  const dashHeader = String(req.headers['x-omnl-dashboard-token'] ?? '').trim();
  return bearer === key || q === key || dashHeader === key;
}

function hasOmnlOperatorAuth(req: Request): boolean {
  const apiKey = process.env.OMNL_API_KEY?.trim();
  if (apiKey && extractBearerOrQuery(req, apiKey)) return true;
  const dashKey = process.env.OMNL_DASHBOARD_TOKEN?.trim();
  if (dashKey && extractBearerOrQuery(req, dashKey)) return true;
  return false;
}

/** Read-only compliance console API (GET). */
function isComplianceConsolePath(path: string): boolean {
  return (
    path.endsWith('/omnl/compliance/console') ||
    path.endsWith('/omnl/compliance/safe-notary-gate-tx') ||
    path.endsWith('/omnl/compliance/web3')
  );
}

/**
 * When `OMNL_API_KEY` is set, require `Authorization: Bearer <key>` or `?access_token=<key>`.
 * If unset, all requests pass (backwards compatible).
 */
export function omnlSensitiveRouteGuard(req: Request, res: Response, next: NextFunction): void {
  const key = process.env.OMNL_API_KEY?.trim();
  if (!key) {
    next();
    return;
  }
  if (hasOmnlOperatorAuth(req)) {
    next();
    return;
  }
  res.status(401).json({ error: 'Unauthorized', hint: 'Set Authorization: Bearer or access_token for OMNL_API_KEY' });
}

/** Public discovery endpoints (always unauthenticated). */
const OMNL_PUBLIC_PATH_SUFFIXES = ['/omnl/openapi.json', '/omnl/catalog', '/omnl/integration-status'];

function isPublicOmnlPath(path: string): boolean {
  if (OMNL_PUBLIC_PATH_SUFFIXES.some((s) => path.endsWith(s))) return true;
  // Compliance console is read-only; allow without API key when explicitly enabled (LAN operator UI).
  if (process.env.OMNL_COMPLIANCE_CONSOLE_PUBLIC === '1' && isComplianceConsolePath(path)) return true;
  return false;
}

/**
 * When `OMNL_REQUIRE_API_KEY=1` or `NODE_ENV=production`, require OMNL_API_KEY on all /omnl routes
 * except openapi.json, catalog, and integration-status.
 */
export function omnlRequireApiKeyInProduction(req: Request, res: Response, next: NextFunction): void {
  if (!req.path.startsWith('/omnl')) {
    next();
    return;
  }
  const requireKey =
    process.env.OMNL_REQUIRE_API_KEY === '1' ||
    (process.env.NODE_ENV || '').toLowerCase() === 'production';
  if (!requireKey || isPublicOmnlPath(req.path)) {
    next();
    return;
  }
  const key = process.env.OMNL_API_KEY?.trim();
  if (!key) {
    res.status(503).json({
      error: 'OMNL_API_KEY required in production',
      hint: 'Set OMNL_API_KEY and pass Authorization: Bearer <key>',
    });
    return;
  }
  if (extractBearerOrQuery(req, key)) {
    next();
    return;
  }
  if (isComplianceConsolePath(req.path) && hasOmnlOperatorAuth(req)) {
    next();
    return;
  }
  res.status(401).json({ error: 'Unauthorized' });
}
