/**
 * billing/entitlements.ts — apply / revoke premium on a family.
 *
 * Design decision (see billing handoff): instead of a second source of truth,
 * the Razorpay webhook SYNCS entitlement onto families.tier / max_members /
 * max_children. All existing enforcement (src/lib/quota.ts → isPaidFamily)
 * keeps working unchanged. These helpers are the only writers of that sync.
 *
 * - grantPremium():  called when a subscription becomes active/charged.
 * - revokeToFree():  called when it halts/cancels/completes/expires.
 *
 * Revoke is a *downgrade of limits only* — it never deletes data. The existing
 * freeze-not-demote policy in quota.ts handles an over-limit family correctly
 * (existing members/children/storage stay; only new additions are blocked).
 */

import { sql } from "@/db";
import {
  PREMIUM_TIER,
  PREMIUM_MEMBER_LIMIT,
  PREMIUM_CHILD_LIMIT,
} from "./config";
import { FREE_MEMBER_LIMIT } from "@/lib/quota";

const FREE_TIER = "free";
const FREE_CHILD_LIMIT = 1; // matches families.max_children default

/**
 * Flip a family to premium: tier + raised member/child caps.
 * subscriptionStatus mirrors the Razorpay status string for at-a-glance admin.
 */
export async function grantPremium(familyId: string, razorpayStatus: string): Promise<void> {
  await sql`
    UPDATE families SET
      tier               = ${PREMIUM_TIER},
      subscription_status = ${razorpayStatus},
      max_members        = ${PREMIUM_MEMBER_LIMIT},
      max_children       = ${PREMIUM_CHILD_LIMIT},
      updated_at         = NOW()
    WHERE id = ${familyId}
  `;
}

/**
 * Return a family to the free tier. Limits drop back to free values; data is
 * untouched (freeze-not-demote). subscriptionStatus records why (halted/etc).
 */
export async function revokeToFree(familyId: string, razorpayStatus: string): Promise<void> {
  await sql`
    UPDATE families SET
      tier               = ${FREE_TIER},
      subscription_status = ${razorpayStatus},
      max_members        = ${FREE_MEMBER_LIMIT},
      max_children       = ${FREE_CHILD_LIMIT},
      updated_at         = NOW()
    WHERE id = ${familyId}
  `;
}

/**
 * Razorpay statuses that should keep a family entitled.
 * - active:        charged & live
 * - authenticated: mandate set up (future-dated start) — treat as entitled
 * - pending:       a charge failed but Razorpay is retrying — GRACE, keep premium
 */
export const ENTITLED_STATUSES = new Set(["active", "authenticated", "pending"]);

/** Razorpay statuses that end entitlement → downgrade to free. */
export const TERMINAL_STATUSES = new Set(["halted", "cancelled", "completed", "expired"]);
