"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.confirmConsultation = exports.rescheduleTimeslot = exports.refundTimeslot = exports.timeslotAdded = void 0;
const functions = require("firebase-functions");
const user_service_1 = require("./user-service");
const user_wallet_functions_1 = require("./user-wallet-functions");
const collections_1 = require("./collections");
const admin = require("firebase-admin");
const db = admin.firestore();
const { firestore } = require("firebase-admin");
const notificationFunction = require("./notification-function");
exports.timeslotAdded = functions.firestore
    .document("/DoctorTimeslot/{doctorTimeslotId}")
    .onCreate((snapshot, context) => {
    //snapshot.ref.update({ balance: 0 });
    const newValue = snapshot.data();
    if (newValue.repeat === "weekly on the same day and time") {
        console.log("weekly on the same day and time");
    }
    return Promise.resolve();
});
async function refundTimeslot(timeSlotId, refundId) {
    try {
        var timeslotSnapshot = await db
            .collection("DoctorTimeslot")
            .doc(timeSlotId)
            .get();
        if (timeslotSnapshot.data().available == false &&
            timeslotSnapshot.data().charged == true) {
            let refundObject = {
                status: "refund",
                refundId: refundId,
            };
            //update Timeslot Status
            await timeslotSnapshot.ref.update(refundObject);
            //update Order collection status
            let orderSnapshot = await db
                .collection("Order")
                .where("timeSlotId", "==", timeSlotId)
                .get();
            let order = orderSnapshot.docs[0];
            order.ref.update(refundObject);
            console.log("update timeslot refund success");
        }
        else {
            throw "timeslot available, not purchase yet";
        }
    }
    catch (error) {
        throw error;
    }
}
exports.refundTimeslot = refundTimeslot;
/** this function will reschedule the timeslot that has been purchase
 * this function get callen in @ClientApp
 */
exports.rescheduleTimeslot = functions.https.onCall(async (request, response) => {
    var timeSlotNow = await db
        .collection("DoctorTimeslot")
        .doc(request.timeSlotIdNow)
        .get();
    var timeSlotChanged = await db
        .collection("DoctorTimeslot")
        .doc(request.timeslotChanged)
        .get();
    console.log("timeslot now data : " + JSON.stringify(timeSlotNow.data()));
    if (timeSlotNow.data().status == "complete") {
        throw new functions.https.HttpsError("unknown", "The appointment has been marked as complete, and cannot be rescheduled");
    }
    if (timeSlotNow.data().status == "refund") {
        throw new functions.https.HttpsError("unknown", "The appointment has been refunded, and cannot be rescheduled");
    }
    if (timeSlotChanged.data().available == false) {
        throw new functions.https.HttpsError("unknown", "The selected timeslot is no longer available");
    }
    if (timeSlotNow.data().pastTimeSlot) {
        throw new functions.https.HttpsError("unknown", "The appointment has been rescheduled once, and cannot be rescheduled again");
    }
    //Update Timeslot
    await timeSlotNow.ref.update({
        timeSlot: timeSlotChanged.data().timeSlot,
        price: timeSlotChanged.data().price,
        duration: timeSlotChanged.data().duration,
        pastTimeSlot: timeSlotNow.data().timeSlot,
        pastDuration: timeSlotNow.data().duration,
        pastPrice: timeSlotNow.data().price,
    });
    await timeSlotChanged.ref.update({
        available: false,
        timseSlotChanged: true,
        timeSlotChangedTo: timeSlotNow.id,
    });
    var timeSlotNow2 = await db
        .collection("DoctorTimeslot")
        .doc(request.timeSlotIdNow)
        .get();
    var timeSlotChanged2 = await db
        .collection("DoctorTimeslot")
        .doc(request.timeSlotIdNow)
        .get();
    console.log("successfully reschedule appointment");
    console.log("timeslot now data after change : " + JSON.stringify(timeSlotNow2.data()));
    console.log("timeslot changed data after change : " +
        JSON.stringify(timeSlotChanged2.data()));
    await notificationFunction.rescheduleTimeslotNotification(timeSlotNow.data().doctorId);
});
// user confirm consultation complete, give money to doctor & create transaction
exports.confirmConsultation = functions.https.onCall(async (request) => {
    try {
        // Start a Firestore batch to ensure atomic updates
        const batch = db.batch();
        // Get the order first to check status
        const order = await db.collection("Order").doc(request.orderId).get();
        const orderData = order.data();
        if (!orderData) {
            throw new functions.https.HttpsError("not-found", "Order not found");
        }
        if (orderData.status !== collections_1.OrderStatus.pay) {
            throw new functions.https.HttpsError("failed-precondition", "Order must be in payment_success status");
        }
        //get doctor timeslot
        let timeSlot = await db
            .collection("DoctorTimeslot")
            .doc(orderData.timeSlotId)
            .get();
        if (!timeSlot.exists) {
            throw new functions.https.HttpsError("not-found", "TimeSlot not found");
        }
        const timeSlotData = timeSlot.data();
        const doctorId = timeSlotData === null || timeSlotData === void 0 ? void 0 : timeSlotData.doctorId;
        //get user id by doctor and increase their wallet balance
        const doctorUser = await (0, user_service_1.getUserByDoctorId)(doctorId);
        const userId = doctorUser.uid;
        console.log("doctor id : " + doctorId);
        console.log("doctor user id : " + userId);
        const completedAt = firestore.Timestamp.fromDate(new Date());
        // Prepare all updates in batch
        // 1. Update order status
        batch.update(order.ref, {
            status: "success",
            completedAt: completedAt,
        });
        // 2. Update timeslot status
        batch.update(timeSlot.ref, {
            status: "complete",
            completedAt: completedAt,
        });
        // 3. Create transaction document
        const transactionRef = db.collection("Transaction").doc();
        batch.set(transactionRef, {
            userId: userId,
            amount: orderData.amount,
            status: "complete",
            type: "payment",
            timeSlot: orderData.timeSlotId,
            createdAt: completedAt,
        });
        // Commit all updates atomically
        await batch.commit();
        console.log("Batch updates committed successfully");
        // After successful batch commit, update wallet balance
        await (0, user_wallet_functions_1.increaseWalletBalance)(userId, orderData.amount);
        console.log("increase wallet balance success");
        // Send completion notification to doctor
        const notificationTitle = "Consultation Completed";
        const notificationMessage = `Consultation completed and payment of ${orderData.amount} has been processed for your session on ${new Date(timeSlotData.timeSlot.toDate()).toLocaleString()}`;
        await notificationFunction.sendNotification(doctorUser.token, notificationTitle, notificationMessage, {
            type: "consultation_completed",
            timeSlotId: orderData.timeSlotId,
            orderId: request.orderId,
            amount: orderData.amount,
            completedAt: completedAt.toDate().toISOString(),
        });
        console.log("Completion notification sent to doctor");
        return { success: true };
    }
    catch (error) {
        console.error("Error in confirmConsultation:", error);
        throw error;
    }
});
//# sourceMappingURL=timeslot-functions.js.map