import {
  PLAN_DEFINITIONS,
  TRIAL_DAYS,
  type Entitlements,
  type SubscriptionPlan,
  type SubscriptionStatus,
} from "@app/shared-types";

export interface SubscriptionSnapshot {
  plan: SubscriptionPlan;
  status: SubscriptionStatus;
  expiresAt?: Date | null;
  gracePeriodExpiresAt?: Date | null;
}

export interface TrialSnapshot {
  startedAt: Date;
  endsAt: Date;
}

export interface UsageSnapshot {
  aiScansUsedThisMonth: number;
}

/**
 * Backend är source of truth (spec §47, §61.14). Denna funktion är den enda
 * platsen som avgör vad en användare får göra.
 *
 * Prioritet: aktiv betald prenumeration (inkl. grace) > pågående trial > free.
 */
export function computeEntitlements(
  subscription: SubscriptionSnapshot | null,
  trial: TrialSnapshot | null,
  usage: UsageSnapshot,
  now: Date = new Date(),
): Entitlements {
  // 1. Betald prenumeration
  if (subscription) {
    const withinPeriod = subscription.expiresAt == null || subscription.expiresAt > now;
    const withinGrace =
      subscription.gracePeriodExpiresAt != null && subscription.gracePeriodExpiresAt > now;
    const active =
      (subscription.status === "active" || subscription.status === "trial") && withinPeriod;
    const inGrace = subscription.status === "in_grace" && withinGrace;

    if (active || inGrace) {
      const def = PLAN_DEFINITIONS[subscription.plan];
      return {
        plan: subscription.plan,
        status: inGrace ? "in_grace" : subscription.status,
        maxHouseholdMembers: def.maxHouseholdMembers,
        aiScansPerMonth: def.aiScansPerMonth,
        aiScansUsedThisMonth: usage.aiScansUsedThisMonth,
        weekPlanning: def.weekPlanning,
        advancedNutrition: def.advancedNutrition,
        communityPublish: def.communityPublish,
        expiresAt: subscription.expiresAt?.toISOString(),
        graceUntil: subscription.gracePeriodExpiresAt?.toISOString(),
      };
    }
  }

  // 2. Trial: 7 dagar full tillgång utan kort (spec §46). Family-nivå under trial.
  if (trial && trial.endsAt > now) {
    const def = PLAN_DEFINITIONS.family;
    return {
      plan: "family",
      status: "trial",
      maxHouseholdMembers: def.maxHouseholdMembers,
      aiScansPerMonth: def.aiScansPerMonth,
      aiScansUsedThisMonth: usage.aiScansUsedThisMonth,
      weekPlanning: true,
      advancedNutrition: true,
      communityPublish: true,
      expiresAt: trial.endsAt.toISOString(),
    };
  }

  // 3. Gratisnivå: användbar men begränsad (spec §46).
  const free = PLAN_DEFINITIONS.free;
  return {
    plan: "free",
    status: "free",
    maxHouseholdMembers: free.maxHouseholdMembers,
    aiScansPerMonth: free.aiScansPerMonth,
    aiScansUsedThisMonth: usage.aiScansUsedThisMonth,
    weekPlanning: free.weekPlanning,
    advancedNutrition: free.advancedNutrition,
    communityPublish: free.communityPublish,
  };
}

export function trialEndsAt(startedAt: Date): Date {
  return new Date(startedAt.getTime() + TRIAL_DAYS * 86_400_000);
}

/** Har användaren AI-skanningar kvar denna månad? (fair use, spec §45) */
export function canUseAiScan(entitlements: Entitlements): boolean {
  return entitlements.aiScansUsedThisMonth < entitlements.aiScansPerMonth;
}

export function resolvePlanFromProductId(productId: string): SubscriptionPlan | null {
  for (const def of Object.values(PLAN_DEFINITIONS)) {
    if (def.appleProductId === productId || def.googleProductId === productId) return def.plan;
  }
  return null;
}
