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 { CarrierShipment } from "../../../data/entities.js";
import { getShippingAdapter } from "../../../lib/adapter-registry.js";
import { getShippingCarrierQueue } from "../../../lib/queue.js";
import { shippingCarriersTag } from "../../openapi.js";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("shipping_carriers").child({ component: "webhook" });
const metadata = {
  path: "/shipping-carriers/webhook/[provider]",
  POST: { requireAuth: false }
};
const WEBHOOK_VERIFICATION_FAILED = "Webhook verification failed";
const shippingCarrierWebhookRateLimitConfig = {
  points: 60,
  duration: 60,
  keyPrefix: "shipping_carriers:webhook"
};
function readCarrierShipmentId(payload) {
  if (!payload) return null;
  const shipmentId = payload.shipmentId;
  if (typeof shipmentId === "string" && shipmentId.trim().length > 0) return shipmentId.trim();
  const data = payload.data;
  if (data && typeof data === "object") {
    const nested = data.shipmentId;
    if (typeof nested === "string" && nested.trim().length > 0) return nested.trim();
  }
  return null;
}
async function POST(req, { params }) {
  const resolvedParams = await params;
  const providerKey = resolvedParams.provider;
  const adapter = getShippingAdapter(providerKey);
  if (!adapter) {
    return NextResponse.json({ error: `No shipping adapter for provider: ${providerKey}` }, { status: 404 });
  }
  const container = await createRequestContainer();
  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 em = container.resolve("em");
  const integrationCredentialsService = container.resolve("integrationCredentialsService");
  const queue = getShippingCarrierQueue("shipping-carriers-webhook");
  const payload = await readJsonSafe(rawBody);
  const carrierShipmentId = readCarrierShipmentId(payload);
  try {
    const candidates = carrierShipmentId ? await findWithDecryption(
      em,
      CarrierShipment,
      {
        providerKey,
        carrierShipmentId,
        deletedAt: null
      },
      { limit: 10, orderBy: { createdAt: "desc" } }
    ) : [];
    let shipment = 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(`carrier_${providerKey}`, candidateScope) ?? {};
      try {
        event = await adapter.verifyWebhook({ rawBody, headers, credentials });
        shipment = candidate;
        matchedScope = candidateScope;
        break;
      } catch (error) {
        lastVerificationError = error;
      }
    }
    if (!event || !shipment || !matchedScope) {
      throw lastVerificationError ?? new Error("Webhook verification failed: no matching shipment");
    }
    await queue.enqueue({
      name: "shipping-carrier-webhook",
      payload: {
        providerKey,
        event,
        shipmentId: shipment.id,
        scope: matchedScope
      }
    });
    return NextResponse.json({ received: true, queued: true }, { status: 202 });
  } catch (error) {
    logger.warn("Webhook verification failed", { providerKey, err: error });
    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,
    shippingCarrierWebhookRateLimitConfig,
    `${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: [shippingCarriersTag],
  summary: "Receive shipping carrier webhook",
  methods: {
    POST: {
      summary: "Process inbound carrier webhook",
      tags: [shippingCarriersTag],
      responses: [
        { status: 202, description: "Webhook accepted for async processing" },
        { status: 401, description: "Signature verification failed" },
        { status: 404, description: "Unknown provider" }
      ]
    }
  }
};
export {
  POST,
  metadata,
  openApi
};
//# sourceMappingURL=route.js.map
