"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UserLogsService = void 0;
const mongoose_1 = __importDefault(require("mongoose"));
const user_logs_db_1 = require("../db/user-logs.db");
const UserLog_model_1 = require("../models/UserLog.model");
const DeletedRecords_model_1 = require("../models/DeletedRecords.model");
const createLogs = true;
class UserLogsService {
    banksService;
    borrowerDB;
    loanChargesService;
    constructor(banksService, borrowerDB, loanChargesService) {
        this.banksService = banksService;
        this.borrowerDB = borrowerDB;
        this.loanChargesService = loanChargesService;
    }
    async createUserLog(params) {
        if (createLogs) {
            await (0, user_logs_db_1.createLog)(params);
        }
    }
    async filterByBorrower(logs, borrowerId) {
        const products = await this.loanChargesService.getBorrowersLoanProducts(borrowerId);
        const productIds = products.map((product) => product._id.toString());
        return logs.filter((r) => {
            if (r.logType === UserLog_model_1.ELogType.LOAN_TRANSACTION && r.record) {
                return productIds.includes(r.record.productId.toString());
            }
            if (r.details && r.details.hasOwnProperty('borrowerId')) {
                if (r.details.borrowerId && r.details.borrowerId === borrowerId) {
                    return true;
                }
            }
            return false;
        });
    }
    async replaceBorrowers(logs) {
        const convertToMap = (arr) => {
            return arr.reduce((acc, item) => {
                acc.set(item._id.toString(), item.name);
                return acc;
            }, new Map());
        };
        const borrowers = await this.borrowerDB.getAllBorrowers();
        const borrowersMap = convertToMap(borrowers);
        const products = await this.loanChargesService.getAllLoanProducts();
        const productsMap = convertToMap(products);
        const banks = await this.banksService.getBanks();
        const banksMap = convertToMap(banks);
        const replacedFields = {
            borrowerId: borrowersMap,
            productId: productsMap,
            bankId: banksMap,
        };
        return logs.map((r) => {
            Object.keys(replacedFields).forEach((key) => {
                if (r.details && r.details.hasOwnProperty(key) && r.details[key]) {
                    r.details[key] = `${replacedFields[key].get(r.details[key].toString())} (${r.details[key].toString()})`;
                }
                if (r.record && r.record.hasOwnProperty(key) && r.record[key]) {
                    r.record[key] = `${replacedFields[key].get(r.record[key].toString())} (${r.record[key].toString()})`;
                }
            });
        });
    }
    async performDynamicLookup(record) {
        try {
            const { _id, recordCollection } = record;
            if (!recordCollection) {
                return record;
            }
            const pipeline = [
                {
                    $match: {
                        _id,
                    },
                },
                {
                    $lookup: {
                        from: recordCollection,
                        localField: 'recordId',
                        foreignField: '_id',
                        as: 'record',
                    },
                },
                {
                    $unwind: {
                        path: '$record',
                        preserveNullAndEmptyArrays: true,
                    },
                },
            ];
            const result = await UserLog_model_1.UserLog.aggregate(pipeline);
            if (result.length > 0 && result[0]) {
                const foundRecord = result[0].record;
                if (!foundRecord) {
                    const deletedRecord = await DeletedRecords_model_1.DeletedRecord
                        .findOne({ DBCollection: recordCollection, recordId: record.recordId })
                        .lean();
                    if (deletedRecord) {
                        result[0].record = deletedRecord.record;
                    }
                }
                return result[0];
            }
            return record;
        }
        catch (error) {
            console.error('Error performing dynamic lookup:', error);
            throw error;
        }
    }
    async getLogs(filter) {
        const logs = await UserLog_model_1.UserLog.aggregate([
            {
                $match: {
                    $and: [
                        { 'timestamp': { $gte: filter.periodStart } },
                        { 'timestamp': { $lte: filter.periodEnd } },
                        filter.userId ? { 'userId': new mongoose_1.default.Types.ObjectId(filter.userId) } : {},
                    ],
                },
            },
            {
                $sort: {
                    'timestamp': 1,
                },
            },
        ]);
        const logsWithRecord = await Promise.all(logs.map(async (log) => await this.performDynamicLookup(log)));
        const filteredByBorrowers = !filter.borrowerId
            ? logsWithRecord.slice()
            : await this.filterByBorrower(logsWithRecord, filter.borrowerId);
        await this.replaceBorrowers(filteredByBorrowers);
        return filteredByBorrowers;
    }
    async getDocumentLogs(documentId) {
        const logs = await UserLog_model_1.UserLog.aggregate([
            {
                $match: {
                    $and: [
                        { 'recordCollection': 'loan_transactions' },
                        { 'recordId': new mongoose_1.default.Types.ObjectId(documentId) },
                    ],
                },
            },
            {
                $sort: {
                    'timestamp': 1,
                },
            },
        ]);
        return await Promise.all(logs.map(async (log) => await this.performDynamicLookup(log)));
    }
}
exports.UserLogsService = UserLogsService;
