import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/core";
import type { Transaction } from "../generated/kysely-tailordb";
import { NotDeliveredError, NotificationNotFoundError } from "../lib/errors.generated";

export interface ArchiveNotificationInput {
  notificationId: string;
}

/**
 * Adds ARCHIVED to a caller-owned, delivered Notification and stamps archivedAt, writing an ARCHIVED audit row. Idempotent; does not imply READ.
 */
export async function run(db: Transaction, input: ArchiveNotificationInput, ctx: CommandContext) {
  const { notificationId } = input;

  const notification = await db
    .selectFrom("Notification")
    .selectAll()
    .where("id", "=", notificationId)
    .forUpdate()
    .executeTakeFirst();

  // A notification owned by another user is reported exactly like a missing
  // one so callers cannot enumerate foreign notification ids.
  if (!notification || notification.recipientUserId !== ctx.actorId) {
    return err(new NotificationNotFoundError(notificationId));
  }

  if (notification.deliveryStatus !== "SENT" && notification.deliveryStatus !== "DELIVERED") {
    return err(new NotDeliveredError(notificationId));
  }

  // Idempotent: row already ARCHIVED -> return unchanged, do not re-stamp archivedAt
  if (notification.engagementStatuses.includes("ARCHIVED")) {
    return ok({ notification });
  }

  const now = new Date();

  const updated = await db
    .updateTable("Notification")
    .set({
      engagementStatuses: [...notification.engagementStatuses, "ARCHIVED"],
      archivedAt: now,
      updatedAt: now,
    })
    .where("id", "=", notificationId)
    .returningAll()
    .executeTakeFirstOrThrow();

  await db
    .insertInto("NotificationDeliveryAudit")
    .values({
      id: crypto.randomUUID(),
      notificationId,
      eventType: "ARCHIVED",
      occurredAt: now,
      occurredBy: notification.recipientUserId,
      errorClass: null,
      errorDetail: null,
      createdAt: now,
      updatedAt: now,
    })
    .execute();

  return ok({ notification: updated });
}
