import type {
  EffectiveOrganizationBilling,
  BillingCycle,
  BillingAdjustmentType,
  BillingPlan,
  OrganizationBilling,
  OrganizationBillingAdjustment,
  OrganizationMember,
  SubscriptionStatus,
} from "@/types";

export const BILLING_PLAN_OPTIONS: Array<{
  value: BillingPlan;
  label: string;
  includedSeats: number;
  monthlyPriceCents: number;
}> = [
  { value: "starter", label: "Starter", includedSeats: 5, monthlyPriceCents: 2900 },
  { value: "growth", label: "Growth", includedSeats: 15, monthlyPriceCents: 8900 },
  { value: "enterprise", label: "Enterprise", includedSeats: 50, monthlyPriceCents: 24900 },
];

export const BILLING_CYCLE_OPTIONS: Array<{ value: BillingCycle; label: string }> = [
  { value: "monthly", label: "Monthly" },
  { value: "yearly", label: "Yearly" },
];

export const SUBSCRIPTION_STATUS_OPTIONS: Array<{
  value: SubscriptionStatus;
  label: string;
}> = [
  { value: "trialing", label: "Trialing" },
  { value: "active", label: "Active" },
  { value: "past_due", label: "Past due" },
  { value: "paused", label: "Paused" },
  { value: "cancelled", label: "Cancelled" },
];

export function calculateSeatUsage(
  members: OrganizationMember[],
  billing: OrganizationBilling | null
) {
  const activeBillableSeats = members.filter(
    (member) => member.counts_toward_seat && member.seat_status === "active"
  ).length;
  const suspendedSeats = members.filter((member) => member.seat_status === "suspended").length;
  const excludedSeats = members.filter((member) => !member.counts_toward_seat).length;
  const seatCapacity = (billing?.included_seats || 0) + (billing?.purchased_seats || 0);
  const availableSeats = Math.max(seatCapacity - activeBillableSeats, 0);
  const overage = Math.max(activeBillableSeats - seatCapacity, 0);

  return {
    activeBillableSeats,
    suspendedSeats,
    excludedSeats,
    seatCapacity,
    availableSeats,
    overage,
    usageRatio:
      seatCapacity > 0 ? Math.min(activeBillableSeats / seatCapacity, 1) : 0,
  };
}

export function formatCurrency(cents: number, cycle?: BillingCycle) {
  const price = new Intl.NumberFormat(undefined, {
    style: "currency",
    currency: "USD",
    maximumFractionDigits: 0,
  }).format(cents / 100);

  return cycle ? `${price}/${cycle === "yearly" ? "yr" : "mo"}` : price;
}

export function toDateTimeLocalValue(value: string | null) {
  if (!value) return "";

  const date = new Date(value);
  const offset = date.getTimezoneOffset();
  const shifted = new Date(date.getTime() - offset * 60 * 1000);
  return shifted.toISOString().slice(0, 16);
}

function isAdjustmentActive(
  adjustment: OrganizationBillingAdjustment,
  now = new Date()
) {
  if (!adjustment.is_active || adjustment.revoked_at) return false;
  const startsAt = new Date(adjustment.starts_at);
  if (Number.isNaN(startsAt.getTime()) || startsAt > now) return false;
  if (!adjustment.ends_at) return true;
  const endsAt = new Date(adjustment.ends_at);
  return !Number.isNaN(endsAt.getTime()) && endsAt >= now;
}

export function getAdjustmentLabel(type: BillingAdjustmentType) {
  switch (type) {
    case "trial_extension_days":
      return "Trial extension";
    case "complimentary_period":
      return "Complimentary period";
    case "seat_grant":
      return "Seat grant";
    case "price_override":
      return "Price override";
    case "discount_percent":
      return "Percent discount";
    case "discount_fixed":
      return "Fixed discount";
    case "manual_status_override":
      return "Status override";
    default:
      return "Adjustment";
  }
}

export function describeAdjustment(adjustment: OrganizationBillingAdjustment) {
  if (adjustment.type === "trial_extension_days") {
    return `${adjustment.amount || 0} extra trial days`;
  }
  if (adjustment.type === "complimentary_period") {
    return `${adjustment.amount || 0} complimentary days`;
  }
  if (adjustment.type === "seat_grant") {
    return `+${adjustment.amount || 0} seats`;
  }
  if (adjustment.type === "price_override") {
    return formatCurrency(adjustment.amount || 0);
  }
  if (adjustment.type === "discount_percent") {
    return `${adjustment.amount || 0}% off`;
  }
  if (adjustment.type === "discount_fixed") {
    return `${formatCurrency(adjustment.amount || 0)} off`;
  }
  if (adjustment.type === "manual_status_override") {
    return adjustment.text_value || "Override";
  }
  return adjustment.note || "Adjustment";
}

