import { Inject, InternalServerErrorException } from '@nestjs/common';
import { type IQueryHandler, QueryHandler } from '@nestjs/cqrs';
import { DomainException, ForbiddenException, LoggerService, NotFoundException } from '@modules/shared';
import {
  PAYMENT_REPOSITORY,
  type IPaymentRepository,
} from '../../../domain/repositories/payment.repository';
import { GetPaymentStatusQuery } from './get-payment-status.query';

export interface PaymentStatusDto {
  id: string;
  provider: string;
  type: string;
  amountVND: string;
  status: string;
  providerTxId: string | null;
  createdAt: Date;
  updatedAt: Date;
}

@QueryHandler(GetPaymentStatusQuery)
export class GetPaymentStatusHandler implements IQueryHandler<GetPaymentStatusQuery> {
  constructor(
    @Inject(PAYMENT_REPOSITORY)
    private readonly paymentRepo: IPaymentRepository,
    private readonly logger: LoggerService,
  ) {}

  async execute(query: GetPaymentStatusQuery): Promise<PaymentStatusDto> {
    try {
      const payment = await this.paymentRepo.findById(query.paymentId);
      if (!payment) {
        throw new NotFoundException('Payment', query.paymentId);
      }

      if (payment.userId !== query.userId) {
        throw new ForbiddenException('Bạn không có quyền xem thanh toán này');
      }

      return {
        id: payment.id,
        provider: payment.provider,
        type: payment.type,
        amountVND: payment.amount.value.toString(),
        status: payment.status,
        providerTxId: payment.providerTxId,
        createdAt: payment.createdAt,
        updatedAt: payment.updatedAt,
      };
    } catch (error) {
      if (error instanceof DomainException) throw error;
      this.logger.error(
        `Failed to get payment status: ${error instanceof Error ? error.message : error}`,
        error instanceof Error ? error.stack : undefined,
        this.constructor.name,
      );
      throw new InternalServerErrorException('Không thể truy vấn trạng thái thanh toán. Vui lòng thử lại sau');
    }
  }
}
