/**
 * config/pricing.js — Single source of truth for all TuneVault plan pricing.
 *
 * Owns: canonical price constants for every tier × billing-period combo.
 * Does NOT own: Razorpay order creation, user credits, quota limits.
 *
 * To add a new plan: add an entry to CONN_PRICES and ANNUAL_DISCOUNT handles
 * the rest automatically. Update CLAUDE.md with the new tier name and price.
 */

'use strict';

// Per-connection pricing in USD cents per connection per month (monthly rate).
// No per-seat fees at any tier — users are included up to max_users.
const CONN_PRICES = {
  free:             { conn: 0,    seat: 0, min_conns: 1,   max_conns: 1,    max_users: 1  },  // $0 — 30-day self-hosted trial; NOT purchasable (see FREE_TIER)
  starter:          { conn: 4900, seat: 0, min_conns: 1,   max_conns: 5,    max_users: 3  },  // $49/conn/mo
  professional:     { conn: 3500, seat: 0, min_conns: 6,   max_conns: 25,   max_users: 10 },  // $35/conn/mo
  business:         { conn: 2500, seat: 0, min_conns: 26,  max_conns: 80,   max_users: 25 },  // $25/conn/mo
  enterprise:       { conn: 1800, seat: 0, min_conns: 81,  max_conns: 300,  max_users: 50 },  // $18/conn/mo
  managed_services: { conn: 1200, seat: 0, min_conns: 301, max_conns: 1000, max_users: -1 },  // $12/conn/mo
  individual:       { conn: 4900, seat: 0, min_conns: 1,   max_conns: 5,    max_users: 3  },  // legacy alias for starter
  team:             { conn: 3500, seat: 0, min_conns: 6,   max_conns: 25,   max_users: 10 },  // legacy alias for professional
};

/**
 * Free self-hosted tier — the canonical shape of the 30-day trial license
 * minted by POST /api/license/free. Single source of truth; routes/license.js
 * reads this rather than hardcoding the numbers.
 *
 * NOT purchasable: 'free' is deliberately absent from PER_CONN_TIERS and from
 * the hardcoded tier allowlists in routes/payments.js, so no Razorpay order can
 * ever be created for it.
 *
 * Unlimited checks are safe here because self-hosted runs on the customer's own
 * hardware with their own AI keys — it costs us nothing. expires_at is what
 * makes the trial a trial (EXPIRED_CAPS then stops new checks), so the value is
 * in the days, not the check count.
 *
 * max_health_checks_per_month -1 = unlimited (lib/license-caps.js isUnlimitedCap
 * treats -1/null/undefined alike).
 */
const FREE_TIER = {
  plan_tier: 'free',
  days: 30,
  max_connections: 1,
  max_health_checks_per_month: -1,
};

// Annual billing: 20% off the monthly rate, charged upfront for 12 months.
const ANNUAL_DISCOUNT = 0.8;

// Enterprise volume-discount tiers (applied on top of the per-conn rate).
const ENTERPRISE_VOLUME_THRESHOLDS = [
  { min: 200, discount: 0.15 },
  { min: 150, discount: 0.10 }
];

/**
 * Returns the enterprise volume discount multiplier (0–1) for a given connection count.
 * 200+ connections → 15% off, 150+ → 10% off, below 150 → 0%.
 */
function enterpriseVolumeDiscount(connectionCount) {
  for (const t of ENTERPRISE_VOLUME_THRESHOLDS) {
    if (connectionCount >= t.min) return t.discount;
  }
  return 0;
}

// List of tiers that use per-connection pricing (vs legacy flat tiers).
const PER_CONN_TIERS = ['starter', 'professional', 'business', 'enterprise', 'managed_services'];

// Legacy flat-rate tiers kept for backwards compatibility with old subscriptions.
const LEGACY_PRICES = {
  individual: 4900,  // $49/mo (old name for starter-equivalent)
  growth:     7900,  // $79/mo
  scale:      19900, // $199/mo
  custom:     49900  // $499/mo
};

