"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.ContactService = void 0;
const uuid_1 = require("uuid");
const database_1 = require("../application/database");
const response_error_1 = require("../error/response-error");
const contact_model_1 = require("../model/contact-model");
const contact_validation_1 = require("../validation/contact-validation");
const validation_1 = require("../validation/validation");
class ContactService {
    static create(request) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the create request
            const createRequest = validation_1.Validation.validate(contact_validation_1.ContactValidation.CREATE, request);
            // Generate a UUID for the new contact
            const contactId = (0, uuid_1.v4)();
            // Insert the new contact into the database with the UUID
            yield database_1.db.query('INSERT INTO contact (id, name, value) VALUES (?, ?, ?)', [
                contactId,
                createRequest.name,
                createRequest.value,
            ]);
            // Retrieve the newly created contact by the UUID
            const contact = yield database_1.db.queryOne('SELECT * FROM contact WHERE id = ? LIMIT 1', [contactId]);
            if (!contact) {
                throw new response_error_1.ResponseError(500, 'Failed to create contact');
            }
            return (0, contact_model_1.toContactResponse)(contact);
        });
    }
    static bulkUpdate(requests) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the bulk update request
            const bulkUpdateRequest = validation_1.Validation.validate(contact_validation_1.ContactValidation.BULK_UPDATE, requests);
            // Start a transaction for batch processing
            yield database_1.db.transaction((conn) => __awaiter(this, void 0, void 0, function* () {
                for (const updateRequest of bulkUpdateRequest) {
                    const fieldsToUpdate = [];
                    const values = [];
                    // Add `name` to the update if provided
                    if (updateRequest.name !== undefined) {
                        fieldsToUpdate.push('name = ?');
                        values.push(updateRequest.name);
                    }
                    // Add `value` to the update if provided
                    if (updateRequest.value !== undefined) {
                        fieldsToUpdate.push('value = ?');
                        values.push(updateRequest.value);
                    }
                    // Skip this update if no fields are provided
                    if (fieldsToUpdate.length === 0)
                        continue;
                    // Add ID at the end for the WHERE clause
                    values.push(updateRequest.id);
                    // Execute the dynamic update query
                    const query = `UPDATE contact SET ${fieldsToUpdate.join(', ')} WHERE id = ?`;
                    yield conn.query(query, values);
                }
            }));
        });
    }
    static delete(id) {
        return __awaiter(this, void 0, void 0, function* () {
            // Retrieve the contact before deleting it
            const contact = yield database_1.db.queryOne('SELECT * FROM contact WHERE id = ?', [id]);
            if (!contact) {
                throw new response_error_1.ResponseError(404, 'Contact not found');
            }
            // Delete the contact from the database
            yield database_1.db.query('DELETE FROM contact WHERE id = ?', [id]);
            return (0, contact_model_1.toContactResponse)(contact);
        });
    }
    static getAll() {
        return __awaiter(this, void 0, void 0, function* () {
            // Retrieve all contacts from the database
            const contacts = yield database_1.db.query('SELECT * FROM contact ORDER BY created_at ASC');
            // Map each contact to the response format
            return contacts.map(contact_model_1.toContactResponse);
        });
    }
    static getByName(name) {
        return __awaiter(this, void 0, void 0, function* () {
            // Retrieve a single contact by name
            const contact = yield database_1.db.queryOne('SELECT * FROM contact WHERE name = ?', [name]);
            if (!contact) {
                throw new response_error_1.ResponseError(404, 'Contact not found');
            }
            return (0, contact_model_1.toContactResponse)(contact);
        });
    }
}
exports.ContactService = ContactService;