export function calculateEffectiveBilling(
  billing: OrganizationBilling | null,
  adjustments: OrganizationBillingAdjustment[],
  now = new Date()
): EffectiveOrganizationBilling | null {
  if (!billing) return null;

  const activeAdjustments = adjustments.filter((adjustment) => isAdjustmentActive(adjustment, now));
  const seatGrantCount = activeAdjustments
    .filter((adjustment) => adjustment.type === "seat_grant")
    .reduce((sum, adjustment) => sum + Math.max(0, adjustment.amount || 0), 0);
  const discountPercent = activeAdjustments
    .filter((adjustment) => adjustment.type === "discount_percent")
    .reduce((max, adjustment) => Math.max(max, Math.max(0, adjustment.amount || 0)), 0);
  const discountFixedCents = activeAdjustments
    .filter((adjustment) => adjustment.type === "discount_fixed")
    .reduce((sum, adjustment) => sum + Math.max(0, adjustment.amount || 0), 0);
  const priceOverrideCents =
    activeAdjustments
      .filter((adjustment) => adjustment.type === "price_override" && typeof adjustment.amount === "number")
      .sort((left, right) => +new Date(right.created_at) - +new Date(left.created_at))[0]?.amount ?? null;
  const trialExtensionDays = activeAdjustments
    .filter((adjustment) => adjustment.type === "trial_extension_days")
    .reduce((sum, adjustment) => sum + Math.max(0, adjustment.amount || 0), 0);
  const manualStatusOverride =
    (activeAdjustments
      .filter(
        (adjustment) =>
          adjustment.type === "manual_status_override" &&
          typeof adjustment.text_value === "string"
      )
      .sort((left, right) => +new Date(right.created_at) - +new Date(left.created_at))[0]
      ?.text_value as SubscriptionStatus | undefined) ?? null;
  const complimentaryAdjustments = activeAdjustments.filter(
    (adjustment) => adjustment.type === "complimentary_period"
  );
  const complimentaryUntil =
    complimentaryAdjustments
      .map((adjustment) => adjustment.ends_at)
      .filter((value): value is string => Boolean(value))
      .sort()
      .slice(-1)[0] || null;
  const isComplimentaryActive = Boolean(
    complimentaryUntil && new Date(complimentaryUntil).getTime() >= now.getTime()
  );

  const basePrice = priceOverrideCents ?? billing.monthly_price_cents;
  const discountedPrice = Math.max(
    0,
    Math.round(basePrice * (1 - discountPercent / 100)) - discountFixedCents
  );
  const effectiveMonthlyPriceCents = isComplimentaryActive ? 0 : discountedPrice;
  const effectiveSeatCapacity =
    (billing.included_seats || 0) + (billing.purchased_seats || 0) + seatGrantCount;

  let effectiveRenewsAt = billing.renews_at;
  if (billing.renews_at && trialExtensionDays > 0) {
    const renewDate = new Date(billing.renews_at);
    renewDate.setDate(renewDate.getDate() + trialExtensionDays);
    effectiveRenewsAt = renewDate.toISOString();
  }
  if (
    complimentaryUntil &&
    (!effectiveRenewsAt || new Date(complimentaryUntil).getTime() > new Date(effectiveRenewsAt).getTime())
  ) {
    effectiveRenewsAt = complimentaryUntil;
  }

  const effectiveStatus = manualStatusOverride || billing.subscription_status;

  return {
    base: billing,
    activeAdjustments,
    effectiveStatus,
    effectiveMonthlyPriceCents,
    effectiveSeatCapacity,
    seatGrantCount,
    discountPercent,
    discountFixedCents,
    priceOverrideCents,
    complimentaryUntil,
    trialExtensionDays,
    effectiveRenewsAt,
    nextChargeAt: effectiveStatus === "cancelled" ? null : effectiveRenewsAt,
    manualStatusOverride,
    isComplimentaryActive,
  };
}
