import type { QueryClient } from '@tanstack/react-query';
import { bookingKeys } from '@/services/bookings/keys';
import { ticketKeys } from '@/services/tickets/keys';
import { refundKeys } from './keys';
import type { RefundSummary } from './types';

/**
 * The one cache transition a successful cancellation causes: the booking flipped `cancelled` and a refund
 * now exists. Prime the fresh refund into its `byBooking` key (so the refund-status screen renders warm,
 * no first-render spinner) and invalidate exactly the affected keys — the booking detail (its status/note
 * changed), the bookings lists (the row moved to cancelled), the policy preview (no longer cancellable),
 * and the refund's `byBooking` — never a blanket refetch. Called from `useCancelBooking`.
 */
export function invalidateAfterCancellation(
  queryClient: QueryClient,
  bookingId: number,
  refund: RefundSummary,
): void {
  queryClient.setQueryData(refundKeys.byBooking(bookingId), refund);
  queryClient.invalidateQueries({ queryKey: bookingKeys.bookingDetail(bookingId) });
  queryClient.invalidateQueries({ queryKey: bookingKeys.lists() });
  queryClient.invalidateQueries({ queryKey: refundKeys.policyPreview(bookingId) });
}

/**
 * After an admin **initiates** a refund (or approves a failed one): the booking's refund now exists / moved,
 * so refresh the customer-facing refund read (`byBooking`), the booking detail + lists (status/refund
 * changed), every admin decomposition preview (the booking is no longer previewable the same way), and the
 * linked support ticket if one was passed (the console posts the outcome onto the ticket). Never a blanket
 * refetch. Called from `useInitiateRefund` / `useApproveRefund`.
 */
export function invalidateAfterAdminRefund(
  queryClient: QueryClient,
  bookingId: number,
  ticketId?: number | null,
): void {
  queryClient.invalidateQueries({ queryKey: refundKeys.byBooking(bookingId) });
  queryClient.invalidateQueries({ queryKey: refundKeys.details() });
  queryClient.invalidateQueries({ queryKey: refundKeys.adminPreviews() });
  queryClient.invalidateQueries({ queryKey: bookingKeys.bookingDetail(bookingId) });
  queryClient.invalidateQueries({ queryKey: bookingKeys.lists() });
  if (ticketId != null) {
    queryClient.invalidateQueries({ queryKey: ticketKeys.detail(ticketId) });
  }
}

/**
 * After an admin **rejects** a refund. Reject returns no booking id, so we refresh the by-refund read and
 * the admin previews (the refund is now terminal `rejected`); the worklist re-reads it on next fetch.
 */
export function invalidateAfterRefundRejection(queryClient: QueryClient, refundId: number): void {
  queryClient.invalidateQueries({ queryKey: refundKeys.detail(refundId) });
  queryClient.invalidateQueries({ queryKey: refundKeys.adminPreviews() });
}
