"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "FloorService", {
    enumerable: true,
    get: function() {
        return FloorService;
    }
});
const _Floor = require("../../models/Floor");
const _validators = require("../../handlers/validators");
const _runtimeexceptions = require("../../exceptions/runtime.exceptions");
const _floorservicevalidation = require("../validators/floor-service.validation");
class FloorService {
    printerCache;
    logger;
    constructor({ printerCache, loggerFactory }){
        this.printerCache = printerCache;
        this.logger = loggerFactory(FloorService.name);
    }
    toDto(floor) {
        return {
            id: floor.id,
            name: floor.name,
            floor: floor.floor,
            printers: floor.printers?.map((p)=>({
                    x: p.x,
                    y: p.y,
                    printerId: p.printerId.toString(),
                    floorId: floor.id
                }))
        };
    }
    async list(patchPositions = true) {
        const floors = await _Floor.Floor.find({});
        if (!patchPositions) {
            return floors;
        }
        return floors;
    }
    async get(floorId, throwError = true) {
        const floor = await _Floor.Floor.findOne({
            _id: floorId
        });
        if (!floor && throwError) {
            throw new _runtimeexceptions.NotFoundException(`Floor with provided id does not exist`);
        }
        return floor;
    }
    async createDefaultFloor() {
        return await this.create({
            name: "Default Floor",
            floor: 1
        });
    }
    async create(floor) {
        const validatedInput = await (0, _validators.validateInput)(floor, _floorservicevalidation.createFloorRules);
        return _Floor.Floor.create(validatedInput);
    }
    async update(floorId, input) {
        const existingFloor = await this.get(floorId);
        const { name, floor, printers } = await (0, _validators.validateInput)(input, _floorservicevalidation.updateFloorRules);
        existingFloor.name = name;
        existingFloor.floor = floor;
        existingFloor.printers = printers;
        return await existingFloor.save();
    }
    async updateName(floorId, floorName) {
        const floor = await this.get(floorId);
        const { name } = await (0, _validators.validateInput)({
            name: floorName
        }, _floorservicevalidation.updateFloorNameRules);
        floor.name = name;
        return await floor.save();
    }
    async updateLevel(floorId, level) {
        const floor = await this.get(floorId);
        const { floor: validLevel } = await (0, _validators.validateInput)({
            floor: level
        }, _floorservicevalidation.updateFloorNumberRules);
        floor.floor = validLevel;
        return await floor.save();
    }
    async deletePrinterFromAnyFloor(printerId) {
        await _Floor.Floor.updateMany({}, {
            $pull: {
                printers: {
                    printerId: {
                        $in: [
                            printerId
                        ]
                    }
                }
            }
        });
    }
    async addOrUpdatePrinter(floorId, updatedPosition) {
        const floor = await this.get(floorId, true);
        const validInput = await (0, _validators.validateInput)(updatedPosition, (0, _floorservicevalidation.printerInFloorRules)(false));
        await this.printerCache.getCachedPrinterOrThrowAsync(validInput.printerId);
        floor.printers = floor.printers.filter((position)=>!(position.x === updatedPosition.x && position.y === updatedPosition.y));
        const positionIndex = floor.printers.findIndex((position)=>position.printerId.toString() === validInput.printerId.toString());
        if (positionIndex !== -1) {
            floor.printers[positionIndex] = validInput;
        } else {
            floor.printers.push(validInput);
        }
        await floor.save();
        return floor;
    }
    async removePrinter(floorId, printerId) {
        const floor = await this.get(floorId, true);
        const validInput = await (0, _validators.validateInput)({
            printerId
        }, (0, _floorservicevalidation.removePrinterInFloorRules)(false));
        await this.printerCache.getCachedPrinterOrThrowAsync(validInput.printerId);
        const foundPrinterInFloorIndex = floor.printers.findIndex((pif)=>pif.printerId.toString() === validInput.printerId);
        if (foundPrinterInFloorIndex === -1) return floor;
        floor.printers.splice(foundPrinterInFloorIndex, 1);
        await floor.save();
        return floor;
    }
    async delete(floorId) {
        await this.get(floorId, true);
        await _Floor.Floor.deleteOne({
            _id: floorId
        });
    }
}

//# sourceMappingURL=floor.service.js.map