"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());
    });
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
    return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _a, _UserPackageService_calculateTotal;
Object.defineProperty(exports, "__esModule", { value: true });
exports.UserPackageService = void 0;
const uuid_1 = require("uuid");
const database_1 = require("../application/database");
const response_error_1 = require("../error/response-error");
const user_package_validation_1 = require("../validation/user-package-validation");
const validation_1 = require("../validation/validation");
class UserPackageService {
    static create(request) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the create request
            const createRequest = validation_1.Validation.validate(user_package_validation_1.UserPackageValidation.CREATE, request);
            // Calculate the total price
            const total_price = yield __classPrivateFieldGet(this, _a, "m", _UserPackageService_calculateTotal).call(this, createRequest);
            // Generate a UUID for the new user package
            const userPackageId = (0, uuid_1.v4)();
            // Create the user package
            yield database_1.db.query(`
      INSERT INTO user_package (id, transportation_id, flight_id, hotel_mekkah_id, hotel_madinah_id, muthawif_id, handling_id, number_of_pax, travel_duration, mekkah_duration, madinah_duration, per_pax_price, total_price)
      VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)
    `, [
                userPackageId,
                createRequest.transportation_id,
                createRequest.flight_id,
                createRequest.hotel_mekkah_id,
                createRequest.hotel_madinah_id,
                createRequest.muthawif_id,
                createRequest.handling_id,
                createRequest.number_of_pax,
                createRequest.travel_duration,
                createRequest.mekkah_duration,
                createRequest.madinah_duration,
                total_price / createRequest.number_of_pax,
                total_price,
            ]);
            return { id: userPackageId };
        });
    }
    static get(id) {
        return __awaiter(this, void 0, void 0, function* () {
            // Retrieve the user package by ID
            const userPackage = yield database_1.db.queryOne(`
      SELECT
        up.*,
        t.name AS transportation,
        f.name AS flight,
        hm.name AS hotel_mekkah,
        hmd.name AS hotel_madinah,
        m.name AS muthawif,
        hd.name AS handling
      FROM user_package up
      JOIN user_package_option t ON up.transportation_id = t.id
      JOIN user_package_option f ON up.flight_id = f.id
      JOIN user_package_option hm ON up.hotel_mekkah_id = hm.id
      JOIN user_package_option hmd ON up.hotel_madinah_id = hmd.id
      JOIN user_package_option m ON up.muthawif_id = m.id
      JOIN user_package_option hd ON up.handling_id = hd.id
      WHERE up.id = ?
      `, [id]);
            if (!userPackage) {
                throw new response_error_1.ResponseError(404, 'User package not found');
            }
            return userPackage;
        });
    }
}
exports.UserPackageService = UserPackageService;
_a = UserPackageService, _UserPackageService_calculateTotal = function _UserPackageService_calculateTotal(request) {
    return __awaiter(this, void 0, void 0, function* () {
        // Retrieve the prices of each user package option
        const [transportation, flight, hotelMekkah, hotelMadinah, muthawif, handling] = yield Promise.all([
            database_1.db.queryOne('SELECT price FROM user_package_option WHERE id = ? LIMIT 1', [request.transportation_id]),
            database_1.db.queryOne('SELECT price FROM user_package_option WHERE id = ? LIMIT 1', [request.flight_id]),
            database_1.db.queryOne('SELECT price FROM user_package_option WHERE id = ? LIMIT 1', [request.hotel_mekkah_id]),
            database_1.db.queryOne('SELECT price FROM user_package_option WHERE id = ? LIMIT 1', [request.hotel_madinah_id]),
            database_1.db.queryOne('SELECT price FROM user_package_option WHERE id = ? LIMIT 1', [request.muthawif_id]),
            database_1.db.queryOne('SELECT price FROM user_package_option WHERE id = ? LIMIT 1', [request.handling_id]),
        ]);
        // Check if any of the user package options are not found
        if (!transportation || !flight || !hotelMekkah || !hotelMadinah || !muthawif || !handling) {
            throw new response_error_1.ResponseError(404, 'User package items not found');
        }
        // Calculate the total price
        let total_price = 0;
        total_price += parseFloat(transportation.price);
        total_price += parseFloat(flight.price);
        total_price += parseFloat(hotelMekkah.price) * request.mekkah_duration;
        total_price += parseFloat(hotelMadinah.price) * request.madinah_duration;
        total_price += parseFloat(muthawif.price);
        total_price += parseFloat(handling.price);
        total_price *= request.number_of_pax;
        return total_price;
    });
};
