"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createBBCDate = exports.getBBCDatesByType = exports.getBBCDatesForPeriod = exports.getBBCDates = exports.getOlderBBCDates = exports.getLatestSignedBBCDateDoc = exports.getLatestBBCDates = exports.getBBCDatesByBorrower = exports.getBBCDateDoc = void 0;
const mongoose_1 = __importDefault(require("mongoose"));
const BBCDate_model_1 = require("../models/BBCDate.model");
const BBCSheet_model_1 = require("../models/BBCSheet.model");
const availability_db_1 = require("./availability.db");
const _models_1 = require("../models/_models");
const getBBCDateDoc = async (bbcDateId) => {
    return BBCDate_model_1.BBCDateModel.findById(bbcDateId).lean();
};
exports.getBBCDateDoc = getBBCDateDoc;
const getBBCDatesByBorrower = async (borrowerId, sortOrder = 1) => {
    return BBCDate_model_1.BBCDateModel.aggregate([
        {
            $match: {
                borrowerId: new mongoose_1.default.Types.ObjectId(borrowerId),
            },
        },
        {
            $sort: { bbcDate: sortOrder },
        },
    ]);
};
exports.getBBCDatesByBorrower = getBBCDatesByBorrower;
const getLatestBBCDates = async (borrowerId, date, repo = BBCDate_model_1.BBCDateModel) => {
    const match = {
        borrowerId: new mongoose_1.default.Types.ObjectId(borrowerId),
    };
    if (date) {
        match.bbcDate = { $lte: date };
    }
    return repo.aggregate([{ $match: match }, { $sort: { bbcDate: -1 } }]);
};
exports.getLatestBBCDates = getLatestBBCDates;
const getLatestSignedBBCDateDoc = async (borrowerId, date) => {
    const match = {
        borrowerId: new mongoose_1.default.Types.ObjectId(borrowerId),
    };
    if (date) {
        match.bbcDate = { $lte: date };
    }
    const bbcDates = await (0, exports.getLatestBBCDates)(borrowerId, date);
    if (!bbcDates.length) {
        return null;
    }
    let foundSignedBBC = null;
    let i = 0;
    while (!foundSignedBBC && i < bbcDates.length) {
        const bbcDateId = bbcDates[i]._id.toString();
        const signs = await (0, availability_db_1.getAvailabilitySigns)([bbcDateId]);
        const availabilitySigns = signs.pop();
        if (availabilitySigns) {
            const totalSigns = availabilitySigns.signs.filter((sign) => !sign.revokedAt);
            foundSignedBBC = totalSigns.length === availabilitySigns.requiredSigns ? bbcDates[i] : null;
        }
        i++;
    }
    return foundSignedBBC;
};
exports.getLatestSignedBBCDateDoc = getLatestSignedBBCDateDoc;
const getOlderBBCDates = async (borrowerId, bbcDate) => {
    return BBCDate_model_1.BBCDateModel.aggregate([
        {
            $match: {
                borrowerId: new mongoose_1.default.Types.ObjectId(borrowerId),
                bbcDate: { $lt: bbcDate },
            },
        },
        {
            $sort: { bbcDate: 1 },
        },
    ]);
};
exports.getOlderBBCDates = getOlderBBCDates;
const getBBCDates = async (borrowerId, bbcDate) => {
    return BBCDate_model_1.BBCDateModel.aggregate([
        {
            $match: {
                borrowerId: new mongoose_1.default.Types.ObjectId(borrowerId),
                bbcDate: new Date(bbcDate),
            },
        },
        {
            $sort: { updatedAt: 1 },
        },
    ]);
};
exports.getBBCDates = getBBCDates;
const getBBCDatesForPeriod = async (borrowerId, bbcDateStart, bbcDateEnd) => {
    return BBCDate_model_1.BBCDateModel.aggregate([
        {
            $match: {
                $and: [
                    { 'borrowerId': new mongoose_1.default.Types.ObjectId(borrowerId) },
                    { 'bbcDate': { $gte: bbcDateStart } },
                    { 'bbcDate': { $lte: bbcDateEnd } },
                ],
            },
        },
        {
            $sort: {
                'bbcDate': 1,
            },
        },
    ]);
};
exports.getBBCDatesForPeriod = getBBCDatesForPeriod;
const getBBCDatesByType = (borrowerId, collateralType) => {
    return BBCSheet_model_1.BBCSheetModel.aggregate([
        {
            $match: {
                'dataType': { $in: collateralType },
            },
        },
        {
            $lookup: {
                from: _models_1.MODEL_NAMES.BBCDates,
                localField: 'bbcDateId',
                foreignField: '_id',
                as: 'bbc',
            },
        },
        {
            $unwind: {
                path: '$bbc',
            },
        },
        {
            $match: {
                'bbc.borrowerId': new mongoose_1.default.Types.ObjectId(borrowerId),
            },
        },
        {
            $group: {
                '_id': '$bbc._id',
                'borrowerId': {
                    $first: '$bbc.borrowerId',
                },
                'bbcDate': {
                    $first: '$bbc.bbcDate',
                },
                'createdAt': {
                    $first: '$bbc.createdAt',
                },
                'updatedAt': {
                    $first: '$bbc.updatedAt',
                },
                '__v': {
                    $first: '$bbc.__v',
                },
            },
        },
        {
            $sort: {
                'bbcDate': -1,
            },
        },
    ]);
};
exports.getBBCDatesByType = getBBCDatesByType;
const createBBCDate = async (borrowerId, bbcDate) => {
    const newBBC = await BBCDate_model_1.BBCDateModel.create({ borrowerId: new mongoose_1.default.Types.ObjectId(borrowerId), bbcDate });
    return newBBC.save();
};
exports.createBBCDate = createBBCDate;
