"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 __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _a, _ContentService_checkContentExist;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContentService = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const uuid_1 = require("uuid");
const database_1 = require("../application/database");
const response_error_1 = require("../error/response-error");
const content_model_1 = require("../model/content-model");
const content_validation_1 = require("../validation/content-validation");
const validation_1 = require("../validation/validation");
class ContentService {
    static create(request) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the create request
            const createRequest = validation_1.Validation.validate(content_validation_1.ContentValidation.CREATE, request);
            // Generate a UUID for the new content
            const contentId = (0, uuid_1.v4)();
            // Insert the new content into the database with the UUID
            yield database_1.db.query('INSERT INTO content (id, page, section, type, key, value) VALUES (?, ?, ?, ?, ?, ?, ?)', [
                contentId,
                createRequest.page,
                createRequest.section,
                createRequest.type,
                createRequest.key,
                JSON.stringify(createRequest.value),
            ]);
            // Retrieve the newly created content by the UUID
            const content = yield database_1.db.queryOne('SELECT * FROM content WHERE id = ? LIMIT 1', [contentId]);
            if (!content) {
                throw new response_error_1.ResponseError(500, 'Failed to create content');
            }
            return (0, content_model_1.toContentResponse)(content);
        });
    }
    static update(id, request) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the update request
            const updateRequest = validation_1.Validation.validate(content_validation_1.ContentValidation.UPDATE, request);
            // Check if the content exists
            yield __classPrivateFieldGet(this, _a, "m", _ContentService_checkContentExist).call(this, id);
            // Update the content in the database
            yield database_1.db.query('UPDATE content SET page = ?, section = ?, type = ?, key = ?, value = ? WHERE id = ?', [
                updateRequest.page,
                updateRequest.section,
                updateRequest.type,
                updateRequest.key,
                JSON.stringify(updateRequest.value),
                id,
            ]);
            // Retrieve the updated content by the UUID
            const content = yield database_1.db.queryOne('SELECT * FROM content WHERE id = ? LIMIT 1', [id]);
            if (!content) {
                throw new response_error_1.ResponseError(500, 'Failed to update content');
            }
            return (0, content_model_1.toContentResponse)(content);
        });
    }
    static updateValue(id, request, file) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the update value request
            const updateValueRequest = validation_1.Validation.validate(content_validation_1.ContentValidation.UPDATE_VALUE, request);
            // Get the value from the request
            const { value } = updateValueRequest;
            // Check if the content exists
            const currentContent = yield __classPrivateFieldGet(this, _a, "m", _ContentService_checkContentExist).call(this, id);
            // If the request contains a file, update the image path
            let updatedValue = value;
            let imagePath;
            if (file) {
                imagePath = `/public/content/${file.filename}`;
                const oldImagePath = currentContent.type === 'IMAGE'
                    ? currentContent.value.src
                    : currentContent.type === 'BENEFIT_CARD'
                        ? currentContent.value.imageSrc
                        : null;
                // Delete the old image if it exists
                if (oldImagePath) {
                    const fullOldImagePath = path_1.default.join(__dirname, '..', '..', oldImagePath);
                    if (fs_1.default.existsSync(fullOldImagePath)) {
                        fs_1.default.unlink(fullOldImagePath, (err) => {
                            if (err) {
                                console.error('Error deleting the old image:', err);
                            }
                            else {
                                console.log('Old image successfully deleted:', oldImagePath);
                            }
                        });
                    }
                }
            }
            // Update the value based on the content type
            if (currentContent.type === 'IMAGE') {
                updatedValue = {
                    src: imagePath || currentContent.value.src,
                };
            }
            else if (currentContent.type === 'BENEFIT_CARD') {
                updatedValue = {
                    imageSrc: imagePath || currentContent.value.imageSrc,
                    title: updatedValue.title,
                    description: updatedValue.description,
                };
            }
            // Update the content in the database
            yield database_1.db.query('UPDATE content SET value = ? WHERE id = ?', [JSON.stringify(updatedValue), id]);
            // Retrieve the updated content by ID
            const content = yield database_1.db.queryOne('SELECT * FROM content WHERE id = ?', [id]);
            if (!content) {
                throw new response_error_1.ResponseError(500, 'Failed to update content value');
            }
            return (0, content_model_1.toContentResponse)(content);
        });
    }
    static updateVisibility(id, visible) {
        return __awaiter(this, void 0, void 0, function* () {
            // Check if the content exists
            yield __classPrivateFieldGet(this, _a, "m", _ContentService_checkContentExist).call(this, id);
            // Update the visibility of the content in the database
            yield database_1.db.query('UPDATE content SET visible = ? WHERE id = ?', [visible, id]);
            // Retrieve the updated content by ID
            const content = yield database_1.db.queryOne('SELECT * FROM content WHERE id = ?', [id]);
            if (!content) {
                throw new response_error_1.ResponseError(500, 'Failed to update content visibility');
            }
            return (0, content_model_1.toContentResponse)(content);
        });
    }
    static delete(id) {
        return __awaiter(this, void 0, void 0, function* () {
            // Retrieve the content before deleting it
            const content = yield __classPrivateFieldGet(this, _a, "m", _ContentService_checkContentExist).call(this, id);
            // Delete the content from the database
            yield database_1.db.query('DELETE FROM content WHERE id = ?', [id]);
            return (0, content_model_1.toContentResponse)(content);
        });
    }
    static getAll() {
        return __awaiter(this, void 0, void 0, function* () {
            // Retrieve all content from the database
            const contents = yield database_1.db.query('SELECT * FROM content ORDER BY created_at ASC');
            // Map each content to the response format
            return contents.map(content_model_1.toContentResponse);
        });
    }
    static getAllByPage(page) {
        return __awaiter(this, void 0, void 0, function* () {
            // Retrieve all content from the database by page
            const contents = yield database_1.db.query('SELECT * FROM content WHERE page = ? ORDER BY created_at ASC', [page]);
            // Map each content to the response format
            return contents.map(content_model_1.toContentResponse);
        });
    }
    static getAllBySection(section) {
        return __awaiter(this, void 0, void 0, function* () {
            // Retrieve all content from the database by section
            const contents = yield database_1.db.query('SELECT * FROM content WHERE section = ? ORDER BY created_at ASC', [
                section,
            ]);
            // Map each content to the response format
            return contents.map(content_model_1.toContentResponse);
        });
    }
    static get(id) {
        return __awaiter(this, void 0, void 0, function* () {
            // Retrieve single content by ID
            const content = yield database_1.db.queryOne('SELECT * FROM content WHERE id = ? LIMIT 1', [id]);
            if (!content) {
                throw new response_error_1.ResponseError(404, 'Content not found');
            }
            return (0, content_model_1.toContentResponse)(content);
        });
    }
    static createColor(request) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the create request
            const createRequest = validation_1.Validation.validate(content_validation_1.ContentValidation.CREATE_COLOR, request);
            // Generate a UUID for the new color
            const colorId = (0, uuid_1.v4)();
            // Insert the new color into the database with the UUID
            yield database_1.db.query('INSERT INTO color (id, hex) VALUES (?, ?)', [colorId, createRequest.hex]);
            // Retrieve the newly created color by the UUID
            const color = yield database_1.db.queryOne('SELECT * FROM color WHERE id = ? LIMIT 1', [colorId]);
            if (!color) {
                throw new response_error_1.ResponseError(500, 'Failed to create color');
            }
            return color;
        });
    }
    static updateColors(request) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the update request
            const updateRequest = validation_1.Validation.validate(content_validation_1.ContentValidation.UPDATE_COLORS, request);
            // Start a transaction for batch processing
            yield database_1.db.transaction((conn) => __awaiter(this, void 0, void 0, function* () {
                for (const { id, hex } of updateRequest) {
                    // Update the color in the database
                    yield conn.query('UPDATE color SET hex = ? WHERE id = ?', [hex, id]);
                }
            }));
        });
    }
    static deleteColor(id) {
        return __awaiter(this, void 0, void 0, function* () {
            // Check if the color exists
            const existingColor = yield database_1.db.queryOne('SELECT id FROM color WHERE id = ? LIMIT 1', [id]);
            if (!existingColor) {
                throw new response_error_1.ResponseError(404, 'Color not found');
            }
            // Delete the color from the database
            yield database_1.db.query('DELETE FROM color WHERE id = ?', [id]);
        });
    }
    static getAllColors() {
        return __awaiter(this, void 0, void 0, function* () {
            // Retrieve all colors from the database
            const colors = yield database_1.db.query('SELECT * FROM color ORDER BY created_at ASC');
            // Map each color to the response
            return colors.map(content_model_1.toColorResponse);
        });
    }
    static getColor(id) {
        return __awaiter(this, void 0, void 0, function* () {
            // Retrieve a single color by ID
            const color = yield database_1.db.queryOne('SELECT * FROM color WHERE id = ? LIMIT 1', [id]);
            if (!color) {
                throw new response_error_1.ResponseError(404, 'Color not found');
            }
            return color;
        });
    }
}
exports.ContentService = ContentService;
_a = ContentService, _ContentService_checkContentExist = function _ContentService_checkContentExist(id) {
    return __awaiter(this, void 0, void 0, function* () {
        // Check if the content exists
        const content = yield database_1.db.queryOne('SELECT * FROM content WHERE id = ? LIMIT 1', [id]);
        if (!content) {
            throw new response_error_1.ResponseError(404, 'Content not found');
        }
        return content;
    });
};
