import * as functions from "firebase-functions";
import {
  doctorCol,
  orderCol,
  OrderStatus,
  timeSlotCol,
  usersCol,
} from "../collections";
import * as random from "randomstring";
import { PaymentMethod, PaymentStatus } from "../payment-functions";
import { firestore } from "firebase-admin";
import {
  orderedTimeslotNotification,
  paymentSuccessNotification,
} from "../notification-function";
const midtransClient = require("midtrans-client");
export const requestMidtransPayment = functions.https.onCall(
  async (request, response) => {
    try {
      // let userId = request.userId;
      let timeSlotId = request.timeSlotId;
      const choosedTimeSlot = (await timeSlotCol.doc(timeSlotId).get()).data();
      if (!choosedTimeSlot) {
        throw new functions.https.HttpsError(
          "not-found",
          "Selected Time slot not found"
        );
      }
      /// Generate order id
      const orderId = random.generate(12);
      let snap = new midtransClient.Snap({
        isProduction: false,
        serverKey: process.env.MIDTRANS_SERVER_KEY,
        clientKey: process.env.MIDTRANS_CLIENT_KEY,
      });
      const paymentAmount = choosedTimeSlot.price * 16000; // Convert to IDR because default currency price is in USD
      let parameter = {
        transaction_details: {
          order_id: orderId,
          gross_amount: paymentAmount,
        },
        credit_card: {
          secure: true,
        },
      };
      let token = await snap
        .createTransaction(parameter)
        .then((transaction: { token: any }) => {
          // transaction token
          let transactionToken = transaction.token;
          console.log("transactionToken:", transactionToken);
          return transactionToken;
        });
      /// Create order in firestore database
      await orderCol.doc(orderId).set({
        createdAt: firestore.Timestamp.fromDate(new Date()),
        timeSlotId: request.timeSlotId,
        userId: request.userId,
        charged: false,
        status: OrderStatus.notPay,
        paymentMethod: PaymentMethod.Midtrans,
      });
      return token;
    } catch (error) {
      console.log(error);
      throw error;
    }
  }
);

export const midtransWebhook = functions.https.onRequest(
  async (request, response) => {
    try {
      console.log(JSON.stringify(request.body));
      const { gross_amount, order_id, currency } = request.body;

      let order = await orderCol.doc(order_id).get();
      if (!order.exists) {
        response.status(404).send("Order not found, with id: " + order_id);
        return;
      }
      order.ref.update({
        charged: true,
        amount: gross_amount,
        status: PaymentStatus.PaymentSuccess,
        currency: currency,
      });
      //Get user info who book this timeslot
      let bookByWho = (await usersCol.doc(order.data()?.userId!).get()).data();
      const timeSlot = await timeSlotCol.doc(order.data()?.timeSlotId!).get();
      const doctor = await doctorCol.doc(timeSlot.data()?.doctorId!).get();
      timeSlot.ref.update({
        charged: true,
        available: false,
        bookByWho: {
          userId: order.data()?.userId!,
          displayName: bookByWho?.displayName,
          photoUrl: bookByWho?.photoUrl ? bookByWho?.photoUrl : "",
        },
        status: "booked",
        doctor: {
          doctorName: doctor.data()?.doctorName,
          doctorPicture: doctor.data()?.doctorPicture,
        },
        purchaseTime: firestore.Timestamp.fromDate(new Date()),
      });
      await orderedTimeslotNotification(doctor.id);
      await paymentSuccessNotification(order.data()?.userId!, order.id);

      response.status(200).send("OK");
    } catch (error) {
      throw error;
    }
  }
);
