import { BaseApiClient } from '../base/BaseApiClient';
import type { MembershipFeeDTO } from '../../types/generated/MembershipFeeDTO';
import type { MemberPaymentDTO } from '../../types/generated/MemberPaymentDTO';
import type { PaymentDTO } from '../../types/generated/PaymentDTO';
import type { PrizeDTO } from '../../types/generated/PrizeDTO';
import type { TransactionDTO } from '../../types/generated/TransactionDTO';
import type { UpdatePaymentStatusInputDTO } from '../../types/generated/UpdatePaymentStatusInputDTO';
import type { WalletDTO } from '../../types/generated/WalletDTO';

// Define missing types that are not fully generated
type GetPaymentsOutputDto = { payments: PaymentDTO[] };
type CreatePaymentInputDto = {
  type: 'sponsorship' | 'membership_fee';
  amount: number;
  payerId: string;
  payerType: 'sponsor' | 'driver';
  leagueId: string;
  seasonId?: string;
};
type CreatePaymentOutputDto = { payment: PaymentDTO };
type GetMembershipFeesOutputDto = {
  fee: MembershipFeeDTO | null;
  payments: MemberPaymentDTO[]
};
type GetPrizesOutputDto = { prizes: PrizeDTO[] };
type GetWalletOutputDto = {
  wallet: WalletDTO;
  transactions: TransactionDTO[]
};
type ProcessWalletTransactionInputDto = {
  leagueId: string;
  type: 'deposit' | 'withdrawal' | 'platform_fee';
  amount: number;
  description: string;
  referenceId?: string;
  referenceType?: 'sponsorship' | 'membership_fee' | 'prize';
};
type ProcessWalletTransactionOutputDto = {
  wallet: WalletDTO;
  transaction: TransactionDTO
};
type UpdateMemberPaymentInputDto = {
  feeId: string;
  driverId: string;
  status?: 'pending' | 'paid' | 'overdue';
  paidAt?: Date | string;
};
type UpdateMemberPaymentOutputDto = { payment: MemberPaymentDTO };
type UpdatePaymentStatusOutputDto = { payment: PaymentDTO };
type UpsertMembershipFeeInputDto = {
  leagueId: string;
  seasonId?: string;
  type: 'season' | 'monthly' | 'per_race';
  amount: number;
};
type UpsertMembershipFeeOutputDto = { fee: MembershipFeeDTO };
type CreatePrizeInputDto = {
  leagueId: string;
  seasonId: string;
  position: number;
  name: string;
  amount: number;
  type: 'cash' | 'merchandise' | 'other';
  description?: string;
};
type CreatePrizeOutputDto = { prize: PrizeDTO };
type AwardPrizeInputDto = {
  prizeId: string;
  driverId: string;
};
type AwardPrizeOutputDto = { prize: PrizeDTO };
type DeletePrizeOutputDto = { success: boolean };

/**
 * Payments API Client
 *
 * Handles all payment-related API operations.
 */
export class PaymentsApiClient extends BaseApiClient {
  /** Get payments */
  getPayments(query?: { leagueId?: string; payerId?: string; type?: 'sponsorship' | 'membership_fee'; status?: 'pending' | 'completed' | 'failed' | 'refunded' }): Promise<GetPaymentsOutputDto> {
    const params = new URLSearchParams();
    if (query?.leagueId) params.append('leagueId', query.leagueId);
    if (query?.payerId) params.append('payerId', query.payerId);
    if (query?.type) params.append('type', query.type);
    if (query?.status) params.append('status', query.status);
    const queryString = params.toString();
    return this.get<GetPaymentsOutputDto>(`/payments${queryString ? `?${queryString}` : ''}`);
  }

  /** Create a payment */
  createPayment(input: CreatePaymentInputDto): Promise<CreatePaymentOutputDto> {
    return this.post<CreatePaymentOutputDto>('/payments', input);
  }

  /** Get membership fees */
  getMembershipFees(query: { leagueId: string; driverId?: string }): Promise<GetMembershipFeesOutputDto> {
    const params = new URLSearchParams();
    params.append('leagueId', query.leagueId);
    if (query.driverId) params.append('driverId', query.driverId);
    const queryString = params.toString();
    return this.get<GetMembershipFeesOutputDto>(`/payments/membership-fees?${queryString}`);
  }

  /** Get prizes */
  getPrizes(query?: { leagueId?: string; seasonId?: string }): Promise<GetPrizesOutputDto> {
    const params = new URLSearchParams();
    if (query?.leagueId) params.append('leagueId', query.leagueId);
    if (query?.seasonId) params.append('seasonId', query.seasonId);
    const queryString = params.toString();
    return this.get<GetPrizesOutputDto>(`/payments/prizes${queryString ? `?${queryString}` : ''}`);
  }

  /** Get wallet */
  getWallet(query?: { leagueId?: string }): Promise<GetWalletOutputDto> {
    const params = new URLSearchParams();
    if (query?.leagueId) params.append('leagueId', query.leagueId);
    const queryString = params.toString();
    return this.get<GetWalletOutputDto>(`/payments/wallets${queryString ? `?${queryString}` : ''}`);
  }

  /** Update payment status */
  updatePaymentStatus(input: UpdatePaymentStatusInputDTO): Promise<UpdatePaymentStatusOutputDto> {
    return this.patch<UpdatePaymentStatusOutputDto>('/payments/status', input);
  }

  /** Upsert membership fee */
  upsertMembershipFee(input: UpsertMembershipFeeInputDto): Promise<UpsertMembershipFeeOutputDto> {
    return this.post<UpsertMembershipFeeOutputDto>('/payments/membership-fees', input);
  }

  /** Update member payment */
  updateMemberPayment(input: UpdateMemberPaymentInputDto): Promise<UpdateMemberPaymentOutputDto> {
    return this.patch<UpdateMemberPaymentOutputDto>('/payments/membership-fees/member-payment', input);
  }

  /** Create prize */
  createPrize(input: CreatePrizeInputDto): Promise<CreatePrizeOutputDto> {
    return this.post<CreatePrizeOutputDto>('/payments/prizes', input);
  }

  /** Award prize */
  awardPrize(input: AwardPrizeInputDto): Promise<AwardPrizeOutputDto> {
    return this.patch<AwardPrizeOutputDto>('/payments/prizes/award', input);
  }

  /** Delete prize */
  deletePrize(prizeId: string): Promise<DeletePrizeOutputDto> {
    return this.delete<DeletePrizeOutputDto>(`/payments/prizes?prizeId=${prizeId}`);
  }

  /** Process wallet transaction */
  processWalletTransaction(input: ProcessWalletTransactionInputDto): Promise<ProcessWalletTransactionOutputDto> {
    return this.post<ProcessWalletTransactionOutputDto>('/payments/wallets/transactions', input);
  }
}
