import { NextResponse } from "next/server";
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
import { findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
import { CommunicationChannel } from "../../../../data/entities.js";
import {
  COMMUNICATION_CHANNELS_QUEUES,
  getCommunicationChannelsQueue
} from "../../../../lib/queue.js";
import {
  decodeGmailPubSubBody,
  getGmailPubSubVerifier,
  GmailPubSubJwtError
} from "../../../../lib/gmail-pubsub-jwt.js";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("communication_channels").child({ component: "gmail-webhook" });
const metadata = {
  path: "/communication_channels/webhooks/gmail",
  // Unauthenticated at the platform layer (a Google-signed JWT is the auth).
  // Rate-limited so a caller can't drive unbounded JWT-verification +
  // cert-fetch work before the signature gate rejects them.
  POST: { requireAuth: false, rateLimit: { points: 120, duration: 60, keyPrefix: "cc_webhook_gmail" } }
};
async function POST(req) {
  const expectedAudience = process.env.OM_GMAIL_PUBSUB_AUDIENCE;
  const expectedEmail = process.env.OM_GMAIL_PUBSUB_SERVICE_ACCOUNT_EMAIL;
  if (!expectedAudience || !expectedEmail) {
    logger.error("OM_GMAIL_PUBSUB_AUDIENCE / OM_GMAIL_PUBSUB_SERVICE_ACCOUNT_EMAIL not set");
    return NextResponse.json({ error: "webhook not configured" }, { status: 503 });
  }
  const verifier = getGmailPubSubVerifier();
  try {
    await verifier.verify({
      authorizationHeader: req.headers.get("authorization"),
      expectedAudience,
      expectedEmail
    });
  } catch (err) {
    if (err instanceof GmailPubSubJwtError) {
      const status = err.code === "wrong_audience" ? 403 : err.code === "fetch_certs_failed" ? 503 : 401;
      return NextResponse.json({ error: err.code, message: err.message }, { status });
    }
    throw err;
  }
  let rawBody;
  try {
    rawBody = await req.text();
  } catch {
    return NextResponse.json({ error: "unreadable_body" }, { status: 400 });
  }
  let payload;
  try {
    payload = decodeGmailPubSubBody(rawBody);
  } catch (err) {
    return NextResponse.json(
      { error: err instanceof Error ? err.message : "invalid_payload" },
      { status: 400 }
    );
  }
  const container = await createRequestContainer();
  const em = container.resolve("em").fork();
  const channels = await findWithDecryption(
    em,
    CommunicationChannel,
    {
      providerKey: "gmail",
      externalIdentifier: payload.emailAddress,
      isActive: true,
      deletedAt: null
    }
  );
  if (channels.length === 0) {
    return new NextResponse(null, { status: 204 });
  }
  const queue = getCommunicationChannelsQueue(
    COMMUNICATION_CHANNELS_QUEUES.gmailHistorySync
  );
  for (const channel of channels) {
    const job = {
      channelId: channel.id,
      scope: {
        tenantId: channel.tenantId,
        organizationId: channel.organizationId ?? null
      },
      notification: {
        emailAddress: payload.emailAddress,
        historyId: String(payload.historyId)
      }
    };
    try {
      await queue.enqueue(job);
    } catch (err) {
      logger.error(
        "failed to enqueue history-sync for channel",
        { channelId: channel.id, err }
      );
    }
  }
  return new NextResponse(null, { status: 204 });
}
const openApi = {
  tags: ["CommunicationChannels"],
  methods: {
    POST: {
      summary: "Gmail Pub/Sub push notification webhook (Spec C \xA7 Phase C2)",
      tags: ["CommunicationChannels"],
      responses: [
        { status: 204, description: "Notification verified + history-sync job enqueued" },
        { status: 400, description: "Body not a valid Pub/Sub envelope" },
        { status: 401, description: "Invalid JWT or email claim" },
        { status: 403, description: "Wrong audience" },
        { status: 503, description: "Webhook not configured / Google certs unreachable" }
      ]
    }
  }
};
var route_default = POST;
export {
  POST,
  route_default as default,
  metadata,
  openApi
};
//# sourceMappingURL=route.js.map
