import {
  type CommonReservedFields,
  type NoReservedFields,
  defaultGqlPermission,
  defaultPermission,
} from "@tailor-platform/erp-kit/core";
import { db, type TailorAnyDBField } from "@tailor-platform/sdk";
import { notification } from "./notification";

export const NOTIFICATION_AUDIT_EVENT_TYPES = [
  "QUEUED",
  "SENT",
  "DELIVERED",
  "SEEN",
  "READ",
  "ARCHIVED",
  "FAILED",
  "BOUNCED",
  "OPENED",
] as const;

const builtins = {
  notificationId: db
    .uuid()
    .relation({
      type: "n-1",
      toward: { type: notification },
      backward: "deliveryAudits",
    })
    .description("Foreign key to the parent Notification this audit row describes"),
  eventType: db
    .enum(NOTIFICATION_AUDIT_EVENT_TYPES)
    .description(
      "Lifecycle event recorded on either the deliveryStatus or engagementStatuses axis",
    ),
  occurredAt: db.datetime().description("Wall-clock timestamp at row write time; immutable"),
  occurredBy: db
    .string({ optional: true })
    .description(
      "userId for user-driven events, 'system' sentinel for dispatcher / adapter, 'TOMBSTONED' once anonymized",
    ),
  errorClass: db
    .string({ optional: true })
    .description("Error class name; populated only for FAILED and BOUNCED events"),
  errorDetail: db
    .string({ optional: true })
    .description("Sanitized error detail; cleared by the retention sweep after TTL"),
};

type ReservedFields = keyof typeof builtins | CommonReservedFields;

export interface CreateNotificationDeliveryAuditTypeParams<
  F extends Record<string, TailorAnyDBField>,
> {
  fields?: NoReservedFields<F, ReservedFields>;
}

export function createNotificationDeliveryAuditType<
  const F extends Record<string, TailorAnyDBField>,
>(params: CreateNotificationDeliveryAuditTypeParams<F>) {
  return db
    .type("NotificationDeliveryAudit", {
      ...builtins,
      ...((params.fields ?? {}) as F),
      ...db.fields.timestamps(),
    })
    .permission(defaultPermission)
    .gqlPermission(defaultGqlPermission);
}

export const notificationDeliveryAudit = createNotificationDeliveryAuditType({});
