"use strict";
/**
 * ConceptoService - Catalogo de Conceptos de Obra
 *
 * Gestiona el catálogo jerárquico de conceptos de obra.
 * Los conceptos pueden tener estructura padre-hijo (niveles).
 *
 * @module Budgets
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConceptoService = void 0;
const typeorm_1 = require("typeorm");
const base_service_1 = require("../../../shared/services/base.service");
class ConceptoService extends base_service_1.BaseService {
    constructor(repository) {
        super(repository);
    }
    /**
     * Crear un nuevo concepto con cálculo automático de nivel y path
     */
    async createConcepto(ctx, data) {
        let level = 0;
        let path = data.code;
        if (data.parentId) {
            const parent = await this.findById(ctx, data.parentId);
            if (parent) {
                level = parent.level + 1;
                path = `${parent.path}/${data.code}`;
            }
        }
        return this.create(ctx, {
            ...data,
            level,
            path,
        });
    }
    /**
     * Obtener conceptos raíz (sin padre)
     */
    async findRootConceptos(ctx, page = 1, limit = 50) {
        return this.findAll(ctx, {
            page,
            limit,
            where: { parentId: (0, typeorm_1.IsNull)() },
        });
    }
    /**
     * Obtener hijos de un concepto
     */
    async findChildren(ctx, parentId) {
        return this.find(ctx, {
            where: { parentId },
            order: { code: 'ASC' },
        });
    }
    /**
     * Obtener árbol completo de conceptos
     */
    async getConceptoTree(ctx, rootId) {
        const where = rootId
            ? { parentId: rootId }
            : { parentId: (0, typeorm_1.IsNull)() };
        const roots = await this.find(ctx, {
            where: where,
            order: { code: 'ASC' },
        });
        return this.buildTree(ctx, roots);
    }
    async buildTree(ctx, conceptos) {
        const tree = [];
        for (const concepto of conceptos) {
            const children = await this.findChildren(ctx, concepto.id);
            const childNodes = children.length > 0
                ? await this.buildTree(ctx, children)
                : [];
            tree.push({
                ...concepto,
                children: childNodes,
            });
        }
        return tree;
    }
    /**
     * Buscar conceptos por código o nombre
     */
    async search(ctx, term, limit = 20) {
        return this.repository
            .createQueryBuilder('c')
            .where('c.tenant_id = :tenantId', { tenantId: ctx.tenantId })
            .andWhere('c.deleted_at IS NULL')
            .andWhere('(c.code ILIKE :term OR c.name ILIKE :term)', {
            term: `%${term}%`,
        })
            .orderBy('c.code', 'ASC')
            .take(limit)
            .getMany();
    }
    /**
     * Verificar si un código ya existe
     */
    async codeExists(ctx, code) {
        return this.exists(ctx, { code });
    }
}
exports.ConceptoService = ConceptoService;
//# sourceMappingURL=concepto.service.js.map