/**
 * Calculate the Razorpay order amount in USD cents for a per-connection order.
 *
 * Monthly:  conn_rate × conns (no seat fee at any tier)
 * Annual:   monthly_total × 12 × 0.8, billed upfront (20% off)
 *
 * connection_count is clamped to [min_conns, max_conns].
 * Returns null if tier is unrecognised.
 */
function calcPerConnAmount(tier, billing, connectionCount, _seatCount) {
  const rates = CONN_PRICES[tier];
  if (!rates) return null;

  const conns = Math.max(rates.min_conns, Math.min(rates.max_conns, parseInt(connectionCount) || rates.min_conns));

  const baseMonthly = rates.conn * conns;

  // Apply enterprise volume discount (150+ conns → 10%, 200+ → 15%).
  // Round to nearest whole dollar (×100) to match the frontend which rounds in dollar space.
  const volDisc = (tier === 'enterprise') ? enterpriseVolumeDiscount(conns) : 0;
  const monthlyTotal = volDisc > 0
    ? Math.round(baseMonthly * (1 - volDisc) / 100) * 100
    : baseMonthly;

  let amount, description;
  if (billing === 'annual') {
    // Enterprise: quarterly billing (3 months) to stay within Razorpay's per-transaction
    // limit; all other tiers charge 12 months upfront. Both get the 20% annual discount.
    const billingMonths = (tier === 'enterprise') ? 3 : 12;
    amount = Math.round(monthlyTotal * billingMonths * ANNUAL_DISCOUNT);
    const connMonthly = Math.round(rates.conn * (1 - volDisc) * ANNUAL_DISCOUNT / 100);
    const billingLabel = (tier === 'enterprise') ? 'quarterly, 20% off' : 'annual, 20% off';
    description = `TuneVault ${tier} — ${conns} conn${conns > 1 ? 's' : ''} × $${connMonthly}/mo`
      + (volDisc > 0 ? ` (${Math.round(volDisc * 100)}% vol. discount, ` : ' (')
      + `${billingLabel})`;
  } else {
    amount = monthlyTotal;
    const effectiveRate = Math.round(rates.conn * (1 - volDisc));
    const connDollars = effectiveRate / 100;
    description = `TuneVault ${tier} — ${conns} conn${conns > 1 ? 's' : ''} × $${connDollars}/mo`
      + (volDisc > 0 ? ` (${Math.round(volDisc * 100)}% vol. discount)` : '');
  }

  return { amount, description, connectionCount: conns, seatCount: 0 };
}

/**
 * Returns the legacy flat-tier price in USD cents.
 * Annual billing uses a 10-month rate (2 months free) for legacy tiers only.
 */
function getLegacyPrice(tier, billing) {
  const monthly = LEGACY_PRICES[tier];
  if (!monthly) return null;
  return billing === 'annual' ? monthly * 10 : monthly;
}

/**
 * Returns a public-safe pricing summary suitable for the GET /api/payments/pricing
 * endpoint. No secrets — just the numbers the frontend needs to display prices
 * and pre-fill checkout amounts for validation.
 */
function getPricingSummary() {
  const tierSummary = (key) => ({
    monthly: { conn: CONN_PRICES[key].conn, seat: 0 },
    annual:  { conn: Math.round(CONN_PRICES[key].conn * ANNUAL_DISCOUNT), seat: 0, note: '20% off, billed upfront × 12' },
    min_conns: CONN_PRICES[key].min_conns,
    max_conns: CONN_PRICES[key].max_conns,
    max_users: CONN_PRICES[key].max_users,
  });

  return {
    tiers: {
      starter:          tierSummary('starter'),
      professional:     tierSummary('professional'),
      business:         tierSummary('business'),
      enterprise:       tierSummary('enterprise'),
      managed_services: tierSummary('managed_services'),
    },
    currency: 'USD',
    annual_discount_pct: 20
  };
}

module.exports = {
  CONN_PRICES,
  FREE_TIER,
  ANNUAL_DISCOUNT,
  PER_CONN_TIERS,
  LEGACY_PRICES,
  enterpriseVolumeDiscount,
  calcPerConnAmount,
  getLegacyPrice,
  getPricingSummary
};
