"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.SubscriptionsService = void 0; const common_1 = require("@nestjs/common"); const typeorm_1 = require("@nestjs/typeorm"); const typeorm_2 = require("typeorm"); const plan_entity_1 = require("./entities/plan.entity"); const subscription_entity_1 = require("./entities/subscription.entity"); const token_balance_entity_1 = require("./entities/token-balance.entity"); const token_usage_entity_1 = require("./entities/token-usage.entity"); let SubscriptionsService = class SubscriptionsService { constructor(planRepo, subscriptionRepo, tokenBalanceRepo, tokenUsageRepo) { this.planRepo = planRepo; this.subscriptionRepo = subscriptionRepo; this.tokenBalanceRepo = tokenBalanceRepo; this.tokenUsageRepo = tokenUsageRepo; } async getPlans() { return this.planRepo.find({ where: { status: 'active' }, order: { priceMonthly: 'ASC' }, }); } async getPlanByCode(code) { const plan = await this.planRepo.findOne({ where: { code } }); if (!plan) { throw new common_1.NotFoundException('Plan no encontrado'); } return plan; } async getSubscription(tenantId) { return this.subscriptionRepo.findOne({ where: { tenantId }, relations: ['plan'], }); } async createSubscription(tenantId, planCode) { const plan = await this.getPlanByCode(planCode); const now = new Date(); const periodEnd = new Date(now); periodEnd.setMonth(periodEnd.getMonth() + 1); const trialEnds = new Date(now); trialEnds.setDate(trialEnds.getDate() + 14); const subscription = this.subscriptionRepo.create({ tenantId, planId: plan.id, currentPeriodStart: now, currentPeriodEnd: periodEnd, status: subscription_entity_1.SubscriptionStatus.TRIAL, trialEndsAt: trialEnds, }); await this.subscriptionRepo.save(subscription); await this.initializeTokenBalance(tenantId, plan.includedTokens); return subscription; } async cancelSubscription(tenantId) { const subscription = await this.getSubscription(tenantId); if (!subscription) { throw new common_1.NotFoundException('Suscripción no encontrada'); } subscription.cancelAtPeriodEnd = true; subscription.cancelledAt = new Date(); return this.subscriptionRepo.save(subscription); } async getTokenBalance(tenantId) { let balance = await this.tokenBalanceRepo.findOne({ where: { tenantId } }); if (!balance) { balance = await this.initializeTokenBalance(tenantId, 0); } return balance; } async initializeTokenBalance(tenantId, tokens) { const existing = await this.tokenBalanceRepo.findOne({ where: { tenantId } }); if (existing) { existing.availableTokens = tokens; existing.lastResetAt = new Date(); return this.tokenBalanceRepo.save(existing); } const balance = this.tokenBalanceRepo.create({ tenantId, availableTokens: tokens, usedTokens: 0, lastResetAt: new Date(), }); return this.tokenBalanceRepo.save(balance); } async consumeTokens(tenantId, tokensToUse, action, metadata) { const balance = await this.getTokenBalance(tenantId); if (balance.availableTokens < tokensToUse) { throw new common_1.BadRequestException(`Tokens insuficientes. Disponibles: ${balance.availableTokens}, Requeridos: ${tokensToUse}`); } const usage = this.tokenUsageRepo.create({ tenantId, tokensUsed: tokensToUse, action, ...metadata, }); await this.tokenUsageRepo.save(usage); balance.availableTokens -= tokensToUse; balance.usedTokens += tokensToUse; return this.tokenBalanceRepo.save(balance); } async addTokens(tenantId, tokens) { const balance = await this.getTokenBalance(tenantId); balance.availableTokens += tokens; return this.tokenBalanceRepo.save(balance); } async getTokenUsage(tenantId, limit = 50) { return this.tokenUsageRepo.find({ where: { tenantId }, order: { createdAt: 'DESC' }, take: limit, }); } async getSubscriptionStats(tenantId) { const subscription = await this.getSubscription(tenantId); const balance = await this.getTokenBalance(tenantId); const daysRemaining = subscription ? Math.max(0, Math.ceil((subscription.currentPeriodEnd.getTime() - Date.now()) / (1000 * 60 * 60 * 24))) : 0; return { subscription: subscription ? { plan: subscription.plan?.name, status: subscription.status, currentPeriodEnd: subscription.currentPeriodEnd, daysRemaining, cancelAtPeriodEnd: subscription.cancelAtPeriodEnd, } : null, tokens: { available: balance.availableTokens, used: balance.usedTokens, total: balance.availableTokens + balance.usedTokens, }, }; } }; exports.SubscriptionsService = SubscriptionsService; exports.SubscriptionsService = SubscriptionsService = __decorate([ (0, common_1.Injectable)(), __param(0, (0, typeorm_1.InjectRepository)(plan_entity_1.Plan)), __param(1, (0, typeorm_1.InjectRepository)(subscription_entity_1.Subscription)), __param(2, (0, typeorm_1.InjectRepository)(token_balance_entity_1.TokenBalance)), __param(3, (0, typeorm_1.InjectRepository)(token_usage_entity_1.TokenUsage)), __metadata("design:paramtypes", [typeorm_2.Repository, typeorm_2.Repository, typeorm_2.Repository, typeorm_2.Repository]) ], SubscriptionsService); //# sourceMappingURL=subscriptions.service.js.map