import { usePrisma } from "../utils/prisma";

/**
 * Versucht einen DiGA-Code für den User einzulösen.
 *
 * Validierung:
 *  - Code existiert
 *  - Code wurde noch nicht eingelöst (used_at IS NULL)
 *  - Code ist nicht abgelaufen (expires_at IS NULL OR expires_at > NOW)
 *
 * Bei Erfolg (atomar in einer Transaktion):
 *  - diga_codes: used_at = NOW(), used_by_profile_id = userId
 *  - profiles: plan = code.grants_plan, onboarding_step = 'done',
 *              diga_code_redeemed_at = NOW()
 *
 * Returns `null` wenn der Code ungültig ist (für saubere 4xx-Errors im Endpoint).
 */
export type RedeemResult =
  | { ok: true; plan: string; codeId: string }
  | { ok: false; reason: "not_found" | "already_used" | "expired" };

export async function redeemDigaCode(
  userId: string,
  rawCode: string,
): Promise<RedeemResult> {
  const code = rawCode.trim().toUpperCase();
  const db = usePrisma();

  return db.$transaction(async (tx) => {
    const found = await tx.digaCode.findUnique({
      where: { code },
      select: { id: true, usedAt: true, expiresAt: true, grantsPlan: true },
    });

    if (!found) {
      return { ok: false as const, reason: "not_found" as const };
    }
    if (found.usedAt) {
      return { ok: false as const, reason: "already_used" as const };
    }
    if (found.expiresAt && found.expiresAt.getTime() < Date.now()) {
      return { ok: false as const, reason: "expired" as const };
    }

    const now = new Date();

    await tx.digaCode.update({
      where: { id: found.id },
      data: { usedAt: now, usedByProfileId: userId },
    });

    // step → 'pre_protection' (NICHT 'done') — User muss noch durch den
    // Protection-Slide (NEFilter/VPN-Aktivierung auf dem Device).
    await tx.profile.update({
      where: { id: userId },
      data: {
        plan: found.grantsPlan,
        onboardingStep: "pre_protection",
        digaCodeRedeemedAt: now,
      },
    });

    return { ok: true as const, plan: found.grantsPlan, codeId: found.id };
  });
}
