import type { DealType } from '@/lib/deal-types';
import { isBusinessDay } from '@/server/calendar/il-business-days';

export type CancellationReason = 'defect' | 'consumer_remorse';

export const STATUTORY_CANCELLATION_WINDOW_DAYS = 14;
export const STATUTORY_CANCELLATION_FEE_CAP_AGOROT = 10_000;

export interface StatutoryRefundInput {
  dealType: DealType;
  amountPaidAgorot: number;
  purchasedAt: Date;
  deliveredAt: Date | null;
  serviceDate: Date | null;
  cancelledAt: Date;
  reason: CancellationReason;
  exempt: boolean;
  redeemedAt: Date | null;
}

export interface StatutoryRefundResult {
  eligible: boolean;
  refundAgorot: number;
  feeAgorot: number;
  platformFeeAgorot: number;
  vendorFeeAgorot: number;
  rule: string;
}

function inCancellationWindow(anchor: Date, cancelledAt: Date): boolean {
  const anchorDay = Date.UTC(anchor.getUTCFullYear(), anchor.getUTCMonth(), anchor.getUTCDate());
  const cancelledDay = Date.UTC(
    cancelledAt.getUTCFullYear(),
    cancelledAt.getUTCMonth(),
    cancelledAt.getUTCDate(),
  );
  const elapsedDays = (cancelledDay - anchorDay) / 86_400_000;
  return elapsedDays >= 0 && elapsedDays <= STATUTORY_CANCELLATION_WINDOW_DAYS;
}

function businessDaysBetween(start: Date, end: Date): number {
  if (end <= start) return 0;

  const cursor = new Date(
    Date.UTC(start.getUTCFullYear(), start.getUTCMonth(), start.getUTCDate()),
  );
  const endDay = new Date(Date.UTC(end.getUTCFullYear(), end.getUTCMonth(), end.getUTCDate()));
  let count = 0;

  while (cursor < endDay) {
    if (isBusinessDay(cursor)) count++;
    cursor.setUTCDate(cursor.getUTCDate() + 1);
  }

  return count;
}

function inServiceCancellationWindow(cancelledAt: Date, serviceDate: Date | null): boolean {
  return serviceDate === null || businessDaysBetween(cancelledAt, serviceDate) >= 2;
}

function ineligible(rule: string): StatutoryRefundResult {
  return {
    eligible: false,
    refundAgorot: 0,
    feeAgorot: 0,
    platformFeeAgorot: 0,
    vendorFeeAgorot: 0,
    rule,
  };
}

export function statutoryRefund(input: StatutoryRefundInput): StatutoryRefundResult {
  if (input.exempt) return ineligible('IL-5771-exempt');
  if (input.reason === 'consumer_remorse' && input.redeemedAt !== null) {
    return ineligible('redeemed-voucher');
  }

  const isItem = input.dealType === 'ITEM';
  const rule =
    input.reason === 'defect'
      ? 'IL-14E-defect'
      : isItem
        ? 'IL-14C-goods-14d'
        : 'IL-14C-service-14d';
  const anchor = isItem ? input.deliveredAt : input.purchasedAt;

  if (anchor !== null && !inCancellationWindow(anchor, input.cancelledAt)) {
    return ineligible(`${rule}-expired`);
  }
  if (!isItem && !inServiceCancellationWindow(input.cancelledAt, input.serviceDate)) {
    return ineligible('IL-14C-service-2-business-days');
  }

  const feeAgorot =
    input.reason === 'defect'
      ? 0
      : Math.min(Math.round(input.amountPaidAgorot * 0.05), STATUTORY_CANCELLATION_FEE_CAP_AGOROT);
  const platformFeeAgorot = Math.ceil(feeAgorot / 2);

  return {
    eligible: true,
    refundAgorot: input.amountPaidAgorot - feeAgorot,
    feeAgorot,
    platformFeeAgorot,
    vendorFeeAgorot: feeAgorot - platformFeeAgorot,
    rule,
  };
}
