"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.UserPackageOrderService = void 0;
const uuid_1 = require("uuid");
const database_1 = require("../application/database");
const response_error_1 = require("../error/response-error");
const user_package_order_model_1 = require("../model/user-package-order-model");
const validation_1 = require("../validation/validation");
const user_package_order_validation_1 = require("../validation/user-package-order-validation");
class UserPackageOrderService {
    static create(request) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the create request
            const createRequest = validation_1.Validation.validate(user_package_order_validation_1.UserPackageOrderValidation.CREATE, request);
            // Generate a UUID for the new user package order
            const userPackageOrderId = (0, uuid_1.v4)();
            // Create the user package order
            yield database_1.db.query(`
        INSERT INTO user_package_order (id, full_name, email, whatsapp_number, user_package_id)
        VALUES (?, ?, ?, ?, ?)
      `, [
                userPackageOrderId,
                createRequest.full_name,
                createRequest.email,
                createRequest.whatsapp_number,
                createRequest.user_package_id,
            ]);
        });
    }
    static getAll(queryParams) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the query parameters
            const queryRequest = validation_1.Validation.validate(user_package_order_validation_1.UserPackageOrderValidation.QUERY, queryParams);
            // Calculate the skip value
            const skip = (queryRequest.page - 1) * queryRequest.limit;
            // Create the WHERE clause
            let filterQuery = 'WHERE 1 = 1';
            const filterParams = [];
            if (queryRequest.search) {
                filterQuery += ' AND (full_name LIKE ? OR email LIKE ? OR whatsapp_number LIKE ?)';
                filterParams.push(`%${queryRequest.search}%`, `%${queryRequest.search}%`, `%${queryRequest.search}%`);
            }
            // Create the ORDER BY clause
            const sortField = queryRequest.sort || 'created_at';
            const sortOrder = queryRequest.order || 'desc';
            // Execute the query
            const userPackageOrders = yield database_1.db.query(`
        SELECT
          upo.*,
          JSON_OBJECT(
            'id', up.id,
            'number_of_pax', up.number_of_pax,
            'transportation', JSON_OBJECT('name', t.name),
            'flight', JSON_OBJECT('name', f.name),
            'travel_duration', up.travel_duration,
            'mekkah_duration', up.mekkah_duration,
            'madinah_duration', up.madinah_duration,
            'hotelMekkah', JSON_OBJECT('name', hm.name),
            'hotelMadinah', JSON_OBJECT('name', hmd.name),
            'muthawif', JSON_OBJECT('name', m.name),
            'handling', JSON_OBJECT('name', hd.name),
            'total_price', up.total_price,
            'per_pax_price', up.per_pax_price
          ) AS user_package
        FROM user_package_order upo
        JOIN user_package up ON upo.user_package_id = up.id
        LEFT JOIN user_package_option t ON up.transportation_id = t.id
        LEFT JOIN user_package_option f ON up.flight_id = f.id
        LEFT JOIN user_package_option hm ON up.hotel_mekkah_id = hm.id
        LEFT JOIN user_package_option hmd ON up.hotel_madinah_id = hmd.id
        LEFT JOIN user_package_option m ON up.muthawif_id = m.id
        LEFT JOIN user_package_option hd ON up.handling_id = hd.id
        ${filterQuery}
        ORDER BY ${sortField} ${sortOrder}
        LIMIT ? OFFSET ?
      `, [...filterParams, queryRequest.limit, skip]);
            // Get total count of userPackageOrders matching the filter criteria
            const count = yield database_1.db.queryOne(`
        SELECT COUNT(*) AS total
        FROM user_package_order upo
        JOIN user_package up ON upo.user_package_id = up.id
        LEFT JOIN user_package_option t ON up.transportation_id = t.id
        LEFT JOIN user_package_option f ON up.flight_id = f.id
        LEFT JOIN user_package_option hm ON up.hotel_mekkah_id = hm.id
        LEFT JOIN user_package_option hmd ON up.hotel_madinah_id = hmd.id
        LEFT JOIN user_package_option m ON up.muthawif_id = m.id
        LEFT JOIN user_package_option hd ON up.handling_id = hd.id
        ${filterQuery}
      `, filterParams);
            if (!count) {
                throw new response_error_1.ResponseError(404, 'User package orders tidak ditemukan');
            }
            // Map the results to the response format
            return {
                data: userPackageOrders.map((order) => (0, user_package_order_model_1.toUserPackageOrderResponse)(order, JSON.parse(order.user_package))),
                pagination: {
                    total: count.total,
                    current_page: queryRequest.page,
                    total_pages: Math.ceil(count.total / queryRequest.limit),
                    limit: queryRequest.limit,
                },
            };
        });
    }
    static delete(id) {
        return __awaiter(this, void 0, void 0, function* () {
            // Check if the user package order exists
            const userPackageOrder = yield database_1.db.queryOne('SELECT id FROM user_package_order WHERE id = ? LIMIT 1', [id]);
            if (!userPackageOrder) {
                throw new response_error_1.ResponseError(404, 'User package order tidak ditemukan');
            }
            // Delete the user package order
            yield database_1.db.query('DELETE FROM user_package_order WHERE id = ?', [id]);
        });
    }
}
exports.UserPackageOrderService = UserPackageOrderService;
