/**
 * Refund policy hardcoded untuk MVP (PR-R3). Akan jadi data-driven di PR-R5.
 *
 * Aturan: hitung persentase refund berdasarkan jarak hari ke tanggal berangkat
 * (UTC calendar day). Selalu integer rupiah — pakai Math.floor supaya tidak
 * ada sub-rupiah dan total refund tidak pernah melebihi nominal yang dibayar.
 *
 * Tier:
 * - ≥7 hari sebelum berangkat → 80% refund (organizer ambil 20% admin fee)
 * - 3–6 hari sebelum berangkat → 50% refund
 * - <3 hari sebelum berangkat / sudah lewat → 0% (tidak ada refund)
 */

import { utcStartOfDay } from "@/lib/trip-dates";

export interface RefundTier {
  /** Minimum jumlah hari sebelum berangkat untuk tier ini. */
  minDaysBefore: number;
  /** Persentase nominal yang di-refund (0–100). */
  refundPercentage: number;
  /** Label untuk UI. */
  label: string;
}

const TIERS: RefundTier[] = [
  { minDaysBefore: 7, refundPercentage: 80, label: "≥ 7 hari sebelum berangkat" },
  { minDaysBefore: 3, refundPercentage: 50, label: "3–6 hari sebelum berangkat" },
  { minDaysBefore: 0, refundPercentage: 0, label: "Kurang dari 3 hari / sudah lewat" },
];

export function getRefundPolicyTiers(): RefundTier[] {
  return TIERS;
}

/**
 * Jumlah hari kalender UTC dari sekarang ke tanggal berangkat. Negative kalau
 * tanggal sudah lewat. Pakai start-of-day UTC supaya jam tidak mempengaruhi.
 */
export function daysUntilDeparture(
  departureDate: Date,
  now: Date = new Date()
): number {
  const todayMs = utcStartOfDay(now).getTime();
  const depMs = utcStartOfDay(departureDate).getTime();
  const oneDayMs = 24 * 60 * 60 * 1000;
  return Math.floor((depMs - todayMs) / oneDayMs);
}

/** Tier aktif untuk jumlah hari yang diberikan. */
export function getTierForDays(days: number): RefundTier {
  for (const tier of TIERS) {
    if (days >= tier.minDaysBefore) {
      return tier;
    }
  }
  return TIERS[TIERS.length - 1];
}

/**
 * Hitung nominal refund (IDR integer) berdasarkan harga booking dan jarak ke
 * tanggal berangkat. Floor supaya tidak pernah > bookingAmount.
 */
export function calculateRefundAmount(
  bookingAmount: number,
  days: number
): number {
  if (bookingAmount <= 0) return 0;
  const tier = getTierForDays(days);
  return Math.floor((bookingAmount * tier.refundPercentage) / 100);
}

export interface RefundPreview {
  days: number;
  tier: RefundTier;
  refundAmount: number;
  bookingAmount: number;
}

/** Bundle lengkap untuk display di UI — preview cancel booking. */
export function previewRefund(
  bookingAmount: number,
  departureDate: Date,
  now: Date = new Date()
): RefundPreview {
  const days = daysUntilDeparture(departureDate, now);
  const tier = getTierForDays(days);
  return {
    days,
    tier,
    refundAmount: calculateRefundAmount(bookingAmount, days),
    bookingAmount,
  };
}
