"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.UserPackageOptionService = void 0;
const uuid_1 = require("uuid");
const database_1 = require("../application/database");
const response_error_1 = require("../error/response-error");
const user_package_option_validation_1 = require("../validation/user-package-option-validation");
const validation_1 = require("../validation/validation");
const user_package_option_model_1 = require("../model/user-package-option-model");
class UserPackageOptionService {
    static getAll() {
        return __awaiter(this, void 0, void 0, function* () {
            // Fetch all user package options
            const options = yield database_1.db.query(`
      SELECT
        upo.*,
        JSON_OBJECT('name', pt.name) AS packageType
      FROM
        user_package_option upo
      JOIN
        package_type pt ON upo.package_type_id = pt.id
      ORDER BY
        upo.order_number ASC
    `);
            // Parse packageType JSON object
            options.forEach((option) => {
                if (typeof option.packageType === 'string') {
                    option.packageType = JSON.parse(option.packageType);
                }
            });
            if (!options) {
                throw new response_error_1.ResponseError(404, 'User package options tidak ditemukan');
            }
            return options.map(user_package_option_model_1.toUserPackageOptionResponse);
        });
    }
    static getByType(type) {
        return __awaiter(this, void 0, void 0, function* () {
            // Format package type name
            type = type.replace(/-/g, ' ');
            // Fetch package type ID
            const packageType = yield database_1.db.queryOne(`SELECT id FROM package_type WHERE name = ?`, [type]);
            if (!packageType) {
                throw new response_error_1.ResponseError(404, 'Package type tidak ditemukan');
            }
            // Fetch user package options by package type ID
            const options = yield database_1.db.query(`
      SELECT
        upo.*,
        JSON_OBJECT('name', pt.name) AS packageType
      FROM
        user_package_option upo
      JOIN
        package_type pt ON upo.package_type_id = pt.id
      WHERE
        upo.package_type_id = ?
      ORDER BY
        upo.order_number ASC
    `, [packageType.id]);
            // Parse packageType JSON object
            options.forEach((option) => {
                if (typeof option.packageType === 'string') {
                    option.packageType = JSON.parse(option.packageType);
                }
            });
            if (!options) {
                throw new response_error_1.ResponseError(404, 'User package options tidak ditemukan');
            }
            return options.map(user_package_option_model_1.toUserPackageOptionResponse);
        });
    }
    static bulkUpdate(request) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the bulk update request
            const { type, modifiedData, deletedData } = request;
            const validatedModifiedData = modifiedData === null || modifiedData === void 0 ? void 0 : modifiedData.map((service) => validation_1.Validation.validate(user_package_option_validation_1.UserPackageOptionValidation.BULK_UPDATE, service));
            // Fetch package type ID
            const serviceType = yield database_1.db.queryOne(`SELECT id FROM package_type WHERE name = ?`, [
                type.replace(/-/g, ' '),
            ]);
            if (!serviceType) {
                throw new response_error_1.ResponseError(404, 'Service type not found');
            }
            // handle update and create
            if (validatedModifiedData.length > 0) {
                yield database_1.db.transaction((conn) => __awaiter(this, void 0, void 0, function* () {
                    yield Promise.all(validatedModifiedData.map((service) => __awaiter(this, void 0, void 0, function* () {
                        if (service.id) {
                            yield conn.query('UPDATE user_package_option SET name = ?, price = ?, order_number = ? WHERE id = ?', [
                                service.name,
                                service.price,
                                service.order_number,
                                service.id,
                            ]);
                        }
                        else {
                            yield conn.query('INSERT INTO user_package_option (id, name, price, package_type_id, order_number) VALUES (?, ?, ?, ?, ?)', [(0, uuid_1.v4)(), service.name || '', service.price || 0, serviceType.id, service.order_number]);
                        }
                    })));
                }));
            }
            // handle delete
            if (deletedData.length > 0) {
                yield database_1.db.transaction((conn) => __awaiter(this, void 0, void 0, function* () {
                    yield conn.query('DELETE FROM user_package_option WHERE id IN (?)', [deletedData]);
                }));
            }
        });
    }
}
exports.UserPackageOptionService = UserPackageOptionService;
