import { MembershipFeeViewModel } from '@/lib/view-models/MembershipFeeViewModel';
import { PaymentViewModel } from '@/lib/view-models/PaymentViewModel';
import { PrizeViewModel } from '@/lib/view-models/PrizeViewModel';
import { WalletViewModel } from '@/lib/view-models/WalletViewModel';
import type { PaymentsApiClient } from '../../api/payments/PaymentsApiClient';
import type { PaymentDTO } from '../../types/generated/PaymentDTO';
import type { PrizeDTO } from '../../types/generated/PrizeDTO';

// Local payment creation request matching the Payments API contract until a shared generated type is introduced
type CreatePaymentRequest = {
  type: 'sponsorship' | 'membership_fee';
  amount: number;
  payerId: string;
  payerType: 'sponsor' | 'driver';
  leagueId: string;
  seasonId?: string;
};


/**
 * Payment Service
 *
 * Orchestrates payment operations by coordinating API calls and view model creation.
 * All dependencies are injected via constructor.
 */
export class PaymentService {
  constructor(
    private readonly apiClient: PaymentsApiClient
  ) {}

  /**
   * Get all payments with optional filters
   */
  async getPayments(leagueId?: string, payerId?: string): Promise<PaymentViewModel[]> {
    const query = (leagueId || payerId) ? { ...(leagueId && { leagueId }), ...(payerId && { payerId }) } : undefined;
    const dto = await this.apiClient.getPayments(query);
    return (dto?.payments || []).map((payment: PaymentDTO) => new PaymentViewModel(payment));
  }

  /**
   * Get single payment by ID
   */
  async getPayment(paymentId: string): Promise<PaymentViewModel> {
    // Note: Assuming the API returns a single payment from the list
    const dto = await this.apiClient.getPayments();
    const payment = (dto?.payments || []).find((p: PaymentDTO) => p.id === paymentId);
    if (!payment) {
      throw new Error(`Payment with ID ${paymentId} not found`);
    }
    return new PaymentViewModel(payment);
  }

  /**
   * Create a new payment
   */
  async createPayment(input: CreatePaymentRequest): Promise<PaymentViewModel> {
    const dto = await this.apiClient.createPayment(input);
    return new PaymentViewModel(dto.payment);
  }

  /**
   * Get membership fees for a league
   */
  async getMembershipFees(leagueId: string, driverId?: string): Promise<MembershipFeeViewModel | null> {
    const dto = await this.apiClient.getMembershipFees({ leagueId, ...(driverId && { driverId }) });
    return dto.fee ? new MembershipFeeViewModel(dto.fee) : null;
  }

  /**
   * Get prizes with optional filters
   */
  async getPrizes(leagueId?: string, seasonId?: string): Promise<PrizeViewModel[]> {
    const query = (leagueId || seasonId) ? { ...(leagueId && { leagueId }), ...(seasonId && { seasonId }) } : undefined;
    const dto = await this.apiClient.getPrizes(query);
    return (dto?.prizes || []).map((prize: PrizeDTO) => new PrizeViewModel(prize));
  }

  /**
   * Get wallet for a league
   */
  async getWallet(leagueId: string): Promise<WalletViewModel> {
    const dto = await this.apiClient.getWallet({ leagueId });
    return new WalletViewModel({ ...dto.wallet, transactions: dto.transactions });
  }

  /**
   * Get payment history for a user (driver)
   */
  async getPaymentHistory(payerId: string): Promise<PaymentViewModel[]> {
    return await this.getPayments(undefined, payerId);
  }
}