"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "FloorService", {
    enumerable: true,
    get: function() {
        return FloorService;
    }
});
const _baseservice = require("./base.service");
const _entities = require("../../entities");
const _floordto = require("../interfaces/floor.dto");
const _validators = require("../../handlers/validators");
const _floorservicevalidation = require("../validators/floor-service.validation");
const _runtimeexceptions = require("../../exceptions/runtime.exceptions");
class FloorService extends (0, _baseservice.BaseService)(_entities.Floor, _floordto.FloorDto, _floordto.CreateFloorDto, _floordto.UpdateFloorDto) {
    floorPositionService;
    constructor({ floorPositionService, typeormService }){
        super({
            typeormService
        });
        this.floorPositionService = floorPositionService;
    }
    async list(options) {
        return super.list(Object.assign(options || {}, {
            relations: [
                "printers"
            ]
        }));
    }
    async get(id, throwIfNotFound = true, options) {
        return super.get(id, throwIfNotFound, Object.assign(options || {}, {
            relations: [
                "printers"
            ]
        }));
    }
    async create(dto) {
        await (0, _validators.validateInput)(dto, _floorservicevalidation.createFloorRules);
        const floor = await super.create({
            name: dto.name,
            floor: dto.floor,
            printers: []
        });
        if (dto.printers?.length) {
            for (const printer of dto.printers){
                await this.addOrUpdatePrinter(floor.id, printer);
            }
        }
        return this.get(floor.id);
    }
    toDto(floor) {
        return {
            id: floor.id,
            name: floor.name,
            floor: floor.floor,
            printers: floor.printers.map((p)=>({
                    printerId: p.printerId,
                    floorId: p.floorId,
                    x: p.x,
                    y: p.y
                }))
        };
    }
    async createDefaultFloor() {
        const floor = await this.create({
            name: "Default Floor",
            floor: 0
        });
        return await this.get(floor.id);
    }
    async update(floorId, update) {
        const floor = await this.get(floorId);
        const floorUpdate = {
            ...floor,
            name: update.name,
            printers: update.printers,
            floor: update.floor
        };
        await (0, _validators.validateInput)(floorUpdate, _floorservicevalidation.updateFloorRules);
        const desiredPositions = floorUpdate.printers;
        if (desiredPositions?.length) {
            for (let printer of desiredPositions){
                await this.addOrUpdatePrinter(floor.id, printer);
            }
        }
        const undesiredPositions = floor.printers.filter((pos)=>!desiredPositions.find((dp)=>dp.printerId === pos.printerId));
        if (undesiredPositions?.length) {
            await this.floorPositionService.deleteMany(undesiredPositions.map((pos)=>pos.id));
        }
        delete floorUpdate.printers;
        return super.update(floorId, floorUpdate);
    }
    async updateName(floorId, name) {
        let floor = await this.get(floorId);
        floor.name = name;
        floor = await this.update(floorId, floor);
        return floor;
    }
    async updateLevel(floorId, level) {
        let floor = await this.get(floorId);
        floor.floor = level;
        floor = await this.update(floorId, floor);
        return floor;
    }
    async addOrUpdatePrinter(floorId, positionDto) {
        await this.get(floorId, true);
        const position = await this.floorPositionService.findPrinterPosition(positionDto.printerId);
        if (position && position.floorId === floorId && position.x === positionDto.x && position.x === positionDto.y && position.printerId === positionDto.printerId) {
            return this.get(floorId);
        }
        if (position) {
            await this.floorPositionService.delete(position.id);
        }
        const xyPosition = await this.floorPositionService.findPosition(floorId, positionDto.x, positionDto.y);
        if (xyPosition) {
            await this.floorPositionService.delete(xyPosition.id);
        }
        const newPosition = new _entities.FloorPosition();
        Object.assign(newPosition, {
            x: positionDto.x,
            y: positionDto.y,
            printerId: positionDto.printerId,
            floorId: floorId
        });
        await this.floorPositionService.create(newPosition);
        return this.get(floorId);
    }
    async removePrinter(floorId, printerId) {
        const position = await this.floorPositionService.findPrinterPositionOnFloor(floorId, printerId);
        if (!position) {
            throw new _runtimeexceptions.NotFoundException("This printer was not found on this floor");
        }
        await this.floorPositionService.delete(position.id);
        return await this.get(floorId);
    }
    async deletePrinterFromAnyFloor(printerId) {
        await this.floorPositionService.deletePrinterPositionsByPrinterId(printerId);
    }
}

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