"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const axios = require("axios");
const qs = require("qs");
const uuid = require("uuid");
const index = require("./i18n-HHdcQbuJ.cjs");
const errorCodes = require("./errorCodes-ifTrQJQk.cjs");
const utils = require("./utils-KiKajtHz.cjs");
const z = require("zod");
const API_HITPAY = process.env.NEXT_PUBLIC_API_HITPAY_PRODUCTION || "https://api.hit-pay.com";
const SANDBOX_API_HITPAY = process.env.NEXT_PUBLIC_API_HITPAY_SANDBOX || "https://api.sandbox.hit-pay.com";
const hitpayCredentialKeysSchema = z.object({
  prod: z.object({
    apiKey: z.string(),
    saltKey: z.string()
  }).optional(),
  sandbox: z.object({
    apiKey: z.string(),
    saltKey: z.string()
  }).optional(),
  isSandbox: z.boolean()
});
const log = index.logger.getSubLogger({ prefix: ["payment-service:hitpay"] });
class PaymentService {
  constructor(credentials) {
    const keyParsing = hitpayCredentialKeysSchema.safeParse(credentials.key);
    if (keyParsing.success) {
      this.credentials = keyParsing.data;
    } else {
      this.credentials = null;
    }
  }
  async create(payment, bookingId, userId, username, bookerName, paymentOption, bookerEmail) {
    try {
      const booking = await index.prisma.booking.findUnique({
        where: {
          id: bookingId
        },
        select: {
          uid: true,
          title: true,
          startTime: true,
          endTime: true,
          eventTypeId: true,
          eventType: {
            select: {
              slug: true,
              seatsPerTimeSlot: true
            }
          },
          attendees: { include: { bookingSeat: true } }
        }
      });
      if (!booking || !this.credentials) {
        throw new Error("Booking or API key not found");
      }
      const { startTime, endTime, eventTypeId } = booking;
      const bookingsWithSameTimeSlot = await index.prisma.booking.findMany({
        where: {
          eventTypeId,
          startTime,
          endTime,
          OR: [{ status: "PENDING" }, { status: "AWAITING_HOST" }]
        },
        select: {
          uid: true,
          title: true
        }
      });
      if (booking.eventType?.seatsPerTimeSlot) {
        if (booking.eventType.seatsPerTimeSlot <= booking.attendees.filter((attendee) => !!attendee.bookingSeat).length || bookingsWithSameTimeSlot.length > booking.eventType.seatsPerTimeSlot) {
          throw new Error(errorCodes.ErrorCode.BookingSeatsFull);
        }
      } else {
        if (bookingsWithSameTimeSlot.length > 1) {
          throw new Error(errorCodes.ErrorCode.NoAvailableUsersFound);
        }
      }
      const { isSandbox } = this.credentials;
      const keyObj = isSandbox ? this.credentials.sandbox : this.credentials.prod;
      if (!keyObj || !keyObj?.apiKey) {
        throw new Error("API key not found");
      }
      const hitpayAPIurl = isSandbox ? SANDBOX_API_HITPAY : API_HITPAY;
      const requestUrl = `${hitpayAPIurl}/v1/payment-requests`;
      const redirectUri = `${index.WEBAPP_URL}/api/integrations/${utils.appConfig$1.slug}/callback`;
      const webhookUri = `${index.WEBAPP_URL}/api/integrations/${utils.appConfig$1.slug}/webhook`;
      const formData = {
        amount: payment.amount / 100,
        currency: payment.currency,
        email: bookerEmail,
        name: bookerName,
        reference_number: bookingId.toString(),
        redirect_url: redirectUri,
        webhook: webhookUri,
        channel: "api_cal",
        purpose: booking.title
      };
      const response = await axios.post(requestUrl, qs.stringify(formData), {
        headers: {
          "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
          "X-BUSINESS-API-KEY": keyObj.apiKey,
          "X-Requested-With": "XMLHttpRequest"
        }
      });
      const data = response.data;
      const getRequestUrl = `${hitpayAPIurl}/v1/payment-requests?request_id=${data.id}&is_default=1`;
      const getResponse = await axios.get(getRequestUrl, {
        headers: {
          "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
          "X-BUSINESS-API-KEY": keyObj.apiKey,
          "X-Requested-With": "XMLHttpRequest"
        }
      });
      const getData = getResponse.data;
      const defaultLink = getData.data[0].url;
      const uid = uuid.v4();
      const paymentData = await index.prisma.payment.create({
        data: {
          uid,
          app: {
            connect: {
              slug: "hitpay"
            }
          },
          booking: {
            connect: {
              id: bookingId
            }
          },
          amount: parseFloat(data.amount.replace(/,/g, "")) * 100,
          externalId: data.id,
          currency: data.currency,
          data: Object.assign(
            {},
            { defaultLink, ...data },
            { bookingUserName: username, eventTypeSlug: booking.eventType?.slug, bookingUid: booking.uid },
            { isPaid: false }
          ),
          fee: 0,
          refunded: false,
          success: false
        }
      });
      if (!paymentData) {
        throw new Error("Failed to store Payment data");
      }
      return paymentData;
    } catch (error) {
      log.error("Payment could not be created", bookingId, index.safeStringify(error));
      try {
        await index.prisma.booking.update({
          where: {
            id: bookingId
          },
          data: {
            status: "CANCELLED"
          }
        });
      } catch (error2) {
        throw new Error(errorCodes.ErrorCode.PaymentCreationFailure);
      }
      if (error.message === errorCodes.ErrorCode.BookingSeatsFull || error.message === errorCodes.ErrorCode.NoAvailableUsersFound) {
        throw error;
      }
      throw new Error(errorCodes.ErrorCode.PaymentCreationFailure);
    }
  }
  async update() {
    throw new Error("Method not implemented.");
  }
  async refund() {
    throw new Error("Method not implemented.");
  }
  async collectCard(_payment, _bookingId, _bookerEmail, _paymentOption) {
    throw new Error("Method not implemented");
  }
  chargeCard(_payment, _bookingId) {
    throw new Error("Method not implemented.");
  }
  getPaymentPaidStatus() {
    throw new Error("Method not implemented.");
  }
  getPaymentDetails() {
    throw new Error("Method not implemented.");
  }
  afterPayment(_event, _booking, _paymentData) {
    return Promise.resolve();
  }
  deletePayment(_paymentId) {
    return Promise.resolve(false);
  }
  isSetupAlready() {
    return !!this.credentials;
  }
}
exports.PaymentService = PaymentService;
