import { nanoid } from "nanoid";
import type { Store } from "@/lib/data/store";
import type { Payment, WalletTransaction } from "@/lib/types";

/**
 * Credits a wallet once a real payment has cleared.
 *
 * Deliberately idempotent: providers retry webhooks, and a duplicate must not
 * pay someone twice. The payment's own status is the guard.
 */
export async function creditPayment(
  store: Store,
  paymentId: string,
  externalId?: string
) {
  const payments = await store.small<Payment[]>("payments", []);
  const payment = payments.find(
    (p) => p.id === paymentId || (externalId && p.externalId === externalId)
  );
  if (!payment) return { ok: false as const, error: "Unknown payment" };
  if (payment.status === "paid") return { ok: true as const, already: true };

  const user = await store.users.get(payment.userId);
  if (!user) return { ok: false as const, error: "Account no longer exists" };

  user.walletBalance = Math.round((user.walletBalance + payment.amount) * 100) / 100;
  payment.status = "paid";
  payment.completedAt = new Date().toISOString();

  const ledger = await store.small<WalletTransaction[]>("walletTransactions", []);
  ledger.unshift({
    id: nanoid(8),
    userId: user.id,
    type: "deposit",
    amount: payment.amount,
    description: `Top-up via ${payment.provider === "stripe" ? "card" : "PayPal"}`,
    createdAt: payment.completedAt,
  });

  await store.users.put(user);
  await store.putSmall("payments", payments);
  await store.putSmall("walletTransactions", ledger);

  return { ok: true as const, already: false };
}
