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

export interface CreateNotificationSubscriptionInput {
  userId: string;
  sourceType: string;
  sourceId: string;
}

/**
 * Creates a NotificationSubscription for a (userId, sourceType, sourceId) triple. Idempotent on the unique triple; self-service only.
 */
export async function run(
  db: Transaction,
  input: CreateNotificationSubscriptionInput,
  ctx: CommandContext,
) {
  const { userId, sourceType, sourceId } = input;

  if (ctx.actorId !== userId) {
    return err(new ForbiddenError(userId));
  }

  const existing = await db
    .selectFrom("NotificationSubscription")
    .selectAll()
    .where("userId", "=", userId)
    .where("sourceType", "=", sourceType)
    .where("sourceId", "=", sourceId)
    .forUpdate()
    .executeTakeFirst();

  if (existing) {
    return ok({ subscription: existing });
  }

  const inserted = await db
    .insertInto("NotificationSubscription")
    .values({
      id: crypto.randomUUID(),
      userId,
      sourceType,
      sourceId,
      subscribedAt: new Date(),
    })
    .returningAll()
    .executeTakeFirstOrThrow();

  return ok({ subscription: inserted });
}
