import { posthog } from "../analytics.js"
import { AuthorizedUserReq } from "../types.js"
import { NextFunction, Response } from "express"
import { AuthStrategyFactory } from "./Auth/auth-strategy-factory.js"
import { logger } from "../utils/logger.js"
import {
  missingAuthorizationHeader,
  invalidApiKey,
  internalServerError,
} from "../exceptions/index.js"
// Middleware to check for valid API key
export async function checkForValidAPIKey(
  req: AuthorizedUserReq,
  res: Response,
  next: NextFunction,
) {
  const authHeader = req.headers.authorization

  if (authHeader == null) {
    // Log missing authorization header - logger handles environment filtering automatically
    // Production: WARN level (important security event), Development: WARN level (important security event)
    logger.warn("Request without authorization header", {
      requestId: req.requestId,
      traceId: req.traceId,
      endpoint: req.path,
      operation: "authentication",
      url: req.url,
      method: req.method,
    })

    posthog?.capture({
      distinctId: "null-user-with-missing-authorization-header",
      event: `cfapi-endpoint-called-with-missing-authorization-header`,
      properties: {
        url: req.url,
        headers: req.headers,
        body: req.body,
      },
      disableGeoip: false,
    })
    next(missingAuthorizationHeader({ requestId: req.requestId, endpoint: req.path }))
    return
  }

  // Optimized Bearer token extraction - avoid regex overhead
  const apiKey = authHeader.startsWith("Bearer ") ? authHeader.substring(7) : authHeader

  try {
    const authResult = await AuthStrategyFactory.getStrategy(apiKey).authenticate()
    if (authResult?.userId == null) {
      console.log(`User Id null for API key ${apiKey}. Returning 403`)
      posthog?.capture({
        distinctId: "null-user-with-invalid-api-key",
        event: `cfapi-endpoint-called-with-invalid-api-key`,
        properties: {
          apiKey,
        },
        disableGeoip: false,
      })
      return res.status(403).send("Invalid API key")
    }
    const userId = authResult.userId
    req.userId = userId
    req.organizationId = authResult.organizationId

    // Success - attach userId to request
    req.userId = userId

    // Log successful authentication - logger handles environment filtering automatically
    // Production: Not logged (DEBUG level), Development: Full details (DEBUG level)
    logger.debug("API key authentication successful", {
      requestId: req.requestId,
      traceId: req.traceId,
      endpoint: req.path,
      operation: "authentication",
      userId,
    })

    next()
  } catch (error) {
    // Log authentication service error - logger handles environment filtering automatically
    // Production: ERROR level with Sentry (critical infrastructure issue), Development: ERROR level with Sentry
    logger.errorWithSentry(
      "Authentication service error occurred",
      {
        requestId: req.requestId,
        traceId: req.traceId,
        endpoint: req.path,
        operation: "authentication",
      },
      {},
      error as Error,
    )

    next(
      internalServerError("Authentication service error", {
        requestId: req.requestId,
        endpoint: req.path,
      }),
    )
  }
}
