import { Injectable, NotFoundException } from '@nestjs/common';
import { BookingsRepository } from './bookings.repository';
import { Booking } from './entities/booking.entity';
import { assertBookingStatus } from './booking-status.util';
import { InAppPaymentReceiptDto } from './dto/pay-booking.dto';
import { PaymentService } from '../payment/payment.service';
import { PaymentStatus } from '../payment/entities/payment.entity';
import { PaymentMethodTypeEnum } from '../payment/payments.dto';
export interface InAppPaymentReceipt extends InAppPaymentReceiptDto { }

const NON_TERMINAL_STATUSES: PaymentStatus[] = [
  "action-required",
  "processing",
  "success",
];

@Injectable()
export class BookingPaymentService {
  constructor(
    private readonly bookingsRepository: BookingsRepository,
    private readonly paymentService: PaymentService,
  ) { }

  async pay(bookingId: string): Promise<{ redirectUrl: string }> {
    const booking = await this.requireBooking(bookingId);
    assertBookingStatus(booking, ['FULLY_EXECUTED', 'SELECTED_FOR_BATCH', 'AWAITING_PAYMENT', '']);

    const existing = await this.paymentService.findBookingById(bookingId);
    if (existing && NON_TERMINAL_STATUSES.includes(existing.status)) {
      if (existing.clientAction) {
        const action = existing.clientAction as { type?: string; url?: string };
        if (action.type === "REDIRECT" && action.url) {
          return { redirectUrl: action.url };
        }
      }
    }

    const resp = await this.paymentService.initiatePayment({
      bookingId,
      method: PaymentMethodTypeEnum.TELEBIRR,
      platform: "web",
    });

    const action = resp.clientAction as { type?: string; url?: string } | undefined;
    return {
      redirectUrl: action?.type === "REDIRECT" ? (action.url ?? "") : "",
    };
  }

  private async requireBooking(id: string): Promise<Booking> {
    const booking = await this.bookingsRepository.findById(id);
    if (!booking) throw new NotFoundException(`Booking ${id} not found`);
    return booking;
  }
}
