import type { Logger } from '@core/shared/application/Logger'; import { Inject, Injectable } from '@nestjs/common'; // Use cases import type { AwardPrizeUseCase } from '@core/payments/application/use-cases/AwardPrizeUseCase'; import type { CreatePaymentUseCase } from '@core/payments/application/use-cases/CreatePaymentUseCase'; import type { CreatePrizeUseCase } from '@core/payments/application/use-cases/CreatePrizeUseCase'; import type { DeletePrizeUseCase } from '@core/payments/application/use-cases/DeletePrizeUseCase'; import type { GetMembershipFeesUseCase } from '@core/payments/application/use-cases/GetMembershipFeesUseCase'; import type { GetPaymentsUseCase } from '@core/payments/application/use-cases/GetPaymentsUseCase'; import type { GetPrizesUseCase } from '@core/payments/application/use-cases/GetPrizesUseCase'; import type { GetWalletUseCase } from '@core/payments/application/use-cases/GetWalletUseCase'; import type { ProcessWalletTransactionUseCase } from '@core/payments/application/use-cases/ProcessWalletTransactionUseCase'; import type { UpdateMemberPaymentUseCase } from '@core/payments/application/use-cases/UpdateMemberPaymentUseCase'; import type { UpdatePaymentStatusUseCase } from '@core/payments/application/use-cases/UpdatePaymentStatusUseCase'; import type { UpsertMembershipFeeUseCase } from '@core/payments/application/use-cases/UpsertMembershipFeeUseCase'; // Presenters import { AwardPrizePresenter } from './presenters/AwardPrizePresenter'; import { CreatePaymentPresenter } from './presenters/CreatePaymentPresenter'; import { CreatePrizePresenter } from './presenters/CreatePrizePresenter'; import { DeletePrizePresenter } from './presenters/DeletePrizePresenter'; import { GetMembershipFeesPresenter } from './presenters/GetMembershipFeesPresenter'; import { GetPaymentsPresenter } from './presenters/GetPaymentsPresenter'; import { GetPrizesPresenter } from './presenters/GetPrizesPresenter'; import { GetWalletPresenter } from './presenters/GetWalletPresenter'; import { ProcessWalletTransactionPresenter } from './presenters/ProcessWalletTransactionPresenter'; import { UpdateMemberPaymentPresenter } from './presenters/UpdateMemberPaymentPresenter'; import { UpdatePaymentStatusPresenter } from './presenters/UpdatePaymentStatusPresenter'; import { UpsertMembershipFeePresenter } from './presenters/UpsertMembershipFeePresenter'; // DTOs import type { AwardPrizeInput, CreatePaymentInput, CreatePaymentOutput, CreatePrizeInput, DeletePrizeInput, GetMembershipFeesOutput, GetMembershipFeesQuery, GetPaymentsOutput, GetPaymentsQuery, GetPrizesQuery, GetWalletQuery, ProcessWalletTransactionInput, UpdateMemberPaymentInput, UpdateMemberPaymentOutput, UpdatePaymentStatusInput, UpdatePaymentStatusOutput, UpsertMembershipFeeInput, UpsertMembershipFeeOutput, } from './dtos/PaymentsDto'; // Injection tokens import { AWARD_PRIZE_USE_CASE_TOKEN, CREATE_PAYMENT_USE_CASE_TOKEN, CREATE_PRIZE_USE_CASE_TOKEN, DELETE_PRIZE_USE_CASE_TOKEN, GET_MEMBERSHIP_FEES_USE_CASE_TOKEN, GET_PAYMENTS_USE_CASE_TOKEN, GET_PRIZES_USE_CASE_TOKEN, GET_WALLET_USE_CASE_TOKEN, LOGGER_TOKEN, PROCESS_WALLET_TRANSACTION_USE_CASE_TOKEN, UPDATE_MEMBER_PAYMENT_USE_CASE_TOKEN, UPDATE_PAYMENT_STATUS_USE_CASE_TOKEN, UPSERT_MEMBERSHIP_FEE_USE_CASE_TOKEN, } from './PaymentsProviders'; @Injectable() export class PaymentsService { constructor( @Inject(GET_PAYMENTS_USE_CASE_TOKEN) private readonly getPaymentsUseCase: GetPaymentsUseCase, @Inject(CREATE_PAYMENT_USE_CASE_TOKEN) private readonly createPaymentUseCase: CreatePaymentUseCase, @Inject(UPDATE_PAYMENT_STATUS_USE_CASE_TOKEN) private readonly updatePaymentStatusUseCase: UpdatePaymentStatusUseCase, @Inject(GET_MEMBERSHIP_FEES_USE_CASE_TOKEN) private readonly getMembershipFeesUseCase: GetMembershipFeesUseCase, @Inject(UPSERT_MEMBERSHIP_FEE_USE_CASE_TOKEN) private readonly upsertMembershipFeeUseCase: UpsertMembershipFeeUseCase, @Inject(UPDATE_MEMBER_PAYMENT_USE_CASE_TOKEN) private readonly updateMemberPaymentUseCase: UpdateMemberPaymentUseCase, @Inject(GET_PRIZES_USE_CASE_TOKEN) private readonly getPrizesUseCase: GetPrizesUseCase, @Inject(CREATE_PRIZE_USE_CASE_TOKEN) private readonly createPrizeUseCase: CreatePrizeUseCase, @Inject(AWARD_PRIZE_USE_CASE_TOKEN) private readonly awardPrizeUseCase: AwardPrizeUseCase, @Inject(DELETE_PRIZE_USE_CASE_TOKEN) private readonly deletePrizeUseCase: DeletePrizeUseCase, @Inject(GET_WALLET_USE_CASE_TOKEN) private readonly getWalletUseCase: GetWalletUseCase, @Inject(PROCESS_WALLET_TRANSACTION_USE_CASE_TOKEN) private readonly processWalletTransactionUseCase: ProcessWalletTransactionUseCase, @Inject(LOGGER_TOKEN) private readonly logger: Logger, private readonly getPaymentsPresenter: GetPaymentsPresenter, private readonly createPaymentPresenter: CreatePaymentPresenter, private readonly updatePaymentStatusPresenter: UpdatePaymentStatusPresenter, private readonly getMembershipFeesPresenter: GetMembershipFeesPresenter, private readonly upsertMembershipFeePresenter: UpsertMembershipFeePresenter, private readonly updateMemberPaymentPresenter: UpdateMemberPaymentPresenter, private readonly getPrizesPresenter: GetPrizesPresenter, private readonly createPrizePresenter: CreatePrizePresenter, private readonly awardPrizePresenter: AwardPrizePresenter, private readonly deletePrizePresenter: DeletePrizePresenter, private readonly getWalletPresenter: GetWalletPresenter, private readonly processWalletTransactionPresenter: ProcessWalletTransactionPresenter, ) {} async getPayments(query: GetPaymentsQuery): Promise { this.logger.debug('[PaymentsService] Getting payments', { query }); const result = await this.getPaymentsUseCase.execute(query); if (result.isErr()) { throw new Error(result.unwrapErr().details?.message ?? 'Failed to get payments'); } return this.getPaymentsPresenter.getResponseModel(); } async createPayment(input: CreatePaymentInput): Promise { this.logger.debug('[PaymentsService] Creating payment', { input }); const result = await this.createPaymentUseCase.execute(input); if (result.isErr()) { throw new Error(result.unwrapErr().details?.message ?? 'Failed to create payment'); } return this.createPaymentPresenter.getResponseModel(); } async updatePaymentStatus(input: UpdatePaymentStatusInput): Promise { this.logger.debug('[PaymentsService] Updating payment status', { input }); const result = await this.updatePaymentStatusUseCase.execute(input); if (result.isErr()) { throw new Error(result.unwrapErr().details?.message ?? 'Failed to update payment status'); } return this.updatePaymentStatusPresenter.getResponseModel(); } async getMembershipFees(query: GetMembershipFeesQuery): Promise { this.logger.debug('[PaymentsService] Getting membership fees', { query }); const result = await this.getMembershipFeesUseCase.execute(query); if (result.isErr()) { throw new Error(result.unwrapErr().details?.message ?? 'Failed to get membership fees'); } return this.getMembershipFeesPresenter.getResponseModel(); } async upsertMembershipFee(input: UpsertMembershipFeeInput): Promise { this.logger.debug('[PaymentsService] Upserting membership fee', { input }); const result = await this.upsertMembershipFeeUseCase.execute(input); if (result.isErr()) { throw new Error(result.unwrapErr().details?.message ?? 'Failed to upsert membership fee'); } return this.upsertMembershipFeePresenter.getResponseModel(); } async updateMemberPayment(input: UpdateMemberPaymentInput): Promise { this.logger.debug('[PaymentsService] Updating member payment', { input }); const result = await this.updateMemberPaymentUseCase.execute(input); if (result.isErr()) { throw new Error(result.unwrapErr().details?.message ?? 'Failed to update member payment'); } return this.updateMemberPaymentPresenter.getResponseModel(); } async getPrizes(query: GetPrizesQuery): Promise { // TODO must return ResponseModel not Presenter this.logger.debug('[PaymentsService] Getting prizes', { query }); const presenter = new GetPrizesPresenter(); await this.getPrizesUseCase.execute({ leagueId: query.leagueId!, seasonId: query.seasonId }, presenter); return presenter; } async createPrize(input: CreatePrizeInput): Promise { // TODO must return ResponseModel not Presenter this.logger.debug('[PaymentsService] Creating prize', { input }); const presenter = new CreatePrizePresenter(); await this.createPrizeUseCase.execute(input, presenter); return presenter; } async awardPrize(input: AwardPrizeInput): Promise { // TODO must return ResponseModel not Presenter this.logger.debug('[PaymentsService] Awarding prize', { input }); const presenter = new AwardPrizePresenter(); await this.awardPrizeUseCase.execute(input, presenter); return presenter; } async deletePrize(input: DeletePrizeInput): Promise { // TODO must return ResponseModel not Presenter this.logger.debug('[PaymentsService] Deleting prize', { input }); const presenter = new DeletePrizePresenter(); await this.deletePrizeUseCase.execute(input, presenter); return presenter; } async getWallet(query: GetWalletQuery): Promise { // TODO must return ResponseModel not Presenter this.logger.debug('[PaymentsService] Getting wallet', { query }); const presenter = new GetWalletPresenter(); await this.getWalletUseCase.execute({ leagueId: query.leagueId! }, presenter); return presenter; } async processWalletTransaction(input: ProcessWalletTransactionInput): Promise { this.logger.debug('[PaymentsService] Processing wallet transaction', { input }); const presenter = new ProcessWalletTransactionPresenter(); await this.processWalletTransactionUseCase.execute(input, presenter); return presenter; } }