"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RolesEndpointsController = void 0;
const abstract_controller_1 = require("./abstract.controller");
const roles_endpoint_model_1 = require("../models/roles-endpoint.model");
const roles_endpoint_method_1 = require("../methods/roles-endpoint.method");
const endpoint_model_1 = require("../models/endpoint.model");
const endpoint_method_1 = require("../methods/endpoint.method");
const mongoose_1 = __importDefault(require("mongoose"));
class RolesEndpointsController extends abstract_controller_1.AbstractController {
    constructor() {
        super(roles_endpoint_model_1.RolesEndpointsModel);
        this.methods = new roles_endpoint_method_1.RolesEndpointsMethods(roles_endpoint_model_1.RolesEndpointsModel);
        this.methodsEndpoints = new endpoint_method_1.EndpointsMethods(endpoint_model_1.EndpointsModel);
    }
    async getItems(req, res, next) {
        try {
            const { filter, sort } = this.params.aqp(req.query);
            const [, options] = this.params.optionsPaginate(req);
            let aggregate = this.model.aggregate([
                {
                    $lookup: {
                        from: "endpoints",
                        localField: "endpoint_id",
                        foreignField: "_id",
                        as: "endpoint",
                    },
                },
                {
                    $unwind: "$endpoint",
                },
                {
                    $lookup: {
                        from: "roles",
                        localField: "role_id",
                        foreignField: "_id",
                        as: "role",
                    },
                },
                {
                    $unwind: "$role",
                },
                {
                    $match: filter,
                },
                ...this.methods.mainFilter(req),
            ]);
            const data = await this.model.aggregatePaginate({ ...aggregate }, {
                ...options,
                sort,
            });
            res.send(data);
        }
        catch (e) {
            this.params.handleHttpError(res, e);
        }
    }
    async getItem(req, res) {
        try {
            const matchedData = this.params.matchedData(req);
            const _id = matchedData._id;
            const data = await this.model.aggregate([
                {
                    $lookup: {
                        from: "endpoints",
                        localField: "endpoint_id",
                        foreignField: "_id",
                        as: "endpoint",
                    },
                },
                {
                    $unwind: "$endpoint",
                },
                {
                    $lookup: {
                        from: "roles",
                        localField: "role_id",
                        foreignField: "_id",
                        as: "role",
                    },
                },
                {
                    $unwind: "$role",
                },
                { $limit: 1 },
                {
                    $match: { _id: new mongoose_1.default.Types.ObjectId(_id) },
                },
                ...this.methods.mainFilter(req),
            ]);
            res.send(data.length > 0 ? data[0] : {});
        }
        catch (e) {
            this.params.handleHttpError(res, e);
        }
    }
    async createItem(req, res) {
        try {
            const matchedData = this.params.matchedData(req);
            const rolesEndpoints = await this.methods.existDocument({
                endpoint_id: matchedData.endpoint_id,
                role_id: matchedData.role_id,
            });
            if (rolesEndpoints) {
                this.params.handleErrorResponse(res, "ROLES_ENDPOINT_EXIST", 402);
                return;
            }
            const endpoints = await this.methodsEndpoints.existDocument({
                _id: matchedData.endpoint_id,
            });
            if (!endpoints) {
                this.params.handleErrorResponse(res, "ENDPOINT_NOT_EXIST", 402);
                return;
            }
            const data = await this.methods.saveDocument(matchedData, req);
            res.send(data);
        }
        catch (e) {
            this.params.handleHttpError(res, e);
        }
    }
    async setPermissions(req, res) {
        try {
            const matchedData = this.params.matchedData(req);
            const _id = matchedData._id;
            const allEndpoints = await endpoint_model_1.EndpointsModel.find();
            const permissions = allEndpoints.map((endpoint) => {
                return { endpoint: endpoint._id, role_id: _id };
            });
            const data = await Promise.all([
                ...permissions.map((permission) => roles_endpoint_model_1.RolesEndpointsModel.findOneAndUpdate({
                    endpoint: permission.endpoint,
                    role_id: permission.role_id,
                }, permission, { upsert: true, new: true, setDefaultsOnInsert: true })),
            ]);
            res.send(data);
        }
        catch (e) {
            this.params.handleHttpError(res, e);
        }
    }
    async avoidCheck(req, res) {
        try {
            const matchedData = this.params.matchedData(req);
            const _id = matchedData._id;
            const existEndpoint = await this.methodsEndpoints.existDocument({
                endpoint: _id,
            });
            if (!existEndpoint) {
                this.params.handleErrorResponse(res, "ENDPOINT_NOT_EXIST", 402);
                return;
            }
        }
        catch (e) {
            this.params.handleHttpError(res, e);
        }
    }
}
exports.RolesEndpointsController = RolesEndpointsController;
