"use strict";
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 __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PermissionService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const permission_entity_1 = require("../entities/permission.entity");
const auth_constants_1 = require("../../auth.constants");
let PermissionService = class PermissionService {
    permissionRepository;
    constructor(permissionRepository) {
        this.permissionRepository = permissionRepository;
    }
    async createPermission(data) {
        const guard = data.guard || auth_constants_1.DEFAULT_GUARD_NAME;
        const existing = await this.permissionRepository.findOne({
            where: { name: data.name.trim(), guard },
        });
        if (existing) {
            throw new common_1.ConflictException(`Permission '${data.name}' with guard '${guard}' already exists`);
        }
        const permission = this.permissionRepository.create({
            name: data.name.trim(),
            guard,
            description: data.description?.trim(),
            category: data.category?.trim(),
            metadata: data.metadata || {},
        });
        return this.permissionRepository.save(permission);
    }
    async getPermissions(options) {
        const query = this.permissionRepository.createQueryBuilder('permission');
        if (options?.search) {
            query.where('(permission.name LIKE :search OR permission.description LIKE :search)', { search: `%${options.search}%` });
        }
        if (options?.category) {
            query.andWhere('permission.category = :category', { category: options.category });
        }
        if (options?.guard) {
            query.andWhere('permission.guard = :guard', { guard: options.guard });
        }
        query.orderBy('permission.name', 'ASC');
        if (options?.limit) {
            query.limit(options.limit);
        }
        return query.getMany();
    }
    async getPermissionByName(name, guard) {
        return this.permissionRepository.findOne({
            where: { name, guard: guard || auth_constants_1.DEFAULT_GUARD_NAME },
        });
    }
    async getPermissionsByGuard(guard) {
        return this.permissionRepository.find({
            where: { guard },
            order: { name: 'ASC' },
        });
    }
    async getGuards() {
        const result = await this.permissionRepository
            .createQueryBuilder('permission')
            .select('DISTINCT permission.guard', 'guard')
            .getRawMany();
        return result.map(r => r.guard).filter(Boolean).sort();
    }
    async getPermissionById(id) {
        const permission = await this.permissionRepository.findOne({
            where: { id },
        });
        if (!permission) {
            throw new common_1.NotFoundException(`Permission with id ${id} not found`);
        }
        return permission;
    }
    async updatePermission(id, data) {
        const permission = await this.getPermissionById(id);
        const guard = data.guard || permission.guard;
        if (data.name && data.name !== permission.name) {
            const existing = await this.permissionRepository.findOne({
                where: { name: data.name.trim(), guard },
            });
            if (existing) {
                throw new common_1.ConflictException(`Permission '${data.name}' with guard '${guard}' already exists`);
            }
            permission.name = data.name.trim();
        }
        if (data.guard && data.guard !== permission.guard) {
            const existing = await this.permissionRepository.findOne({
                where: { name: permission.name, guard: data.guard },
            });
            if (existing) {
                throw new common_1.ConflictException(`Permission '${permission.name}' with guard '${data.guard}' already exists`);
            }
            permission.guard = data.guard;
        }
        if (data.description !== undefined) {
            permission.description = data.description?.trim() || null;
        }
        if (data.category !== undefined) {
            permission.category = data.category?.trim() || null;
        }
        if (data.metadata !== undefined) {
            permission.metadata = data.metadata || {};
        }
        return this.permissionRepository.save(permission);
    }
    async deletePermission(id) {
        const permission = await this.getPermissionById(id);
        await this.permissionRepository.remove(permission);
    }
    async getPermissionsByNames(names) {
        if (names.length === 0) {
            return [];
        }
        return this.permissionRepository.find({
            where: names.map(name => ({ name })),
        });
    }
    async searchPermissions(query, guard, limit = 20) {
        const whereConditions = [
            { name: (0, typeorm_2.Like)(`%${query}%`) },
            { description: (0, typeorm_2.Like)(`%${query}%`) },
        ];
        if (guard) {
            whereConditions.forEach(condition => {
                condition.guard = guard;
            });
        }
        return this.permissionRepository.find({
            where: whereConditions,
            take: limit,
            order: { name: 'ASC' },
        });
    }
    async getCategories() {
        const result = await this.permissionRepository
            .createQueryBuilder('permission')
            .select('DISTINCT permission.category', 'category')
            .where('permission.category IS NOT NULL')
            .getRawMany();
        return result.map(r => r.category).filter(Boolean).sort();
    }
    async createPermissions(permissions) {
        const existing = await this.permissionRepository.find({
            where: permissions.map(p => ({ name: p.name })),
        });
        const existingNames = new Set(existing.map(p => p.name));
        const toCreate = permissions.filter(p => !existingNames.has(p.name));
        if (toCreate.length === 0) {
            return existing;
        }
        const newPermissions = this.permissionRepository.create(toCreate.map(p => ({
            name: p.name.trim(),
            description: p.description?.trim(),
            category: p.category?.trim(),
            metadata: p.metadata || {},
        })));
        const saved = await this.permissionRepository.save(newPermissions);
        return [...existing, ...saved];
    }
};
exports.PermissionService = PermissionService;
exports.PermissionService = PermissionService = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectRepository)(permission_entity_1.NestAuthPermission)),
    __metadata("design:paramtypes", [typeorm_2.Repository])
], PermissionService);
//# sourceMappingURL=permission.service.js.map