"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); }
};
var OnboardingService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.OnboardingService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const tenant_entity_1 = require("../tenants/entities/tenant.entity");
const user_entity_1 = require("../auth/entities/user.entity");
const token_entity_1 = require("../auth/entities/token.entity");
const subscription_entity_1 = require("../billing/entities/subscription.entity");
const email_service_1 = require("../email/services/email.service");
const audit_service_1 = require("../audit/services/audit.service");
const audit_log_entity_1 = require("../audit/entities/audit-log.entity");
let OnboardingService = OnboardingService_1 = class OnboardingService {
    constructor(tenantRepository, userRepository, tokenRepository, subscriptionRepository, emailService, auditService) {
        this.tenantRepository = tenantRepository;
        this.userRepository = userRepository;
        this.tokenRepository = tokenRepository;
        this.subscriptionRepository = subscriptionRepository;
        this.emailService = emailService;
        this.auditService = auditService;
        this.logger = new common_1.Logger(OnboardingService_1.name);
    }
    async getStatus(tenantId) {
        const tenant = await this.tenantRepository.findOne({
            where: { id: tenantId },
        });
        if (!tenant) {
            throw new common_1.BadRequestException('Tenant not found');
        }
        const teamData = await this.getTeamData(tenantId);
        const planData = await this.getPlanData(tenantId);
        const companyData = this.getCompanyData(tenant);
        const step = this.calculateStep(companyData, teamData, planData, tenant);
        const completed = tenant.status === 'active';
        return {
            step,
            completed,
            data: {
                company: companyData,
                team: teamData,
                plan: planData,
            },
        };
    }
    async completeOnboarding(tenantId, userId) {
        const tenant = await this.tenantRepository.findOne({
            where: { id: tenantId },
        });
        if (!tenant) {
            throw new common_1.BadRequestException('Tenant not found');
        }
        if (tenant.status === 'active') {
            return {
                success: true,
                redirectUrl: '/dashboard',
            };
        }
        if (tenant.status !== 'trial' && tenant.status !== 'suspended' && tenant.status !== 'canceled') {
            throw new common_1.BadRequestException('Tenant is not in a valid state for onboarding completion');
        }
        const user = await this.userRepository.findOne({
            where: { id: userId, tenant_id: tenantId },
        });
        if (!user) {
            throw new common_1.BadRequestException('User not found');
        }
        const oldStatus = tenant.status;
        tenant.status = 'active';
        await this.tenantRepository.save(tenant);
        await this.auditService.createAuditLog({
            tenant_id: tenantId,
            user_id: userId,
            action: audit_log_entity_1.AuditAction.UPDATE,
            entity_type: 'tenant',
            entity_id: tenantId,
            old_values: { status: oldStatus },
            new_values: { status: 'active' },
            description: 'Onboarding completed',
        });
        await this.sendWelcomeEmail(user, tenant);
        this.logger.log(`Onboarding completed for tenant ${tenantId}`);
        return {
            success: true,
            redirectUrl: '/dashboard',
        };
    }
    getCompanyData(tenant) {
        if (!tenant.name || !tenant.slug) {
            return null;
        }
        return {
            name: tenant.name,
            slug: tenant.slug,
            logo_url: tenant.logo_url,
            settings: tenant.settings,
        };
    }
    async getTeamData(tenantId) {
        const invitesSent = await this.tokenRepository.count({
            where: {
                tenant_id: tenantId,
                token_type: 'invitation',
            },
        });
        const membersJoined = await this.userRepository.count({
            where: {
                tenant_id: tenantId,
                status: 'active',
            },
        });
        const actualMembersJoined = membersJoined > 1 ? membersJoined - 1 : 0;
        return {
            invitesSent,
            membersJoined: actualMembersJoined,
        };
    }
    async getPlanData(tenantId) {
        const subscription = await this.subscriptionRepository.findOne({
            where: { tenant_id: tenantId },
            order: { created_at: 'DESC' },
        });
        return {
            selected: !!subscription,
            planId: subscription?.plan_id || null,
        };
    }
    calculateStep(companyData, teamData, planData, tenant) {
        if (tenant.status === 'active') {
            return 4;
        }
        if (!companyData) {
            return 1;
        }
        if (!planData.selected) {
            return 3;
        }
        return 4;
    }
    async sendWelcomeEmail(user, tenant) {
        try {
            await this.emailService.sendTemplateEmail({
                to: {
                    email: user.email,
                    name: user.first_name || undefined,
                },
                templateKey: 'welcome',
                variables: {
                    userName: user.first_name || user.email,
                    appName: 'Template SaaS',
                    tenantName: tenant.name,
                },
            });
            this.logger.log(`Welcome email sent to ${user.email}`);
        }
        catch (error) {
            this.logger.error(`Failed to send welcome email to ${user.email}`, error.stack);
        }
    }
};
exports.OnboardingService = OnboardingService;
exports.OnboardingService = OnboardingService = OnboardingService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectRepository)(tenant_entity_1.Tenant)),
    __param(1, (0, typeorm_1.InjectRepository)(user_entity_1.User)),
    __param(2, (0, typeorm_1.InjectRepository)(token_entity_1.Token)),
    __param(3, (0, typeorm_1.InjectRepository)(subscription_entity_1.Subscription)),
    __metadata("design:paramtypes", [typeorm_2.Repository,
        typeorm_2.Repository,
        typeorm_2.Repository,
        typeorm_2.Repository,
        email_service_1.EmailService,
        audit_service_1.AuditService])
], OnboardingService);
//# sourceMappingURL=onboarding.service.js.map