"use client";

import {
  useMutation,
  useQuery,
  type UseMutationOptions,
  type UseMutationResult,
  type UseQueryOptions,
  type UseQueryResult,
} from "@tanstack/react-query";

import { queryKeys } from "@/core/api";

import {
  type Invoice,
  type InvoiceList,
  type InvoiceSsoLink,
  type InvoiceQueryParams,
} from "@customer-portal/domain/billing";

import { type PaymentMethodList } from "@customer-portal/domain/payments";
import { useAuthSession } from "@/features/auth/stores/auth.store";
import { billingService } from "../api/billing.api";

// Type helpers for React Query
type InvoicesQueryKey = ReturnType<typeof queryKeys.billing.invoices>;
type InvoiceQueryKey = ReturnType<typeof queryKeys.billing.invoice>;
type PaymentMethodsQueryKey = ReturnType<typeof queryKeys.billing.paymentMethods>;

type InvoicesQueryOptions = Omit<
  UseQueryOptions<InvoiceList, Error, InvoiceList, InvoicesQueryKey>,
  "queryKey" | "queryFn"
>;

type InvoiceQueryOptions = Omit<
  UseQueryOptions<Invoice, Error, Invoice, InvoiceQueryKey>,
  "queryKey" | "queryFn"
>;

type PaymentMethodsQueryOptions = Omit<
  UseQueryOptions<PaymentMethodList, Error, PaymentMethodList, PaymentMethodsQueryKey>,
  "queryKey" | "queryFn"
>;

type SsoLinkMutationOptions = UseMutationOptions<
  InvoiceSsoLink,
  Error,
  { invoiceId: number; target?: "view" | "download" | "pay" }
>;

// Exported hooks
export function useInvoices(
  params?: InvoiceQueryParams,
  options?: InvoicesQueryOptions
): UseQueryResult<InvoiceList, Error> {
  const { isAuthenticated } = useAuthSession();
  const queryKeyParams = params ? { ...params } : undefined;
  return useQuery({
    queryKey: queryKeys.billing.invoices(queryKeyParams),
    queryFn: () => billingService.getInvoices(params),
    enabled: isAuthenticated,
    ...options,
  });
}

export function useInvoice(
  id: string,
  options?: InvoiceQueryOptions
): UseQueryResult<Invoice, Error> {
  const { isAuthenticated } = useAuthSession();
  return useQuery({
    queryKey: queryKeys.billing.invoice(id),
    queryFn: () => billingService.getInvoice(id),
    enabled: isAuthenticated && Boolean(id),
    ...options,
  });
}

export function usePaymentMethods(
  options?: PaymentMethodsQueryOptions
): UseQueryResult<PaymentMethodList, Error> {
  const { isAuthenticated } = useAuthSession();
  return useQuery({
    queryKey: queryKeys.billing.paymentMethods(),
    queryFn: billingService.getPaymentMethods,
    enabled: isAuthenticated,
    ...options,
  });
}

export function useCreateInvoiceSsoLink(
  options?: SsoLinkMutationOptions
): UseMutationResult<
  InvoiceSsoLink,
  Error,
  { invoiceId: number; target?: "view" | "download" | "pay" }
> {
  return useMutation({
    mutationFn: async ({ invoiceId, target }) => {
      return billingService.createInvoiceSsoLink(invoiceId, target);
    },
    ...options,
  });
}

export function useCreatePaymentMethodsSsoLink(
  options?: UseMutationOptions<InvoiceSsoLink, Error, void>
): UseMutationResult<InvoiceSsoLink, Error, void> {
  return useMutation({
    mutationFn: billingService.createPaymentMethodsSsoLink,
    ...options,
  });
}
