/**
 * Application Use Case: UpdatePaymentStatusUseCase
 *
 * Updates the status of a payment.
 */

import type { IPaymentRepository } from '../../domain/repositories/IPaymentRepository';
import type { PaymentStatus } from '../../domain/entities/Payment';
import type {
  IUpdatePaymentStatusPresenter,
  UpdatePaymentStatusResultDTO,
  UpdatePaymentStatusViewModel,
} from '../presenters/IUpdatePaymentStatusPresenter';
import type { UseCase } from '@core/shared/application/UseCase';

export interface UpdatePaymentStatusInput {
  paymentId: string;
  status: PaymentStatus;
}

export class UpdatePaymentStatusUseCase
  implements UseCase<UpdatePaymentStatusInput, UpdatePaymentStatusResultDTO, UpdatePaymentStatusViewModel, IUpdatePaymentStatusPresenter>
{
  constructor(private readonly paymentRepository: IPaymentRepository) {}

  async execute(
    input: UpdatePaymentStatusInput,
    presenter: IUpdatePaymentStatusPresenter,
  ): Promise<void> {
    presenter.reset();

    const { paymentId, status } = input;

    const payment = await this.paymentRepository.findById(paymentId);
    if (!payment) {
      throw new Error('Payment not found');
    }

    payment.status = status;
    if (status === ('completed' as PaymentStatus)) {
      payment.completedAt = new Date();
    }

    const updatedPayment = await this.paymentRepository.update(payment);

    const dto: UpdatePaymentStatusResultDTO = {
      payment: {
        id: updatedPayment.id,
        type: updatedPayment.type,
        amount: updatedPayment.amount,
        platformFee: updatedPayment.platformFee,
        netAmount: updatedPayment.netAmount,
        payerId: updatedPayment.payerId,
        payerType: updatedPayment.payerType,
        leagueId: updatedPayment.leagueId,
        seasonId: updatedPayment.seasonId,
        status: updatedPayment.status,
        createdAt: updatedPayment.createdAt,
        completedAt: updatedPayment.completedAt,
      },
    };

    presenter.present(dto);
  }
}