import type { Edition } from "../services/licenseService";

/**
 * UI entitlements matrix — single front-end source of truth for feature gating.
 *
 * Keys are kebab-case because the JWT `features[]` array is a namespace shared
 * between the Rust override and this TS layer (cf. `auto-update` string on the
 * Rust side). Enforcement is UI-only (soft-paywall, GPL assumed) — the edition
 * itself is still resolved by the machine-bound Rust `current_edition()`.
 *
 * Modules that stay Free (dashboard, import, transactions, categories,
 * reports/trends, export, changelog, docs) have NO key here → never gated.
 */
export type FeatureKey =
  | "budget"
  | "adjustments"
  | "reports-advanced"
  | "multi-profile"
  | "balance";

export const ENTITLEMENTS: Record<FeatureKey, Edition[]> = {
  budget: ["base", "premium"],
  adjustments: ["base", "premium"],
  "reports-advanced": ["base", "premium"],
  "multi-profile": ["base", "premium"],
  balance: ["premium"],
};

/**
 * Pure entitlement check.
 *
 * Fail-closed in Free (CWE-863): a `license.key` copied onto another machine
 * downgrades `edition` → "free" (machine-binding), but still carries its signed
 * `features[]`. We must NOT re-grant those features to a downgraded license, so
 * the Free short-circuit runs BEFORE the `features[]` override.
 *
 * `licenseFeatures` is the JWT override namespace. An unknown feature (not in
 * the matrix — the namespace is shared with Rust and may drift) is deny-all
 * unless explicitly present in the signed override.
 */
export function isEntitled(
  f: FeatureKey,
  edition: Edition,
  licenseFeatures: string[],
): boolean {
  if (edition === "free") return false;
  const tiers = ENTITLEMENTS[f];
  if (!tiers) return licenseFeatures.includes(f);
  return tiers.includes(edition) || licenseFeatures.includes(f);
}

/**
 * Minimum paid tier that unlocks a feature — drives the upsell copy
 * ("Obtenir Base" vs "Obtenir Premium"). Derived from matrix MEMBERSHIP, not
 * array order, so reordering an ENTITLEMENTS row can never change the answer.
 */
export function requiredTierFor(f: FeatureKey): Edition {
  return ENTITLEMENTS[f].includes("base") ? "base" : "premium";
}
