import { NextResponse } from "next/server";
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
import { findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
import { readJsonSafe } from "@open-mercato/shared/lib/http/readJsonSafe";
import { checkRateLimit, getClientIp, RATE_LIMIT_ERROR_FALLBACK } from "@open-mercato/shared/lib/ratelimit/helpers";
import { getWebhookHandler } from "@open-mercato/shared/modules/payment_gateways/types";
import { GatewayTransaction } from "../../../data/entities.js";
import { getPaymentGatewayQueue } from "../../../lib/queue.js";
import { processPaymentGatewayWebhookJob } from "../../../lib/webhook-processor.js";
import { paymentGatewaysTag } from "../../openapi.js";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("payment_gateways").child({ component: "webhook" });
const metadata = {
  path: "/payment_gateways/webhook/[provider]",
  POST: { requireAuth: false }
};
const WEBHOOK_VERIFICATION_FAILED = "Webhook verification failed";
const paymentGatewayWebhookRateLimitConfig = {
  points: 60,
  duration: 60,
  keyPrefix: "payment_gateways:webhook"
};
async function POST(req, { params }) {
  const resolvedParams = await params;
  const providerKey = resolvedParams.provider;
  const container = await createRequestContainer();
  const registration = getWebhookHandler(providerKey);
  if (!registration) {
    return NextResponse.json({ error: `No webhook handler for provider: ${providerKey}` }, { status: 404 });
  }
  const rateLimitResponse = await checkProviderWebhookRateLimit(container, req, providerKey);
  if (rateLimitResponse) return rateLimitResponse;
  const rawBody = await req.text();
  const headers = {};
  req.headers.forEach((value, key) => {
    headers[key] = value;
  });
  const service = container.resolve("paymentGatewayService");
  const em = container.resolve("em");
  const integrationCredentialsService = container.resolve("integrationCredentialsService");
  const queue = getPaymentGatewayQueue(registration.queue ?? "payment-gateways-webhook");
  const payload = await readJsonSafe(rawBody);
  const sessionIdHint = registration.readSessionIdHint?.(payload) ?? null;
  try {
    const candidates = sessionIdHint ? await findWithDecryption(
      em,
      GatewayTransaction,
      {
        providerKey,
        providerSessionId: sessionIdHint,
        deletedAt: null
      },
      { limit: 10, orderBy: { createdAt: "desc" } }
    ) : [];
    let transaction = null;
    let matchedScope = null;
    let event = null;
    let lastVerificationError = null;
    for (const candidate of candidates) {
      const candidateScope = { organizationId: candidate.organizationId, tenantId: candidate.tenantId };
      const credentials = await integrationCredentialsService.resolve(`gateway_${providerKey}`, candidateScope) ?? {};
      try {
        event = await registration.handler({ rawBody, headers, credentials });
        transaction = candidate;
        matchedScope = candidateScope;
        break;
      } catch (error) {
        lastVerificationError = error;
      }
    }
    if (!event || !transaction || !matchedScope) {
      throw lastVerificationError ?? new Error("Webhook verification failed: no matching transaction");
    }
    const scope = matchedScope;
    const jobPayload = {
      providerKey,
      event,
      transactionId: transaction.id,
      scope
    };
    if (process.env.QUEUE_STRATEGY === "async") {
      await queue.enqueue({
        name: "payment-gateway-webhook",
        payload: jobPayload
      });
    } else {
      await processPaymentGatewayWebhookJob(
        {
          em: container.resolve("em"),
          paymentGatewayService: service,
          integrationLogService: container.resolve("integrationLogService")
        },
        jobPayload
      );
    }
    return NextResponse.json({ received: true, queued: true }, { status: 202 });
  } catch (err) {
    logger.warn("Webhook verification failed", { providerKey, err });
    return NextResponse.json({ error: WEBHOOK_VERIFICATION_FAILED }, { status: 401 });
  }
}
async function checkProviderWebhookRateLimit(container, req, providerKey) {
  const rateLimiterService = tryResolve(container, "rateLimiterService");
  if (!rateLimiterService) return null;
  return checkRateLimit(
    rateLimiterService,
    paymentGatewayWebhookRateLimitConfig,
    `${providerKey}:${getClientIp(req, rateLimiterService.trustProxyDepth) ?? "unknown"}`,
    RATE_LIMIT_ERROR_FALLBACK
  );
}
function tryResolve(container, name) {
  try {
    return container.resolve(name);
  } catch {
    return null;
  }
}
const openApi = {
  tags: [paymentGatewaysTag],
  summary: "Receive payment gateway webhook",
  methods: {
    POST: {
      summary: "Process inbound webhook from payment provider",
      tags: [paymentGatewaysTag],
      responses: [
        { status: 202, description: "Webhook accepted for async processing" },
        { status: 401, description: "Signature verification failed" },
        { status: 404, description: "Unknown provider" }
      ]
    }
  }
};
var route_default = POST;
export {
  POST,
  route_default as default,
  metadata,
  openApi
};
//# sourceMappingURL=route.js.map
