/**
 * Payment Hooks
 * TanStack Query hooks for payment operations
 * Epic: OQI-005 Pagos y Stripe
 */

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { paymentService } from '../services/payment.service';
import type { RefundRequest } from '../types/payment.types';

// Query Keys
export const paymentKeys = {
  all: ['payments'] as const,
  invoices: () => [...paymentKeys.all, 'invoices'] as const,
  invoicesList: (limit: number, offset: number) => [...paymentKeys.invoices(), { limit, offset }] as const,
  invoice: (id: string) => [...paymentKeys.invoices(), id] as const,
  paymentMethods: () => [...paymentKeys.all, 'payment-methods'] as const,
  refunds: () => [...paymentKeys.all, 'refunds'] as const,
  refundsList: (limit: number, offset: number, status?: string) =>
    [...paymentKeys.refunds(), { limit, offset, status }] as const,
  refund: (id: string) => [...paymentKeys.refunds(), id] as const,
  refundEligibility: (subscriptionId: string) =>
    [...paymentKeys.refunds(), 'eligibility', subscriptionId] as const,
};

// ============================================================================
// Invoice Hooks
// ============================================================================

export interface UseInvoicesOptions {
  limit?: number;
  offset?: number;
  enabled?: boolean;
}

export function useInvoices(options: UseInvoicesOptions = {}) {
  const { limit = 20, offset = 0, enabled = true } = options;

  return useQuery({
    queryKey: paymentKeys.invoicesList(limit, offset),
    queryFn: () => paymentService.getInvoices(limit, offset),
    enabled,
    staleTime: 30000, // 30 seconds
  });
}

export function useInvoice(invoiceId: string | undefined) {
  return useQuery({
    queryKey: paymentKeys.invoice(invoiceId ?? ''),
    queryFn: () => paymentService.getInvoiceById(invoiceId!),
    enabled: !!invoiceId,
    staleTime: 60000, // 1 minute
  });
}

export function useDownloadInvoice() {
  return useMutation({
    mutationFn: async (invoiceId: string) => {
      const blob = await paymentService.downloadInvoice(invoiceId);
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `invoice-${invoiceId}.pdf`;
      document.body.appendChild(a);
      a.click();
      window.URL.revokeObjectURL(url);
      document.body.removeChild(a);
      return true;
    },
  });
}

// ============================================================================
// Payment Methods Hooks
// ============================================================================

export function usePaymentMethods(enabled = true) {
  return useQuery({
    queryKey: paymentKeys.paymentMethods(),
    queryFn: () => paymentService.getPaymentMethods(),
    enabled,
    staleTime: 60000, // 1 minute
  });
}

export function useAddPaymentMethod() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (paymentMethodId: string) => paymentService.addPaymentMethod(paymentMethodId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: paymentKeys.paymentMethods() });
    },
  });
}

export function useRemovePaymentMethod() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (paymentMethodId: string) => paymentService.removePaymentMethod(paymentMethodId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: paymentKeys.paymentMethods() });
    },
  });
}

export function useSetDefaultPaymentMethod() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (paymentMethodId: string) => paymentService.setDefaultPaymentMethod(paymentMethodId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: paymentKeys.paymentMethods() });
    },
  });
}

// ============================================================================
// Refund Hooks
// ============================================================================

export interface UseRefundsOptions {
  limit?: number;
  offset?: number;
  status?: string;
  enabled?: boolean;
}

export function useRefunds(options: UseRefundsOptions = {}) {
  const { limit = 20, offset = 0, status, enabled = true } = options;

  return useQuery({
    queryKey: paymentKeys.refundsList(limit, offset, status),
    queryFn: () => paymentService.getRefunds(limit, offset, status),
    enabled,
    staleTime: 30000, // 30 seconds
  });
}

export function useRefund(refundId: string | undefined) {
  return useQuery({
    queryKey: paymentKeys.refund(refundId ?? ''),
    queryFn: () => paymentService.getRefundById(refundId!),
    enabled: !!refundId,
    staleTime: 60000, // 1 minute
  });
}

export function useRefundEligibility(subscriptionId: string | undefined) {
  return useQuery({
    queryKey: paymentKeys.refundEligibility(subscriptionId ?? ''),
    queryFn: () => paymentService.getRefundEligibility(subscriptionId!),
    enabled: !!subscriptionId,
    staleTime: 60000, // 1 minute
  });
}

export function useRequestRefund() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (request: RefundRequest) => paymentService.requestRefund(request),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: paymentKeys.refunds() });
    },
  });
}

export function useCancelRefund() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (refundId: string) => paymentService.cancelRefund(refundId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: paymentKeys.refunds() });
    },
  });
}

// ============================================================================
// Combined Hook for Billing Page
// ============================================================================

export function useBillingData() {
  const invoicesQuery = useInvoices({ limit: 5 });
  const paymentMethodsQuery = usePaymentMethods();
  const refundsQuery = useRefunds({ limit: 5 });

  return {
    invoices: invoicesQuery.data?.invoices ?? [],
    paymentMethods: paymentMethodsQuery.data ?? [],
    refunds: refundsQuery.data?.refunds ?? [],
    isLoading:
      invoicesQuery.isLoading || paymentMethodsQuery.isLoading || refundsQuery.isLoading,
    error: invoicesQuery.error || paymentMethodsQuery.error || refundsQuery.error,
    refetch: () => {
      invoicesQuery.refetch();
      paymentMethodsQuery.refetch();
      refundsQuery.refetch();
    },
  };
}

export default {
  useInvoices,
  useInvoice,
  useDownloadInvoice,
  usePaymentMethods,
  useAddPaymentMethod,
  useRemovePaymentMethod,
  useSetDefaultPaymentMethod,
  useRefunds,
  useRefund,
  useRefundEligibility,
  useRequestRefund,
  useCancelRefund,
  useBillingData,
};
