"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 __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getLastId = exports.insertMessageContactCache = exports.escapeCharCache = exports.createOrUpdateContactCache = exports.updateContactCacheById = exports.deleteContactsByIdCache = exports.searchContactCache = exports.loadContactsCache = void 0;
const unflatten = require('flat').unflatten;
var flatten = require('flat');
const ListContactsServiceCache_1 = __importDefault(require("../services/ContactServices/ListContactsServiceCache"));
const TicketCache_1 = require("./TicketCache");
const deleteContactsByIdCache = (id) => __awaiter(void 0, void 0, void 0, function* () {
    const redis = yield TicketCache_1.redisConn();
    if (!redis)
        return;
    //  if (redis.status !== 'connect') return
    const contact_cache = yield redis.hgetall(`contact:${id}`);
    try {
        if (contact_cache && Object.keys(contact_cache).length > 0) {
            yield redis.del(`contact:${id}`);
            console.log(`Contacts cache number ${contact_cache['number']} deleted!`);
        }
        else {
            console.log('CONTACT CACHE NOT FOUND!');
        }
    }
    catch (error) {
        console.log(`There was an error on deleteContactsByIdCache:  ${error}`);
    }
    // await redis.quit()
});
exports.deleteContactsByIdCache = deleteContactsByIdCache;
const updateContactCache = (hash, json_object) => __awaiter(void 0, void 0, void 0, function* () {
    const redis = yield TicketCache_1.redisConn();
    if (!redis)
        return;
    //  if (redis.status !== 'connect') return
    const pipeline = redis.pipeline();
    let entries = Object.entries(json_object);
    entries.forEach((e) => {
        pipeline.hset(hash, e[0], e[1]);
    });
    yield pipeline.exec(() => { console.log("Key/value inserted/updated"); });
    // await redis.quit()
});
const updateContactCacheById = (id, update_fields) => __awaiter(void 0, void 0, void 0, function* () {
    const redis = yield TicketCache_1.redisConn();
    if (!redis)
        return;
    //  if (redis.status !== 'connect') return
    const contact_cache = yield redis.hgetall(`contact:${id}`);
    try {
        if (contact_cache && Object.keys(contact_cache).length > 0) {
            // await redis.del(`contact:${id}`) 
            update_fields.escaped_name = escapeCharCache(update_fields.name);
            yield updateContactCache(`contact:${id}`, update_fields);
            console.log(`CONTACT ${contact_cache['number']} CACHE WAS UPDATED!`);
        }
        else {
            console.log('CONTACT CACHE NOT FOUND!');
        }
    }
    catch (error) {
        console.log(`There was an error on updateContactCacheById:  ${error}`);
    }
    // await redis.quit()
});
exports.updateContactCacheById = updateContactCacheById;
const createOrUpdateContactCache = (hash, contact) => __awaiter(void 0, void 0, void 0, function* () {
    const redis = yield TicketCache_1.redisConn();
    if (!redis)
        return;
    //  if (redis.status !== 'connect') return
    if (contact.name) {
        contact.escaped_name = escapeCharCache(contact.name);
    }
    yield redis.hmset(hash, contact);
    // await redis.quit()
});
exports.createOrUpdateContactCache = createOrUpdateContactCache;
function searchContactCache(search, offset, limit) {
    return __awaiter(this, void 0, void 0, function* () {
        const redis = yield TicketCache_1.redisConn();
        if (!redis)
            return;
        //  if (redis.status !== 'connect') return null
        search = escapeCharCache(search);
        const response = yield redis.call('FT.SEARCH', 'idx_contact_message', `(@escaped_name:*${search}*)|(@number:*${search}*)`, 'LIMIT', offset, limit, 'SORTBY', 'escaped_name', 'ASC');
        // await redis.quit()
        if (response.length === 1) {
            return [];
        }
        const results = [];
        for (let n = 2; n < response.length; n += 2) {
            const result = {};
            const fieldNamesAndValues = response[n];
            for (let m = 0; m < fieldNamesAndValues.length; m += 2) {
                const k = fieldNamesAndValues[m];
                const v = fieldNamesAndValues[m + 1];
                result[k] = v;
            }
            results.push(result);
        }
        return results;
    });
}
exports.searchContactCache = searchContactCache;
const removeExtraSpace = (str) => {
    str = str.replace(/^\s+/g, '');
    return str.replace(/\s+/g, ' ');
};
const escapeCharCache = (str) => {
    const pattern = /[\'|\"|\.|\,|\;|\<|\>|\{|\}|\[|\]|\"|\'|\=|\~|\*|\:|\#|\+|\^|\$|\@|\%|\!|\&|\)|\(|/|\-|\\)]/g; // no match, use replace function.
    let newStr = str.replace(pattern, (t1) => `\\${t1}`);
    newStr = removeExtraSpace(newStr);
    return newStr.trim();
};
exports.escapeCharCache = escapeCharCache;
const getLastId = (hash) => __awaiter(void 0, void 0, void 0, function* () {
    const redis = yield TicketCache_1.redisConn();
    if (!redis)
        return;
    //  if (redis.status !== 'connect') return
    const contact_cache = yield redis.hgetall(hash);
    return contact_cache;
});
exports.getLastId = getLastId;
const insertMessageContactCache = (hash, contact_message) => __awaiter(void 0, void 0, void 0, function* () {
    const redis = yield TicketCache_1.redisConn();
    if (!redis)
        return;
    //  if (redis.status !== 'connect') return
    yield redis.hmset(hash, contact_message);
    console.log('CREATED/UPDATED CONTACT MESSAGE');
    // await redis.quit()
});
exports.insertMessageContactCache = insertMessageContactCache;
const loadContactsCache = () => __awaiter(void 0, void 0, void 0, function* () {
    yield createContactMessageIndexCache('idx_contact_message');
    const redis = yield TicketCache_1.redisConn();
    if (!redis)
        return;
    //  if (redis.status !== 'connect') return
    let contacts = yield ListContactsServiceCache_1.default();
    const pipeline = redis.pipeline();
    for (let i = 0; i < contacts.length; i++) {
        contacts[i].createdAt = new Date(contacts[i].createdAt).toISOString();
        contacts[i].updatedAt = new Date(contacts[i].updatedAt).toISOString();
        contacts[i].escaped_name = escapeCharCache(contacts[i].name);
        pipeline.hmset(`contact:${contacts[i].id}`, contacts[i]);
    }
    yield pipeline.exec(() => { console.log(`${contacts.length} CONTACTS INSERTED IN CACHE!`); });
    // await redis.quit()
});
exports.loadContactsCache = loadContactsCache;
const createContactMessageIndexCache = (hashIndex) => __awaiter(void 0, void 0, void 0, function* () {
    const redis = yield TicketCache_1.redisConn();
    if (!redis)
        return;
    //  if (redis.status !== 'connect') return
    try {
        const lst_index_redis = yield redis.call('FT._LIST');
        if (lst_index_redis.includes(hashIndex)) {
            console.log('entrou...');
            yield redis.call('FT.DROPINDEX', hashIndex);
        }
        const response = yield redis.call('FT.CREATE', hashIndex, 'ON', 'HASH', 'PREFIX', '1', 'contact_message:', 'SCHEMA', 'number', 'TEXT', 'SORTABLE');
        console.log('contact_message index created: ', response);
    }
    catch (error) {
        console.log('There was an error on contact_message: ', error);
    }
    // await redis.quit()
});
