"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HomeController = void 0;
const ResponseHelper_1 = require("../../helpers/ResponseHelper");
const Banner_1 = require("../../models/Banner");
const Order_1 = require("../../models/Order");
const moment = require("moment");
const ProductService_1 = require("../../models/ProductService");
const UserSubscription_1 = require("../../models/UserSubscription");
const OrderDetail_1 = require("../../models/OrderDetail");
const OrderController_1 = require("./OrderController");
const Transaction_1 = require("../../models/Transaction");
const Helper_1 = require("../../helpers/Helper");
const OrderStatus_1 = require("../../models/OrderStatus");
const Subscription_1 = require("../../models/Subscription");
const Settings_1 = require("../../models/Settings");
class HomeController {
    /**
     * @api {get} /api/app/auth/dashboard Dashboard
     * @apiVersion 1.0.0
     * @apiName Dashboard
     * @apiHeader {String} Authorization Pass jwt token.
     * @apiGroup Dashboard
     */
    static dashboard(req, res, next) {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                const startTime = new Date().getTime();
                const todayDate = moment().format("YYYY-MM-DD");
                const endDate = moment().add(5, "days").format("YYYY-MM-DD");
                const user_id = req.user.id;
                const orderFilterQuery = {};
                orderFilterQuery.date = {
                    $gte: todayDate,
                    $lte: endDate,
                };
                const [banner, featured_service, subscription, upcoming_on_demand_wash, upcoming_subscription_wash, expired_subscription,] = yield Promise.all([
                    Banner_1.default.find({ is_active: true }),
                    ProductService_1.default.find({ is_active: true, is_featured: true }),
                    UserSubscription_1.default.find({ user_id: user_id }),
                    Order_1.default.find({ user_id: user_id })
                        .find({ order_type: "OnDemand", status: "new" })
                        .find(orderFilterQuery)
                        .sort({ date: 1 })
                        .populate([
                        {
                            path: "user_id",
                        },
                        {
                            path: "car_id",
                            populate: [
                                {
                                    path: "make_id",
                                    select: "name image",
                                },
                                {
                                    path: "model_id",
                                    select: "name",
                                },
                                {
                                    path: "color_id",
                                    select: "color",
                                },
                                {
                                    path: "avatar_id",
                                    select: "image",
                                },
                            ],
                        },
                    ]),
                    OrderDetail_1.default.find({ user_id: user_id, status: "new" })
                        .find(orderFilterQuery)
                        .sort({ date: 1 })
                        .populate([
                        {
                            path: "user_id",
                        },
                        {
                            path: "car_id",
                            populate: [
                                {
                                    path: "make_id",
                                    select: "name image",
                                },
                                {
                                    path: "model_id",
                                    select: "name",
                                },
                                {
                                    path: "color_id",
                                    select: "color",
                                },
                                {
                                    path: "avatar_id",
                                    select: "image",
                                },
                            ],
                        },
                    ]),
                    UserSubscription_1.default.find({ end_date: { $lte: todayDate } })
                        .find({ user_id: user_id })
                        .populate([{ path: "subscription_id" }, { path: "car_id" }]),
                ]);
                // New Code Added On 07-06-2024 As Per Client Requirement.
                // Assuming additionalPrice is a fixed value you want to add
                const setting = yield Settings_1.default.findOne({}).sort({ created_at: -1 });
                const additionalPrice = setting === null || setting === void 0 ? void 0 : setting.tariff_charge;
                const updatedFeaturedService = featured_service.map((service) => {
                    const modifyService = service.toObject();
                    modifyService.price += additionalPrice;
                    modifyService.tariff_charge = additionalPrice.toFixed(2); // New key on 07-06-2024
                    return modifyService;
                });
                // End New Code Here
                const response = {
                    banner: banner,
                    featured_service: updatedFeaturedService,
                    subscription: subscription,
                    upcoming_on_demand_wash: upcoming_on_demand_wash,
                    upcoming_subscription_wash: upcoming_subscription_wash,
                    expired_subscription: expired_subscription,
                };
                const protocol = req.protocol;
                const host = req.get("host");
                Object.keys(response).forEach((key) => {
                    if (response[key].length > 0 && "image" in response[key][0]) {
                        response[key].forEach((item) => {
                            item.image = item.image
                                ? `${protocol}://${host}/public/${item.image}`
                                : "";
                        });
                    }
                });
                return ResponseHelper_1.default.api(res, true, req.lang["DashboardData"], response, startTime);
            }
            catch (err) {
                return next(err);
            }
        });
    }
    /**
     * @api {get} /api/app/auth/my-subscription Dashboard
     * @apiVersion 1.0.0
     * @apiName My Subscription
     * @apiHeader {String} Authorization Pass jwt token.
     * @apiGroup Dashboard
     */
    static mySubscriptions(req, res, next) {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                const startTime = new Date().getTime();
                const getSubscription = yield UserSubscription_1.default.find({
                    user_id: req.user.id,
                }).populate([
                    {
                        path: "subscription_id",
                    },
                    {
                        path: "subscription_service.service_id",
                    },
                ]);
                if (!getSubscription) {
                    return ResponseHelper_1.default.api(res, false, req.lang["SubscriptionNotFound"], {}, startTime);
                }
                return ResponseHelper_1.default.api(res, true, req.lang["MySubscriptionList"], getSubscription, startTime);
            }
            catch (err) {
                next(err);
            }
        });
    }
    /**
     * @api {post} /api/app/auth/upgrade-subscription Upgrade Subscription
     * @apiVersion 1.0.0
     * @apiName Upgrade Subscription
     * @apiHeader {String} Authorization Pass jwt token.
     * @apiGroup Dashboard
     * @apiParam {String} subscription_id Subscription ID.
     * @apiParam {String} order_id Order ID.
     * @apiParam {String} payment_method Payment Method ("Online","Cod").
     */
    static upgradeSubscriptions(req, res, next) {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                const startTime = new Date().getTime();
                const user_id = req.user.id;
                const { subscription_id, order_id, payment_method } = req.body;
                const getOldOrder = yield Order_1.default.findOne({
                    user_id: user_id,
                    order_id: order_id,
                });
                const getNewSubscription = yield Subscription_1.default.findById(subscription_id);
                const getSetting = yield Settings_1.default.findOne({}).sort({ created_at: -1 });
                const tariffCharge = (getSetting === null || getSetting === void 0 ? void 0 : getSetting.tariff_charge)
                    ? Number(getSetting.tariff_charge).toFixed(2)
                    : 0.0;
                const todayDate = moment().format("YYYY-MM-DD");
                const endDate = moment().add(30, "days").format("YYYY-MM-DD");
                const betweenDates = OrderController_1.OrderController.getDatesBetween(todayDate, endDate);
                var month = ("0" + (new Date().getMonth() + 1)).slice(-2);
                const unique = new Date().valueOf();
                let genrateCode = yield Helper_1.default.generatePassword(4, {
                    digits: true,
                    lowercase: false,
                    uppercase: true,
                });
                let randomOrderId = genrateCode + String(unique).substring(10, 12) + month;
                // Add the is_complete key to each object
                const modifiedServiceIdArray = getOldOrder.service_id.map((service) => (Object.assign(Object.assign({}, service), { is_complete: false, complete_on: null })));
                let modifiedSubscriptionObject = {}; // Change to an object
                if (getOldOrder.order_type === "Subscription") {
                    try {
                        if (getNewSubscription) {
                            // Retrieve the ProductService data for all service_ids
                            const productServiceDataPromises = getNewSubscription.services.map((service) => __awaiter(this, void 0, void 0, function* () {
                                const productServiceData = yield ProductService_1.default.findById(service.service_id);
                                if (productServiceData) {
                                    return productServiceData.toObject();
                                }
                                else {
                                    return null;
                                }
                            }));
                            // Wait for all promises to resolve
                            const productServiceDataArray = yield Promise.all(productServiceDataPromises);
                            // Merge the ProductService data into the existing getNewSubscription object
                            for (let i = 0; i < getNewSubscription.services.length; i++) {
                                getNewSubscription.services[i] = Object.assign(Object.assign(Object.assign({}, getNewSubscription.services[i].toObject()), productServiceDataArray[i]), { is_complete: false, complete_on: null, total_service: productServiceDataArray[i].no_of_time || 0 });
                            }
                            // Add the modified getNewSubscription to the modifiedSubscriptionObject
                            modifiedSubscriptionObject = Object.assign(Object.assign({}, modifiedSubscriptionObject), getNewSubscription.toObject());
                        }
                    }
                    catch (error) {
                        console.error("Error:", error);
                    }
                }
                // modifiedSubscriptionObject will now contain the modified subscription data
                const currentDate = new Date();
                const expiredDate = new Date(currentDate.getTime() + 24 * 60 * 60 * 1000); // Add 24 hours (in milliseconds)
                const addOrder = yield new Order_1.default({
                    random_order_id: randomOrderId,
                    user_id: user_id,
                    car_id: getOldOrder.car_id,
                    service_id: getOldOrder.service_id ? modifiedServiceIdArray : null,
                    subscription_id: getOldOrder.order_type == "Subscription" ? subscription_id : null,
                    subscription: getOldOrder.order_type == "Subscription"
                        ? modifiedSubscriptionObject
                        : null,
                    date: getOldOrder.date,
                    time: getOldOrder.time,
                    address: getOldOrder.address,
                    landmark: getOldOrder.landmark,
                    city: getOldOrder.city,
                    state: getOldOrder.state,
                    country: getOldOrder.country,
                    currency: getOldOrder.currency,
                    latitude: getOldOrder.latitude,
                    longitude: getOldOrder.longitude,
                    sub_total: getOldOrder.sub_total,
                    tariff_charge: tariffCharge,
                    discount_amount: null,
                    discount_code: null,
                    discount_id: null,
                    total: getNewSubscription.discount,
                    current_status: "new",
                    status: "new",
                    date_time_stamp: getOldOrder.date + " " + getOldOrder.time,
                    order_type: getOldOrder.order_type,
                    payment_status: payment_method == "Online" ? "pending" : "Cod",
                    payment_method: payment_method,
                    order_expire_on: expiredDate,
                }).save();
                yield new OrderStatus_1.default({
                    order_id: addOrder._id,
                    mark_by: null,
                    mark_on: new Date(),
                    status: "new",
                }).save();
                yield new Transaction_1.default({
                    transaction_id: "lcw-" + startTime + month,
                    subscription_id: subscription_id ? subscription_id : null,
                    discount_code: null,
                    total: getNewSubscription.discount,
                    sub_total: getNewSubscription.price,
                    tariff_charge: tariffCharge,
                    order_id: addOrder._id,
                    service_id: getOldOrder.service_id ? getOldOrder.service_id : null,
                    type: subscription_id ? "Subscription" : "OnDemand",
                    payment_status: payment_method == "Online" ? "pending" : "Cod",
                    payment_method: payment_method,
                    order_expire_on: expiredDate,
                }).save();
                // Related to subscription order
                if (subscription_id &&
                    subscription_id != null &&
                    getOldOrder.order_type === "Subscription") {
                    // && payment_status === 'success'
                    // Loop from today to 30 days (Monthly Data Creation)
                    betweenDates.forEach((element) => __awaiter(this, void 0, void 0, function* () {
                        const orderDetails = {
                            order_id: addOrder._id,
                            random_order_id: addOrder.random_order_id,
                            date: element,
                            service_id: getOldOrder.service_id,
                            subscription_id: getOldOrder.order_type == "Subscription" ? subscription_id : null,
                            subscription: getOldOrder.order_type == "Subscription"
                                ? modifiedSubscriptionObject
                                : null,
                            time: getOldOrder.time,
                            user_id: user_id,
                            car_id: getOldOrder.car_id,
                            latitude: getOldOrder.latitude,
                            longitude: getOldOrder.longitude,
                            address: getOldOrder.address,
                            currency: getOldOrder.currency,
                            landmark: getOldOrder.landmark,
                            city: getOldOrder.city,
                            state: getOldOrder.state,
                            country: getOldOrder.country,
                            status: "new",
                            current_status: "new",
                            date_time_stamp: element + " " + getOldOrder.time,
                        };
                        yield new OrderDetail_1.default(orderDetails).save();
                    }));
                    yield UserSubscription_1.default.create({
                        user_id: user_id,
                        start_date: todayDate,
                        end_date: endDate,
                        subscription: getOldOrder.order_type == "Subscription"
                            ? modifiedSubscriptionObject
                            : null,
                        car_id: getOldOrder.car_id,
                        subscription_type: "Month",
                        subscription_no: "lamsa-" + startTime,
                    });
                }
                if (addOrder) {
                    // Find the old UserSubscription
                    const oldUserSubscription = yield UserSubscription_1.default.findOne({
                        user_id: user_id,
                        car_id: getOldOrder.car_id,
                        "subscription._id": subscription_id,
                    });
                    if (oldUserSubscription) {
                        // If oldUserSubscription exists, delete related records
                        yield Transaction_1.default.findOneAndDelete({
                            user_id: user_id,
                            order_id: addOrder._id,
                        });
                        yield OrderStatus_1.default.deleteMany({ order_id: addOrder._id });
                        yield Order_1.default.findOneAndDelete({
                            user_id: user_id,
                            order_id: order_id,
                        });
                    }
                }
                return ResponseHelper_1.default.api(res, true, req.lang["OrderPlacedSuccess"], addOrder, startTime);
            }
            catch (err) {
                return next(err);
            }
        });
    }
}
exports.HomeController = HomeController;
