"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UserService = void 0;
const common_1 = require("@nestjs/common");
const argon = __importStar(require("@node-rs/argon2"));
const client_1 = require("../../generated/prisma/client");
const bootstrap_table_response_dto_1 = require("../commons/dto/bootstrap-table-response.dto");
const prisma_query_builder_1 = require("../commons/utils/prisma-query-builder");
const prisma_service_1 = require("../prisma/prisma.service");
let UserService = class UserService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    async create(dto) {
        const hash = await argon.hash(dto.password);
        try {
            const user = await this.prisma.user.create({
                data: {
                    email: dto.email,
                    hash,
                    firstName: dto.firstName,
                    lastName: dto.lastName,
                    roleId: dto.roleId,
                },
            });
            if (dto.branchIds && dto.branchIds.length) {
                const ops = dto.branchIds.map((branchId) => this.prisma.userBranch.upsert({
                    where: {
                        userId_branchId: {
                            userId: user.id,
                            branchId,
                        },
                    },
                    update: {},
                    create: {
                        userId: user.id,
                        branchId,
                    },
                }));
                await this.prisma.$transaction(ops);
            }
            const result = { ...user };
            delete result.hash;
            return result;
        }
        catch (e) {
            if (e instanceof client_1.Prisma.PrismaClientKnownRequestError &&
                e.code === 'P2002' &&
                (e.meta?.target).includes('email')) {
                throw new common_1.ConflictException('Email already in use');
            }
            throw e;
        }
    }
    async findAll(query) {
        console.log('RAW query:', JSON.stringify(query));
        console.log('filter:', query.filter);
        const allowedFilters = {
            roleId: 'exact',
        };
        const where = (0, prisma_query_builder_1.buildWhereClause)(query, allowedFilters, [
            "email", "firstName", "lastName"
        ]);
        const allowedSortColumns = ['email', 'firstName', 'lastName', 'createdAt', 'modifiedAt'];
        const orderBy = {};
        if (query.sort && allowedSortColumns.includes(query.sort)) {
            orderBy[query.sort] = query.sortOrder;
        }
        else {
            orderBy.createdAt = 'desc';
        }
        const [total, rows] = await this.prisma.$transaction([
            this.prisma.user.count({ where }),
            this.prisma.user.findMany({
                where,
                skip: query.skip,
                take: query.take,
                orderBy,
                include: {
                    role: true,
                    branches: {
                        include: {
                            branch: true,
                        },
                    },
                },
            }),
        ]);
        const rowsCleaned = rows.map((u) => {
            const result = { ...u };
            delete result.hash;
            return result;
        });
        return new bootstrap_table_response_dto_1.BootstrapTableResponseDto(total, rowsCleaned);
    }
    async findOne(id) {
        const user = await this.prisma.user.findUnique({
            where: { id },
            include: {
                role: true,
                branches: {
                    include: { branch: true },
                },
            },
        });
        if (user) {
            const result = { ...user };
            delete result.hash;
            return result;
        }
        return null;
    }
    async update(id, dto) {
        const existing = await this.prisma.user.findUnique({ where: { id } });
        if (!existing) {
            throw new common_1.NotFoundException(`User with id ${id} not found`);
        }
        const data = {
            email: dto.email,
            firstName: dto.firstName,
            lastName: dto.lastName,
            roleId: dto.roleId,
        };
        if (dto.password) {
            data.hash = await argon.hash(dto.password);
        }
        Object.keys(data).forEach((k) => data[k] === undefined && delete data[k]);
        let updated;
        try {
            updated = await this.prisma.user.update({
                where: { id },
                data,
            });
        }
        catch (e) {
            if (e instanceof client_1.Prisma.PrismaClientKnownRequestError &&
                e.code === 'P2002' &&
                (e.meta?.target).includes('email')) {
                throw new common_1.ConflictException('Email already in use');
            }
            throw e;
        }
        if (dto.branchIds) {
            await this.prisma.userBranch.deleteMany({
                where: { userId: id, branchId: { notIn: dto.branchIds } },
            });
            const ops = dto.branchIds.map((branchId) => this.prisma.userBranch.upsert({
                where: {
                    userId_branchId: { userId: id, branchId },
                },
                update: {},
                create: { userId: id, branchId },
            }));
            await this.prisma.$transaction(ops);
        }
        const result = { ...updated };
        delete result.hash;
        return result;
    }
    remove(id) {
        return this.prisma.user.delete({
            where: { id },
        });
    }
};
exports.UserService = UserService;
exports.UserService = UserService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [prisma_service_1.PrismaService])
], UserService);
//# sourceMappingURL=user.service.js.map