/**
 * API Key Authentication Middleware
 * 
 * Allows external tools (like NotiBot) to authenticate via API key
 * instead of session cookies. Supports:
 * - Header: X-API-Key: <key>
 * - Header: Authorization: Bearer <key>
 * - Query param: ?apiKey=<key>
 * 
 * If an API key is present and valid, the request is authenticated
 * as that user (req.user is set, req.isAuthenticated() returns true).
 * If no API key is present, falls through to normal session auth.
 */

import { Request, Response, NextFunction } from "express";
import { storage } from "./storage.js";
import { User } from "../shared/schema.js";

export function apiKeyAuth() {
  return async (req: Request, _res: Response, next: NextFunction) => {
    // Skip if already authenticated via session
    if (req.isAuthenticated && req.isAuthenticated()) {
      return next();
    }

    // Extract API key from various sources
    let apiKey: string | undefined;

    // 1. X-API-Key header
    const xApiKey = req.headers["x-api-key"];
    if (typeof xApiKey === "string") {
      apiKey = xApiKey;
    }

    // 2. Authorization: Bearer <key>
    if (!apiKey) {
      const auth = req.headers["authorization"];
      if (typeof auth === "string" && auth.startsWith("Bearer ")) {
        apiKey = auth.substring(7);
      }
    }

    // 3. Query parameter
    if (!apiKey && typeof req.query.apiKey === "string") {
      apiKey = req.query.apiKey;
    }

    if (!apiKey) {
      return next(); // No API key, fall through to session auth
    }

    try {
      const user = await storage.getUserByApiKey(apiKey);
      if (user && user.isActive) {
        // Attach user to request (mimics passport behavior)
        (req as any).user = user;
        (req as any).isAuthenticated = () => true;
      }
    } catch (err) {
      console.error("[API Key Auth] Error:", err);
    }

    next();
  };
}
