/**
 * Free Trial Eligibility
 *
 * The free trial is a one-shot offer for brand-new accounts. A company loses it
 * permanently the moment it either:
 *
 *   - activates the trial, or
 *   - buys any paid package — taking a paid plan directly skips the trial for good.
 *
 * A checkout that was started but never paid for does NOT burn the trial: an
 * abandoned `pending_payment` record means the company never actually bought
 * anything, so it stays eligible.
 *
 * Every path goes through here — the pricing feed that decides what to show, and
 * checkout, which is the authority. Keeping them on one rule means the trial can
 * never be hidden but still purchasable, or vice versa.
 */

import { getModels } from '../models';

/**
 * Subscription statuses that only exist once a company has really been on a
 * plan. `pending_payment` is deliberately absent — see the note above.
 * `cancelled` is absent too: cancelling an unpaid checkout lands there, and a
 * company that cancelled a *paid* plan is caught by the paid-invoice check.
 */
const COMMITTED_STATUSES = ['active', 'trial', 'expired', 'suspended'];

export interface TrialEligibility {
  eligible: boolean;
  /** Why not, for the UI and for the checkout error message. */
  reason: 'eligible' | 'trial_used' | 'already_purchased' | 'no_company';
}

/**
 * Whether a company may still start the free trial.
 */
export async function getTrialEligibility(companyId?: string | null): Promise<TrialEligibility> {
  if (!companyId) return { eligible: false, reason: 'no_company' };

  const { CompanySubscription, Invoice } = getModels();

  // 1. Trial already activated — the strongest signal, and it survives the
  //    trial package being renamed or deleted because the flag lives on the
  //    subscription record.
  const usedTrial = await CompanySubscription.findOne({ companyId, isFreeTrial: true });
  if (usedTrial) return { eligible: false, reason: 'trial_used' };

  // 2. Ever been on a real plan (including trials created before the
  //    isFreeTrial flag existed).
  const committed = await CompanySubscription.findOne({
    companyId,
    status: { $in: COMMITTED_STATUSES },
  });
  if (committed) {
    return {
      eligible: false,
      reason: committed.status === 'trial' ? 'trial_used' : 'already_purchased',
    };
  }

  // 3. Ever paid an invoice — catches a company that subscribed and later
  //    cancelled, whose subscription status is no longer in the list above.
  try {
    const paidInvoice = await Invoice.findOne({ companyId, status: 'paid' });
    if (paidInvoice) return { eligible: false, reason: 'already_purchased' };
  } catch {
    // Invoice lookup is a backstop; the checks above already cover the
    // common cases, so don't fail eligibility on a lookup error.
  }

  return { eligible: true, reason: 'eligible' };
}

/** Human-readable explanation for a checkout rejection. */
export function trialIneligibilityMessage(reason: TrialEligibility['reason']): string {
  switch (reason) {
    case 'trial_used':
      return 'Your free trial has already been used. Choose a paid plan to continue.';
    case 'already_purchased':
      return 'The free trial is only available to new accounts. Since you already have a subscription, please choose a paid plan.';
    case 'no_company':
      return 'No company associated with this user.';
    default:
      return 'The free trial is not available for this account.';
  }
}
