"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.MitraPackageOrderService = void 0;
const uuid_1 = require("uuid");
const database_1 = require("../application/database");
const response_error_1 = require("../error/response-error");
const mitra_package_order_validation_1 = require("../validation/mitra-package-order-validation");
const validation_1 = require("../validation/validation");
class MitraPackageOrderService {
    static create(user, request) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the create request
            const createRequest = validation_1.Validation.validate(mitra_package_order_validation_1.MitraPackageOrderValidation.CREATE, request);
            // Check if the mitra package exists
            const mitraPackage = yield database_1.db.queryOne('SELECT id FROM mitra_package WHERE id = ? LIMIT 1', [
                createRequest.mitra_package_id,
            ]);
            if (!mitraPackage) {
                throw new response_error_1.ResponseError(404, 'Mitra package not found');
            }
            // Generate a UUID for the new mitra package order
            const mitraPackageOrderId = (0, uuid_1.v4)();
            // Insert the new mitra package order into the database with the UUID
            yield database_1.db.query('INSERT INTO mitra_package_order (id, user_id, mitra_package_id) VALUES (?, ?, ?)', [
                mitraPackageOrderId,
                user.id,
                createRequest.mitra_package_id,
            ]);
        });
    }
    static getAll(queryParams) {
        return __awaiter(this, void 0, void 0, function* () {
            var _a;
            // Validate the query parameters
            const queryRequest = validation_1.Validation.validate(mitra_package_order_validation_1.MitraPackageOrderValidation.QUERY, queryParams);
            // Calculate the offset and limit for pagination
            const skip = (queryRequest.page - 1) * queryRequest.limit;
            const limit = queryRequest.limit;
            let filterQuery = '';
            let filterParams = [];
            // Build the WHERE clause for filtering by search term
            if (queryRequest.search) {
                const searchTerm = `%${queryRequest.search.toLowerCase()}%`;
                filterQuery = `
        WHERE LOWER(User.full_name) LIKE ? 
        OR LOWER(User.email) LIKE ? 
        OR LOWER(User.whatsapp_number) LIKE ?
      `;
                filterParams = [searchTerm, searchTerm, searchTerm];
            }
            // Build the ORDER BY clause for sorting
            const sortFieldMap = {
                'User.email': 'User.email',
                'User.full_name': 'User.full_name',
                'User.whatsapp_number': 'User.whatsapp_number',
                'mitra_package.per_pax_price_double': 'mitra_package.per_pax_price_double',
                'mitra_package.per_pax_price_triple': 'mitra_package.per_pax_price_triple',
                'mitra_package.per_pax_price_quad': 'mitra_package.per_pax_price_quad',
                created_at: 'mitra_package_order.created_at',
                updated_at: 'mitra_package_order.updated_at',
            };
            const sortField = sortFieldMap[(_a = queryRequest.sort) !== null && _a !== void 0 ? _a : 'created_at'] || 'created_at';
            const sortOrder = queryRequest.order === 'asc' ? 'ASC' : 'DESC';
            // Build the main query to fetch the mitra package orders
            const mainQuery = `
      SELECT mitra_package_order.*, 
             user.id as user_id, user.full_name, user.email, user.whatsapp_number, user.role,
             mitra_package.id as mitra_package_id, mitra_package.per_pax_price_double, 
             mitra_package.per_pax_price_triple, mitra_package.per_pax_price_quad
      FROM mitra_package_order
      JOIN user ON mitra_package_order.user_id = user.id
      JOIN mitra_package ON mitra_package_order.mitra_package_id = mitra_package.id
      ${filterQuery}
      ORDER BY ${sortField} ${sortOrder}
      LIMIT ? OFFSET ?
    `;
            // Build the query to fetch the total number of results
            const totalCountQuery = `
      SELECT COUNT(*) as total
      FROM mitra_package_order
      JOIN User ON mitra_package_order.user_id = User.id
      ${filterQuery}
    `;
            try {
                // Fetch the mitra package orders and total number of results from the database
                const mitraPackageOrders = yield database_1.db.query(mainQuery, [...filterParams, limit, skip]);
                const totalResult = yield database_1.db.query(totalCountQuery, filterParams);
                const total = totalResult[0].total;
                // Transform the database rows to match the expected MitraPackageOrderResponse structure
                const formattedOrders = mitraPackageOrders.map((order) => ({
                    id: order.id,
                    user: {
                        id: order.user_id,
                        full_name: order.full_name,
                        email: order.email,
                        whatsapp_number: order.whatsapp_number,
                        role: order.role,
                        created_at: new Date(),
                        updated_at: new Date(),
                    },
                    mitra_package_id: order.mitra_package_id,
                    per_pax_price_double: Number(order.per_pax_price_double),
                    per_pax_price_triple: Number(order.per_pax_price_triple),
                    per_pax_price_quad: Number(order.per_pax_price_quad),
                    created_at: order.created_at,
                    updated_at: order.updated_at,
                }));
                return {
                    data: formattedOrders,
                    pagination: {
                        total,
                        current_page: queryRequest.page,
                        total_pages: Math.ceil(total / queryRequest.limit),
                        limit: queryRequest.limit,
                    },
                };
            }
            catch (error) {
                console.error(error);
                throw new Error('Failed to fetch MitraPackage orders');
            }
        });
    }
    static getAllByUser(user) {
        return __awaiter(this, void 0, void 0, function* () {
            // Fetch the mitra package orders for the user from the
            const mitraPackageOrders = yield database_1.db.query(`
      SELECT mitra_package_order.*, 
             user.id as user_id, user.full_name, user.email, user.whatsapp_number, user.role,
             mitra_package.id as mitra_package_id, mitra_package.per_pax_price_double, 
             mitra_package.per_pax_price_triple, mitra_package.per_pax_price_quad
      FROM mitra_package_order
      JOIN user ON mitra_package_order.user_id = user.id
      JOIN mitra_package ON mitra_package_order.mitra_package_id = mitra_package.id
      WHERE user.id = ?
    `, [user.id]);
            // Transform the database rows to match the expected MitraPackageOrderResponse structure
            return mitraPackageOrders.map((order) => ({
                id: order.id,
                user: {
                    id: order.user_id,
                    full_name: order.full_name,
                    email: order.email,
                    whatsapp_number: order.whatsapp_number,
                    role: order.role,
                    created_at: new Date(),
                    updated_at: new Date(),
                },
                mitra_package_id: order.mitra_package_id,
                per_pax_price_double: Number(order.per_pax_price_double),
                per_pax_price_triple: Number(order.per_pax_price_triple),
                per_pax_price_quad: Number(order.per_pax_price_quad),
                created_at: order.created_at,
                updated_at: order.updated_at,
            }));
        });
    }
    static get(id) {
        return __awaiter(this, void 0, void 0, function* () {
            // Fetch the mitra package order from the database
            const mitraPackageOrder = yield database_1.db.queryOne(`
      SELECT mitra_package_order.*, 
             user.id as user_id, user.full_name, user.email, user.whatsapp_number, user.role,
             mitra_package.id as mitra_package_id, mitra_package.per_pax_price_double, 
             mitra_package.per_pax_price_triple, mitra_package.per_pax_price_quad
      FROM mitra_package_order
      JOIN user ON mitra_package_order.user_id = user.id
      JOIN mitra_package ON mitra_package_order.mitra_package_id = mitra_package.id
      WHERE mitra_package_order.id = ?
    `, [id]);
            if (!mitraPackageOrder) {
                throw new response_error_1.ResponseError(404, 'Mitra package order not found');
            }
            // Transform the database row to match the expected MitraPackageOrderResponse structure
            return {
                id: mitraPackageOrder.id,
                user: {
                    id: mitraPackageOrder.user_id,
                    full_name: mitraPackageOrder.full_name,
                    email: mitraPackageOrder.email,
                    whatsapp_number: mitraPackageOrder.whatsapp_number,
                    role: mitraPackageOrder.role,
                    created_at: new Date(),
                    updated_at: new Date(),
                },
                mitra_package_id: mitraPackageOrder.mitra_package_id,
                per_pax_price_double: Number(mitraPackageOrder.per_pax_price_double),
                per_pax_price_triple: Number(mitraPackageOrder.per_pax_price_triple),
                per_pax_price_quad: Number(mitraPackageOrder.per_pax_price_quad),
                created_at: mitraPackageOrder.created_at,
                updated_at: mitraPackageOrder.updated_at,
            };
        });
    }
    static delete(id) {
        return __awaiter(this, void 0, void 0, function* () {
            // Check if the mitra package order exists
            const mitraPackageOrder = yield database_1.db.queryOne('SELECT id FROM mitra_package_order WHERE id = ? LIMIT 1', [
                id,
            ]);
            if (!mitraPackageOrder) {
                throw new response_error_1.ResponseError(404, 'Mitra package order not found');
            }
            // Delete the mitra package order from the database
            yield database_1.db.query('DELETE FROM mitra_package_order WHERE id = ?', [id]);
        });
    }
}
exports.MitraPackageOrderService = MitraPackageOrderService;
