import {
  ok,
  type ReadonlyDB,
  type QueryContext,
  type PaginationInput,
  buildPaginatedResult,
  DEFAULT_PAGE_SIZE,
} from "@tailor-platform/erp-kit/core";
import type { DB } from "../generated/kysely-tailordb";

type AuditOrderByField = "occurredAt" | "createdAt";

export interface ListAuditBySourceInput extends PaginationInput<AuditOrderByField> {
  sourceType: string;
  sourceId: string;
}

/**
 * Returns the paginated audit trail for a source's fanned-out Notifications ordered by occurredAt, scoped to the caller's own rows.
 */
export async function run(db: ReadonlyDB<DB>, input: ListAuditBySourceInput, ctx: QueryContext) {
  const limit = input.limit ?? DEFAULT_PAGE_SIZE;
  const offset = input.offset ?? 0;
  const orderBy = input.orderBy ?? "occurredAt";
  const orderDirection = input.orderDirection ?? "asc";

  // Resolve Notifications by (sourceType, sourceId) first, then load the audit
  // rows anchored to those notifications. Self-scope: a caller only sees audit
  // rows of notifications addressed to them.
  const notifications = await db
    .selectFrom("Notification")
    .select(["id"])
    .where("sourceType", "=", input.sourceType)
    .where("sourceId", "=", input.sourceId)
    .where("recipientUserId", "=", ctx.actorId)
    .execute();

  const notificationIds = notifications.map((n) => n.id);
  if (notificationIds.length === 0) {
    return ok(buildPaginatedResult([], limit));
  }

  const rows = await db
    .selectFrom("NotificationDeliveryAudit")
    .selectAll()
    .where("notificationId", "in", notificationIds)
    .orderBy(orderBy, orderDirection)
    .limit(limit + 1)
    .offset(offset)
    .execute();

  return ok(buildPaginatedResult(rows, limit));
}
