import { NextResponse } from "next/server";
import { z } from "zod";
import { sql } from "kysely";
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
import { findOneWithDecryption, findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
import { CommunicationChannel, ExternalConversation, MessageChannelLink } from "../../../../../data/entities.js";
import { ChannelAccessDeniedError, assertCanAccessChannel } from "../../../../../lib/access-control.js";
const metadata = {
  path: "/communication_channels/channels/[id]/health",
  GET: { requireAuth: true, requireFeatures: ["communication_channels.view"] }
};
const WINDOW_HOURS = 24;
const RECENT_FAILURES_LIMIT = 10;
async function GET(req, context) {
  const { id } = await context.params;
  if (!z.string().uuid().safeParse(id).success) {
    return NextResponse.json({ error: "Invalid channel id" }, { status: 400 });
  }
  const auth = await getAuthFromRequest(req);
  if (!auth?.tenantId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }
  const container = await createRequestContainer();
  const em = container.resolve("em").fork();
  const dscope = {
    tenantId: auth.tenantId,
    organizationId: auth.orgId ?? null
  };
  const channel = await findOneWithDecryption(
    em,
    CommunicationChannel,
    { id, tenantId: auth.tenantId, organizationId: dscope.organizationId, deletedAt: null },
    void 0,
    dscope
  );
  if (!channel) {
    return NextResponse.json({ error: "Channel not found" }, { status: 404 });
  }
  let userFeatures = [];
  try {
    const rbac = container.resolve("rbacService");
    const acl = await rbac.loadAcl(auth.sub, {
      tenantId: auth.tenantId,
      organizationId: dscope.organizationId
    });
    userFeatures = acl?.isSuperAdmin ? ["*"] : Array.isArray(acl?.features) ? acl.features : [];
  } catch {
    userFeatures = [];
  }
  try {
    assertCanAccessChannel(channel, auth.sub, userFeatures);
  } catch (err) {
    if (err instanceof ChannelAccessDeniedError) {
      return NextResponse.json({ error: "Channel not found" }, { status: 404 });
    }
    throw err;
  }
  const conversations = await findWithDecryption(
    em,
    ExternalConversation,
    { channelId: channel.id, tenantId: auth.tenantId },
    void 0,
    dscope
  );
  const conversationIds = conversations.map((c) => c.id).filter(Boolean);
  const counts = { sent: 0, delivered: 0, read: 0, failed: 0, pending: 0, queued: 0, other: 0 };
  let totalsLast24h = 0;
  let recentFailures = [];
  if (conversationIds.length > 0) {
    const since = new Date(Date.now() - WINDOW_HOURS * 60 * 60 * 1e3);
    const db = em.getKysely();
    const statusRows = await db.selectFrom("message_channel_links").select(["delivery_status", sql`count(*)`.as("count")]).where("external_conversation_id", "in", conversationIds).where("tenant_id", "=", auth.tenantId).where("created_at", ">=", since).groupBy("delivery_status").execute();
    for (const row of statusRows) {
      const value = Number(row.count) || 0;
      totalsLast24h += value;
      const key = row.delivery_status;
      if (key && key in counts) counts[key] += value;
      else counts.other += value;
    }
    recentFailures = await findWithDecryption(
      em,
      MessageChannelLink,
      {
        externalConversationId: { $in: conversationIds },
        tenantId: auth.tenantId,
        deliveryStatus: "failed"
      },
      { limit: RECENT_FAILURES_LIMIT, orderBy: { createdAt: "desc" } },
      dscope
    );
  }
  return NextResponse.json({
    channelId: channel.id,
    providerKey: channel.providerKey,
    channelType: channel.channelType,
    windowHours: WINDOW_HOURS,
    counts,
    totalsLast24h,
    recentFailures: recentFailures.map((link) => ({
      id: link.id,
      messageId: link.messageId,
      direction: link.direction,
      createdAt: link.createdAt?.toISOString?.() ?? null,
      lastError: link.channelMetadata?.lastError ?? null,
      transient: link.channelMetadata?.transient ?? null
    }))
  });
}
const openApi = {
  tags: ["CommunicationChannels"],
  methods: {
    GET: {
      summary: "Snapshot of channel delivery health (last 24h)",
      tags: ["CommunicationChannels"],
      responses: [
        { status: 200, description: "Health snapshot" },
        { status: 400, description: "Invalid channel id" },
        { status: 401, description: "Unauthorized" },
        { status: 404, description: "Channel not found" }
      ]
    }
  }
};
var route_default = GET;
export {
  GET,
  route_default as default,
  metadata,
  openApi
};
//# sourceMappingURL=route.js.map
