/**
 * Subscription tiers (CK Basis / CK Pro) — the one place that decides what a
 * tier is allowed to see. Community & Research, the push service and the admin
 * cockpit all go through these functions; none of them compares tiers itself.
 *
 * A tier is a *content* level, independent of module rights (`community` READ /
 * WRITE) and of the ADMIN role. Pro always includes Basis.
 */

export const SUBSCRIPTION_TIERS = ['BASIS', 'PRO'] as const;
export type SubscriptionTier = (typeof SUBSCRIPTION_TIERS)[number];

/**
 * Transition rule until the soft launch: accounts without a subscription tier
 * (`users.subscription_tier IS NULL` — existing members, staff) are treated as
 * this tier, so nothing gets worse for the existing community. At the soft
 * launch this single constant is switched to 'BASIS'; no other code changes.
 */
export const NO_SUBSCRIPTION_FALLBACK_TIER: SubscriptionTier = 'PRO';

/** What a new channel requires when nobody chose otherwise. */
export const DEFAULT_CHANNEL_MIN_TIER: SubscriptionTier = 'PRO';

const RANK: Record<SubscriptionTier, number> = { BASIS: 1, PRO: 2 };

export interface TierSubject {
  role: 'USER' | 'ADMIN';
  subscriptionTier: SubscriptionTier | null;
}

/**
 * The tier an account is served at. Administrators always see everything; an
 * editor (`options.editor`) does too, because an editor must be able to open
 * and correct every post. Everyone else gets their stored tier, or the
 * transition fallback when they have none.
 */
export function effectiveTier(
  subject: TierSubject,
  options: { editor?: boolean } = {},
): SubscriptionTier {
  if (subject.role === 'ADMIN' || options.editor) return 'PRO';
  return subject.subscriptionTier ?? NO_SUBSCRIPTION_FALLBACK_TIER;
}

/** `required` null (or absent) means "no minimum": every tier qualifies. */
export function tierSatisfies(have: SubscriptionTier, required: SubscriptionTier | null): boolean {
  return required == null || RANK[have] >= RANK[required];
}
