import api, { authorizeApi } from './api';
import {
  PaymentTransaction,
  CreditCard,
  AuthorizeTransaction,
  TransactionListResponse,
  CardListResponse,
  CreateCardRequest,
  PaymentRequest,
  AxiosResponse,
  TokenizeCardRequest,
  UpdateTokenizedCardRequest,
  ChargeSavedCardRequest,
  ChargeDirectRequest,
  CaptureRequest,
  PreauthorizeSavedCardRequest,
  AuthorizeNetTransactionResponse,
  CardResponse,
  CardsResponse
} from '../types/models';

export const paymentService = {
  // Card management (Main API)
  getCard: (id: number): Promise<AxiosResponse<CardResponse>> =>
    api.get(`/payment/card/${id}`),

  getCards: (customerId: number): Promise<AxiosResponse<CardsResponse>> =>
    api.get(`/payment/cards/${customerId}`),

  getCardsOnFile: (customerId: number): Promise<AxiosResponse<CardsResponse>> =>
    api.get(`/payment/cards/onfile/${customerId}`),

  getAllCards: (page: number = 1): Promise<AxiosResponse<CardListResponse>> =>
    api.get(`/payment/cards/all/${page}`),

  createCard: (customerId: number, data: CreateCardRequest): Promise<AxiosResponse<CardResponse>> =>
    api.post(`/payment/card/create/${customerId}`, data),

  updateCard: (id: number, data: Partial<CreditCard>): Promise<AxiosResponse<CardResponse>> =>
    api.put(`/payment/card/edit/${id}`, data),

  removeCard: (id: number): Promise<AxiosResponse<{ ok: boolean }>> =>
    api.delete(`/payment/card/remove/${id}`),

  removeCardAlt: (id: number): Promise<AxiosResponse<{ ok: boolean }>> =>
    api.delete(`/payment/cards/remove/${id}`),

  updatePaymentProfile: (id: number, data: { auth_net_payment_profile_id: string }): Promise<AxiosResponse<{ ok: boolean }>> =>
    api.put(`/payment/card/update_payment_profile/${id}`, data),

  // Authorization & capture (Main API)
  authorizeDelivery: (id: number, data: PaymentRequest): Promise<AxiosResponse<PaymentTransaction & { ok: boolean }>> =>
    api.put(`/payment/authorize/${id}`, data),

  authorizeService: (id: number, data: PaymentRequest): Promise<AxiosResponse<PaymentTransaction & { ok: boolean }>> =>
    api.put(`/payment/authorize/service/${id}`, data),

  cleanupAuthorization: (id: number): Promise<AxiosResponse<{ ok: boolean; message?: string; error?: string }>> =>
    api.put(`/payment/authorize/cleanup/${id}`),

  captureServicePayment: (id: number, data: { amount: number }): Promise<AxiosResponse<PaymentTransaction & { ok: boolean }>> =>
    api.put(`/payment/capture/service/${id}`, data),

  // Service payment
  getServicePayment: (id: number, type: string): Promise<AxiosResponse<{ amount: number; ok: boolean }>> =>
    api.get(`/payment/service/payment/${id}/${type}`),

  // Transactions
  getDeliveryTransaction: (id: number): Promise<AxiosResponse<PaymentTransaction & { ok: boolean }>> =>
    api.get(`/payment/transaction/delivery/${id}`),

  getAuthorizeTransactions: (): Promise<AxiosResponse<AuthorizeTransaction[] & { ok: boolean }>> =>
    api.get('/payment/transactions/authorize/1'),

  getCustomerTransactions: (customerId: number, page: number = 1): Promise<AxiosResponse<TransactionListResponse>> =>
    api.get(`/payment/transactions/customer/${customerId}/${page}`),

  getServiceTransactions: (serviceId: number): Promise<AxiosResponse<PaymentTransaction[] & { ok: boolean }>> =>
    api.get(`/payment/transactions/service/${serviceId}`),

  // Authorize.net endpoints
  authorize: {
    tokenizeCard: (customerId: number, data: TokenizeCardRequest): Promise<AxiosResponse<CardResponse>> =>
      authorizeApi.post(`/api/payments/customers/${customerId}/cards`, data),

    updateTokenizedCard: (customerId: number, cardId: number, data: UpdateTokenizedCardRequest): Promise<AxiosResponse<CardResponse>> =>
      authorizeApi.put(`/api/payments/customers/${customerId}/cards/${cardId}`, data),

    authorizeSavedCard: (customerId: number, data: PreauthorizeSavedCardRequest): Promise<AxiosResponse<AuthorizeNetTransactionResponse & { ok: boolean }>> =>
      authorizeApi.post(`/api/payments/authorize/saved-card/${customerId}`, data),

    chargeSavedCard: (customerId: number, data: ChargeSavedCardRequest): Promise<AxiosResponse<AuthorizeNetTransactionResponse & { ok: boolean }>> =>
      authorizeApi.post(`/api/payments/charge/saved-card/${customerId}`, data),

    charge: (customerId: number, data: ChargeDirectRequest): Promise<AxiosResponse<AuthorizeNetTransactionResponse & { ok: boolean }>> =>
      authorizeApi.post(`/api/charge/${customerId}`, data),

    capture: (data: CaptureRequest): Promise<AxiosResponse<AuthorizeNetTransactionResponse & { ok: boolean }>> =>
      authorizeApi.post('/api/payments/capture', data),

    // Auto transaction endpoints
    getAutoTransaction: (deliveryId: number): Promise<AxiosResponse<AuthorizeNetTransactionResponse & { ok: boolean }>> =>
      authorizeApi.get(`/api/auto/transaction/delivery/${deliveryId}`),

    updateAutoTransactionId: (deliveryId: number, newId: number, data?: Record<string, unknown>): Promise<AxiosResponse<{ ok: boolean }>> =>
      authorizeApi.put(`/api/auto/transaction/delivery/${deliveryId}/update/${newId}`, data ?? {}),

    linkTransactionToAuto: (transactionId: number, autoId: number, data?: Record<string, unknown>): Promise<AxiosResponse<{ ok: boolean }>> =>
      authorizeApi.put(`/api/transaction/${transactionId}/update_auto_id/${autoId}`, data ?? {}),

    // Check authorize account status
    checkAccount: (customerId: number): Promise<AxiosResponse<{ profile_exists: boolean; has_payment_methods: boolean; missing_components: string[]; valid_for_charging: boolean }>> =>
      authorizeApi.get(`/user/check-authorize-account/${customerId}`),
  },

  // Convenience wrappers for commonly used operations
  getCardById: (id: number): Promise<AxiosResponse<CardResponse>> =>
    api.get(`/payment/card/${id}`),

  checkAuthorizeAccount: (customerId: number): Promise<AxiosResponse<{ profile_exists: boolean; has_payment_methods: boolean; missing_components: string[]; valid_for_charging: boolean }>> =>
    authorizeApi.get(`/user/check-authorize-account/${customerId}`),

  createAuthorizeCard: (customerId: number, data: TokenizeCardRequest): Promise<AxiosResponse<CardResponse>> =>
    authorizeApi.post(`/api/payments/customers/${customerId}/cards`, data),

  updateAuthorizeCard: (customerId: number, cardId: number, data: UpdateTokenizedCardRequest): Promise<AxiosResponse<CardResponse>> =>
    authorizeApi.put(`/api/payments/customers/${customerId}/cards/${cardId}`, data),
};

export default paymentService;
