"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.AlphaNumExternalIdComputationProvider = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const computed_field_provider_decorator_1 = require("../../../decorators/computed-field-provider.decorator");
const typeorm_2 = require("typeorm");
const lodash_1 = require("lodash");
let AlphaNumExternalIdComputationProvider = class AlphaNumExternalIdComputationProvider {
    constructor(entityManager) {
        this.entityManager = entityManager;
    }
    name() {
        return this.constructor.name;
    }
    help() {
        return 'Provider used to compute external ID for a CommonEntity with support for static or dynamic prefix.';
    }
    async preComputeValue(triggerEntity, computedFieldMetadata) {
        const { prefix, length, dynamicFieldPrefix } = computedFieldMetadata.computedFieldValueProviderCtxt;
        const eventContext = computedFieldMetadata.eventContext;
        const entityName = eventContext?.metadataName ?? eventContext.databaseEntity?.constructor?.name ?? '';
        const codeLength = length || 5;
        let resolvedPrefix = prefix || '';
        if (dynamicFieldPrefix) {
            const dynamicValue = (0, lodash_1.get)(triggerEntity, dynamicFieldPrefix);
            if (dynamicValue) {
                resolvedPrefix = String(dynamicValue).trim().toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9\-]/g, '');
            }
        }
        const uniqueCode = await this.generateUniqueExternalId(resolvedPrefix, codeLength, computedFieldMetadata.fieldName, entityName);
        const finalExternalId = resolvedPrefix ? `${resolvedPrefix}-${uniqueCode}` : uniqueCode;
        triggerEntity[computedFieldMetadata.fieldName] = finalExternalId;
    }
    generateRandomCode(length = 5) {
        const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        let result = '';
        for (let i = 0; i < length; i++) {
            result += chars.charAt(Math.floor(Math.random() * chars.length));
        }
        return result;
    }
    async isExternalIdUnique(externalId, fieldName, entityName) {
        const count = await this.entityManager.count(entityName, {
            where: { [fieldName]: externalId },
        });
        return count === 0;
    }
    async generateUniqueExternalId(resolvedPrefix, codeLength, fieldName, entityName) {
        const maxAttempts = 10;
        for (let attempt = 0; attempt < maxAttempts; attempt++) {
            const newId = this.generateRandomCode(codeLength);
            const fullId = resolvedPrefix ? `${resolvedPrefix}-${newId}` : newId;
            const isUnique = await this.isExternalIdUnique(fullId, fieldName, entityName);
            if (isUnique) {
                return newId;
            }
        }
        throw new Error('Failed to generate a unique external ID after multiple attempts');
    }
};
exports.AlphaNumExternalIdComputationProvider = AlphaNumExternalIdComputationProvider;
exports.AlphaNumExternalIdComputationProvider = AlphaNumExternalIdComputationProvider = __decorate([
    (0, computed_field_provider_decorator_1.ComputedFieldProvider)(),
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectEntityManager)()),
    __metadata("design:paramtypes", [typeorm_2.EntityManager])
], AlphaNumExternalIdComputationProvider);
//# sourceMappingURL=alpha-num-external-id-computed-field-provider.js.map