import { NextResponse } from "next/server";
import { z } from "zod";
import { sql } from "kysely";
import { CrudHttpError, isCrudHttpError } from "@open-mercato/shared/lib/crud/errors";
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
import { resolveOrganizationScopeForRequest } from "@open-mercato/core/modules/directory/utils/organizationScope";
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
import { applyEmailVisibilityFilter } from "../../../lib/visibilityFilter.js";
import { TERMINAL_INTERACTION_STATUS_LIST } from "../../../lib/interactionStatus.js";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("customers");
const querySchema = z.object({
  entityId: z.string().uuid(),
  // `open` counts every non-terminal status (planned/in_progress/waiting + any custom status);
  // `planned` is kept as the BC alias for callers that used it to mean "open".
  status: z.enum(["done", "planned", "open"]).optional()
});
const responseSchema = z.object({
  ok: z.literal(true),
  result: z.object({
    call: z.number(),
    email: z.number(),
    meeting: z.number(),
    note: z.number(),
    task: z.number(),
    total: z.number()
  })
});
const metadata = {
  GET: { requireAuth: true, requireFeatures: ["customers.interactions.view"] }
};
const openApi = {
  tag: "Customers",
  methods: {
    GET: {
      summary: "Get interaction counts by type",
      description: "Returns per-type interaction counts scoped to an entity.",
      query: querySchema,
      responses: [
        {
          status: 200,
          description: "Counts by interaction type",
          schema: responseSchema
        }
      ]
    }
  }
};
async function GET(req) {
  try {
    const queryUrl = new URL(req.url);
    const query = querySchema.parse(Object.fromEntries(queryUrl.searchParams));
    const container = await createRequestContainer();
    const auth = await getAuthFromRequest(req);
    const { translate } = await resolveTranslations();
    if (!auth || !auth.tenantId) {
      throw new CrudHttpError(401, {
        error: translate("customers.errors.unauthorized", "Unauthorized")
      });
    }
    const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req });
    const organizationIds = Array.isArray(scope?.filterIds) && scope.filterIds.length > 0 ? scope.filterIds : auth.orgId ? [auth.orgId] : [];
    const em = container.resolve("em").fork();
    const kysely = em.getKysely();
    let baseQuery = kysely.selectFrom("customer_interactions").where("entity_id", "=", query.entityId).where("tenant_id", "=", auth.tenantId).where("deleted_at", "is", null);
    if (organizationIds.length === 1) {
      baseQuery = baseQuery.where("organization_id", "=", organizationIds[0]);
    } else if (organizationIds.length > 1) {
      baseQuery = baseQuery.where("organization_id", "in", organizationIds);
    }
    if (query.status === "open" || query.status === "planned") {
      baseQuery = baseQuery.where("status", "not in", [...TERMINAL_INTERACTION_STATUS_LIST]);
    } else if (query.status) {
      baseQuery = baseQuery.where("status", "=", query.status);
    }
    const viewerUserId = auth.isApiKey ? null : auth.sub ?? null;
    baseQuery = applyEmailVisibilityFilter(baseQuery, {
      currentUserId: viewerUserId,
      userFeatures: void 0
    });
    const rows = await baseQuery.select(["interaction_type", sql`count(*)`.as("count")]).groupBy("interaction_type").execute();
    const counts = { call: 0, email: 0, meeting: 0, note: 0, task: 0 };
    let total = 0;
    for (const row of rows) {
      const count = typeof row.count === "string" ? parseInt(row.count, 10) : row.count;
      const type = row.interaction_type;
      if (type in counts) {
        counts[type] = count;
      }
      total += count;
    }
    return NextResponse.json({ ok: true, result: { ...counts, total } });
  } catch (err) {
    if (isCrudHttpError(err)) {
      return NextResponse.json(err.body, { status: err.status });
    }
    logger.error("GET failed", { component: "interactions/counts", err });
    return NextResponse.json({ error: "Internal server error" }, { status: 500 });
  }
}
export {
  GET,
  metadata,
  openApi
};
//# sourceMappingURL=route.js.map
