import type { User, Tier } from "./types";

/**
 * What each tier allows.
 *
 * Kept in one place so a permission is decided the same way everywhere —
 * four separate checks would answer differently the first time one of them
 * was changed and the others weren't.
 */
export const TIERS: Record<
  Tier,
  {
    name: string;
    /** Monthly, in the site's currency. */
    price: number;
    perks: string[];
  }
> = {
  basic: {
    name: "Basic",
    price: 0,
    perks: [
      "Post, comment and share",
      "Follow anyone",
      "Message people who follow you",
    ],
  },
  pro: {
    name: "Pro",
    price: 5,
    perks: [
      "Message anyone, followed or not",
      "The full set of profile effects",
      "Your story shown to everyone, not only followers",
    ],
  },
  ultra: {
    name: "Ultra",
    price: 15,
    perks: [
      "Everything in Pro",
      "A badge on your name, everywhere it appears",
      "Priority support",
      "No adverts",
    ],
  },
};

/**
 * The tiers with whatever prices and names an admin has set.
 *
 * Falls back to the built-in ones, so a fresh site works before anybody
 * has been near the settings.
 */
export function tiersWith(settings: Record<string, unknown>) {
  const out = { ...TIERS };

  for (const key of ["pro", "ultra"] as const) {
    const price = Number(settings[`${key}Price`]);
    const name = String(settings[`${key}Name`] ?? "").trim();

    out[key] = {
      ...out[key],
      ...(Number.isFinite(price) && price >= 0 ? { price } : {}),
      ...(name ? { name } : {}),
    };
  }

  return out;
}

/** Whose tier is still current — an expired one is no tier at all. */
export function tierOf(user: Pick<User, "tier" | "tierExpiresAt"> | null | undefined): Tier {
  if (!user?.tier || user.tier === "basic") return "basic";

  if (user.tierExpiresAt && new Date(user.tierExpiresAt) < new Date()) {
    return "basic";
  }
  return user.tier;
}

/** Pro or better. System includes everything Pro has. */
export function isPro(user: Parameters<typeof tierOf>[0]): boolean {
  const tier = tierOf(user);
  return tier === "pro" || tier === "ultra";
}

/**
 * The three things Pro actually changes.
 *
 * Named rather than checked inline, so what a tier means is readable in
 * one place instead of scattered across the routes that enforce it.
 */
export const can = {
  /** Message someone who doesn't follow them. */
  messageAnyone: isPro,
  /** Use the paid profile effects. */
  fullProfileEffects: isPro,
  /** Have a story shown beyond their followers. */
  storyToEveryone: isPro,
};
