import { useMutation, useQuery } from "@tanstack/react-query";
import { useState } from "react";

import { api } from "@/services/api";
import {
  paymentsService,
  type PaymentMethod,
} from "@/services/payments.service";
import { invoicesService } from "@/services/invoices.service";
import { isPayable } from "@/pages/billing/invoice-ui";

/**
 * Shared payment flow for a single booking: opens the method modal, fires
 * POST /billing/my-invoices/:id/pay for the booking's currently payable
 * invoice, and redirects the browser to the provider (or the fallback
 * checkout page). Reused by the booking detail page, the booking list, and
 * the home page so "Pay now" behaves identically everywhere.
 */
export function useBookingPayment(bookingId: string) {
  const [modalOpen, setModalOpen] = useState(false);

  const { data: invoices = [] } = useQuery({
    queryKey: ["booking-invoices", bookingId],
    queryFn: () => invoicesService.listForSource("booking", bookingId),
  });
  const payableInvoiceId = invoices.find((inv) => isPayable(inv.status))?.id;

  const mutation = useMutation({
    mutationFn: (method: PaymentMethod) => {
      if (!payableInvoiceId) {
        throw new Error(
          "No payable invoice found for this booking yet. Please refresh or contact support.",
        );
      }
      return api.invoices.pay.call({
        id: payableInvoiceId,
        payload: { method, platform: "web" },
      });
    },
    onSuccess: (data, method) => {
      const redirectUrl =
        data?.clientAction?.type === "REDIRECT" && data.clientAction.url
          ? data.clientAction.url
          : paymentsService.checkoutUrlForInvoice({
              invoiceId: payableInvoiceId!,
              method,
            });
      window.location.href = redirectUrl;
    },
  });

  const open = () => setModalOpen(true);

  const close = () => {
    if (!mutation.isPending) {
      setModalOpen(false);
      mutation.reset();
    }
  };

  const error = mutation.isError
    ? mutation.error instanceof Error
      ? mutation.error.message
      : "Could not start payment. Please try again."
    : null;

  return {
    modalOpen,
    open,
    close,
    processing: mutation.isPending,
    error,
    confirm: (method: PaymentMethod) => mutation.mutate(method),
  };
}
