"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, _PeriodService_checkPeriodExist;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PeriodService = void 0;
const uuid_1 = require("uuid");
const database_1 = require("../application/database");
const response_error_1 = require("../error/response-error");
const period_model_1 = require("../model/period-model");
const period_validation_1 = require("../validation/period-validation");
const validation_1 = require("../validation/validation");
class PeriodService {
    static create(request) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the create request
            const createRequest = validation_1.Validation.validate(period_validation_1.PeriodValidation.CREATE, request);
            // Generate a UUID for the new period
            const periodId = (0, uuid_1.v4)();
            // Insert the new period into the database with the UUID
            yield database_1.db.query('INSERT INTO period (id, category, start_date, end_date) VALUES (?, ?, ?, ?)', [
                periodId,
                createRequest.category,
                createRequest.start_date,
                createRequest.end_date,
            ]);
            // Retrieve the newly created period by the UUID
            const period = yield database_1.db.queryOne('SELECT * FROM period WHERE id = ? LIMIT 1', [periodId]);
            if (!period) {
                throw new response_error_1.ResponseError(500, 'Failed to create period');
            }
            // Get all hotels
            const hotels = yield database_1.db.query('SELECT * FROM hotel');
            // Create period prices for each hotel
            const periodPricesData = hotels.map((hotel) => ({
                hotel_id: hotel.id,
                period_id: period.id,
                price_double: 0,
                price_triple: 0,
                price_quad: 0,
            }));
            // Insert period prices into the database
            yield database_1.db.query('INSERT INTO hotel_period_price (id, hotel_id, period_id, price_double, price_triple, price_quad) VALUES ?', [
                periodPricesData.map((price) => [(0, uuid_1.v4)(), price.hotel_id, price.period_id, price.price_double, price.price_triple, price.price_quad]),
            ]);
            return (0, period_model_1.toPeriodResponse)(period);
        });
    }
    static update(id, request) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the update request
            const updateRequest = validation_1.Validation.validate(period_validation_1.PeriodValidation.UPDATE, request);
            // Check if the period exists
            yield __classPrivateFieldGet(this, _a, "m", _PeriodService_checkPeriodExist).call(this, id);
            // Update the period in the database
            yield database_1.db.query('UPDATE period SET category = ?, start_date = ?, end_date = ? WHERE id = ?', [
                updateRequest.category,
                updateRequest.start_date,
                updateRequest.end_date,
                id,
            ]);
            // Retrieve the updated period by the UUID
            const period = yield database_1.db.queryOne('SELECT * FROM period WHERE id = ? LIMIT 1', [id]);
            if (!period) {
                throw new response_error_1.ResponseError(500, 'Failed to update period');
            }
            return (0, period_model_1.toPeriodResponse)(period);
        });
    }
    static delete(id) {
        return __awaiter(this, void 0, void 0, function* () {
            // Retrieve the period before deleting
            const period = yield database_1.db.queryOne('SELECT * FROM period WHERE id = ? LIMIT 1', [id]);
            if (!period) {
                throw new response_error_1.ResponseError(500, 'Failed to delete period');
            }
            // Delete the period from the database
            yield database_1.db.query('DELETE FROM period WHERE id = ?', [id]);
            return (0, period_model_1.toPeriodResponse)(period);
        });
    }
    static getById(id) {
        return __awaiter(this, void 0, void 0, function* () {
            // Retrieve a single period by ID
            const period = yield database_1.db.queryOne('SELECT * FROM period WHERE id = ? LIMIT 1', [id]);
            if (!period) {
                throw new response_error_1.ResponseError(404, 'Period not found');
            }
            return (0, period_model_1.toPeriodResponse)(period);
        });
    }
    static getAll() {
        return __awaiter(this, void 0, void 0, function* () {
            // Retrieve all periods from the database
            const periods = yield database_1.db.query('SELECT * FROM period ORDER BY start_date ASC');
            // Map each period to the response format
            return periods.map(period_model_1.toPeriodResponse);
        });
    }
}
exports.PeriodService = PeriodService;
_a = PeriodService, _PeriodService_checkPeriodExist = function _PeriodService_checkPeriodExist(id) {
    return __awaiter(this, void 0, void 0, function* () {
        // Check if the period exists
        const period = yield database_1.db.queryOne('SELECT id FROM period WHERE id = ? LIMIT 1', [id]);
        if (!period) {
            throw new response_error_1.ResponseError(404, 'Period not found');
        }
    });
};
