"use strict";
/**
 * PartnerManager: Channel partner infrastructure for My Compliance Center.
 *
 * Manages the partner hierarchy: Connexum > Partner Orgs > Client Orgs.
 * Partners (compliance consultancies, health IT integrators) onboard their
 * clients, tune policies, and monitor governance posture across all sub-orgs.
 *
 * This is the #1 build priority per Thomas: channel partners are the bridge
 * to CISOs that direct sales cannot reach at seed stage.
 *
 * @module governance/partner-manager
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.PartnerManager = void 0;
const crypto = __importStar(require("node:crypto"));
// ---- Implementation ----
const DEFAULT_CONFIG = {
    maxClientsPerPartner: 100,
    defaultCommissionRate: 0.2,
    aggregateReporting: true,
};
class PartnerManager {
    config;
    partners = new Map();
    clients = new Map();
    commissions = [];
    constructor(config = {}) {
        this.config = { ...DEFAULT_CONFIG, ...config };
    }
    /**
     * Register a new channel partner.
     */
    registerPartner(input) {
        const id = `partner_${crypto.randomUUID()}`;
        const now = new Date().toISOString();
        const partner = {
            id,
            name: input.name,
            contactEmail: input.contactEmail,
            type: input.type,
            commissionRate: input.commissionRate ?? this.config.defaultCommissionRate,
            branding: {
                companyName: input.name,
                hidePoweredBy: false,
                ...input.branding,
            },
            clientOrgIds: [],
            status: 'active',
            templates: [],
            createdAt: now,
            lastActiveAt: now,
        };
        this.partners.set(id, partner);
        return partner;
    }
    /**
     * Provision a new client organization under a partner.
     */
    provisionClient(partnerOrgId, input) {
        const partner = this.partners.get(partnerOrgId);
        if (!partner) {
            throw new Error(`Partner not found: ${partnerOrgId}`);
        }
        if (partner.status !== 'active') {
            throw new Error(`Partner is not active: ${partner.status}`);
        }
        if (partner.clientOrgIds.length >= this.config.maxClientsPerPartner) {
            throw new Error(`Partner has reached maximum clients: ${this.config.maxClientsPerPartner}`);
        }
        // Apply template if specified
        let activePacks = [];
        if (input.templateId) {
            const template = partner.templates.find(t => t.id === input.templateId);
            if (template) {
                activePacks = [...template.packs];
            }
        }
        const id = `client_${crypto.randomUUID()}`;
        const client = {
            id,
            partnerOrgId,
            name: input.name,
            contactEmail: input.contactEmail,
            vertical: input.vertical,
            activePacks,
            status: 'onboarding',
            createdAt: new Date().toISOString(),
        };
        this.clients.set(id, client);
        partner.clientOrgIds.push(id);
        partner.lastActiveAt = new Date().toISOString();
        return client;
    }
    /**
     * Activate a client org (move from onboarding to active).
     */
    activateClient(clientOrgId) {
        const client = this.clients.get(clientOrgId);
        if (!client)
            throw new Error(`Client not found: ${clientOrgId}`);
        client.status = 'active';
        return client;
    }
    /**
     * Add an onboarding template to a partner.
     */
    addTemplate(partnerOrgId, template) {
        const partner = this.partners.get(partnerOrgId);
        if (!partner)
            throw new Error(`Partner not found: ${partnerOrgId}`);
        const fullTemplate = {
            ...template,
            id: `tmpl_${crypto.randomUUID()}`,
        };
        partner.templates.push(fullTemplate);
        return fullTemplate;
    }
    /**
     * Record a commission for a partner.
     */
    recordCommission(partnerOrgId, clientOrgId, monthlyRevenue, period) {
        const partner = this.partners.get(partnerOrgId);
        if (!partner)
            throw new Error(`Partner not found: ${partnerOrgId}`);
        const record = {
            id: `comm_${crypto.randomUUID()}`,
            partnerOrgId,
            clientOrgId,
            monthlyRevenue,
            commissionAmount: Math.round(monthlyRevenue * partner.commissionRate * 100) / 100,
            period,
            createdAt: new Date().toISOString(),
        };
        this.commissions.push(record);
        return record;
    }
    /**
     * Get aggregate dashboard data for a partner.
     */
    getPartnerDashboard(partnerOrgId) {
        const partner = this.partners.get(partnerOrgId);
        if (!partner)
            throw new Error(`Partner not found: ${partnerOrgId}`);
        const clientOrgs = partner.clientOrgIds
            .map(id => this.clients.get(id))
            .filter((c) => c !== undefined);
        const activeClients = clientOrgs.filter(c => c.status === 'active');
        const recentCommissions = this.commissions
            .filter(c => c.partnerOrgId === partnerOrgId)
            .sort((a, b) => b.createdAt.localeCompare(a.createdAt))
            .slice(0, 10);
        return {
            partner,
            clientCount: clientOrgs.length,
            activeClientCount: activeClients.length,
            metrics: {
                totalAgents: 0, // Populated from external data
                totalEvents: 0,
                totalBlocked: 0,
                averageComplianceScore: 0,
                falsePositiveRate: 0,
            },
            recentCommissions,
            clientsNeedingAttention: [],
        };
    }
    /**
     * Update partner branding.
     */
    updateBranding(partnerOrgId, branding) {
        const partner = this.partners.get(partnerOrgId);
        if (!partner)
            throw new Error(`Partner not found: ${partnerOrgId}`);
        partner.branding = { ...partner.branding, ...branding };
        return partner;
    }
    /**
     * Get a partner by ID.
     */
    getPartner(partnerOrgId) {
        return this.partners.get(partnerOrgId);
    }
    /**
     * Get a client by ID.
     */
    getClient(clientOrgId) {
        return this.clients.get(clientOrgId);
    }
    /**
     * Get all clients for a partner.
     */
    getPartnerClients(partnerOrgId) {
        const partner = this.partners.get(partnerOrgId);
        if (!partner)
            return [];
        return partner.clientOrgIds
            .map(id => this.clients.get(id))
            .filter((c) => c !== undefined);
    }
    /**
     * Get all commissions for a partner.
     */
    getCommissions(partnerOrgId) {
        return this.commissions.filter(c => c.partnerOrgId === partnerOrgId);
    }
    /**
     * List all partners.
     */
    listPartners() {
        return Array.from(this.partners.values());
    }
    /**
     * Suspend a partner.
     */
    suspendPartner(partnerOrgId) {
        const partner = this.partners.get(partnerOrgId);
        if (!partner)
            throw new Error(`Partner not found: ${partnerOrgId}`);
        partner.status = 'suspended';
        return partner;
    }
}
exports.PartnerManager = PartnerManager;
//# sourceMappingURL=partner-manager.js.map