/**
 * Hierarchy Reporting Service
 *
 * Handles the hierarchical reporting chain: Workers report to Team Leaders,
 * Team Leaders aggregate and report up to the Orchestrator.
 *
 * Key responsibilities:
 * - Receive worker status reports and route them to the Team Leader
 * - Aggregate multiple worker reports into a single TL report
 * - Generate AggregatedReport format for Orchestrator consumption
 * - Emit hierarchy:report_up events when reports flow upward
 *
 * @module services/hierarchy/hierarchy-reporting
 */
// =============================================================================
// Service
// =============================================================================
/**
 * HierarchyReportingService manages the upward reporting chain.
 * Singleton pattern matching other Crewly services.
 */
export class HierarchyReportingService {
    static instance = null;
    /** Stored worker reports indexed by parentTaskId */
    workerReports = new Map();
    /** Event bus reference for emitting hierarchy events */
    eventBus = null;
    constructor() { }
    /**
     * Get the singleton instance of HierarchyReportingService.
     *
     * @returns The singleton instance
     */
    static getInstance() {
        if (!HierarchyReportingService.instance) {
            HierarchyReportingService.instance = new HierarchyReportingService();
        }
        return HierarchyReportingService.instance;
    }
    /**
     * Clear the singleton instance (for testing).
     */
    static clearInstance() {
        HierarchyReportingService.instance = null;
    }
    /**
     * Set the EventBusService reference for emitting events.
     *
     * @param eventBus - The EventBusService instance
     */
    setEventBus(eventBus) {
        this.eventBus = eventBus;
    }
    /**
     * Receive a worker's status report and store it for aggregation.
     * Called when a Worker sends a StatusReport to their Team Leader.
     *
     * @param report - The worker's status report
     * @param workerSession - Session name of the reporting worker
     * @param parentTaskId - The parent task ID this report belongs to
     * @returns The stored report entry
     */
    receiveWorkerReport(report, workerSession, parentTaskId) {
        const entry = {
            report,
            receivedAt: new Date().toISOString(),
            workerSession,
        };
        const existing = this.workerReports.get(parentTaskId) ?? [];
        existing.push(entry);
        this.workerReports.set(parentTaskId, existing);
        return entry;
    }
    /**
     * Aggregate all stored worker reports for a parent task and generate
     * an AggregatedReport for the Orchestrator.
     *
     * @param parentTaskId - The parent task to aggregate reports for
     * @param subtasks - All subtasks under this parent task
     * @param tlSummary - Team Leader's summary of the aggregated work
     * @param tlSession - Team Leader's session name
     * @param teamInfo - Team and member info for event emission
     * @returns The aggregated report, or null if no reports exist
     */
    aggregateAndReportUp(parentTaskId, subtasks, tlSummary, tlSession, teamInfo) {
        const report = this.generateAggregatedReport(parentTaskId, subtasks, tlSummary, tlSession);
        if (!report) {
            return null;
        }
        // Emit hierarchy:report_up event
        if (this.eventBus && teamInfo) {
            const event = {
                id: crypto.randomUUID(),
                type: 'hierarchy:report_up',
                timestamp: new Date().toISOString(),
                teamId: teamInfo.teamId,
                teamName: teamInfo.teamName,
                memberId: teamInfo.memberId,
                memberName: teamInfo.memberName,
                sessionName: tlSession,
                previousValue: '',
                newValue: report.overallState,
                changedField: 'hierarchyAction',
                taskId: parentTaskId,
            };
            this.eventBus.publish(event);
        }
        // Clean up stored reports after aggregation
        this.workerReports.delete(parentTaskId);
        return report;
    }
    /**
     * Generate an AggregatedReport from subtask data.
     * Computes the overall state, subtask summary, and collects key artifacts.
     *
     * @param parentTaskId - The parent task ID
     * @param subtasks - All subtasks under this parent task
     * @param tlSummary - Team Leader's written summary
     * @param tlSession - Team Leader's session name
     * @returns The aggregated report, or null if no subtasks
     */
    generateAggregatedReport(parentTaskId, subtasks, tlSummary, tlSession) {
        if (subtasks.length === 0) {
            return null;
        }
        const summary = this.computeSubtaskSummary(subtasks);
        const overallState = this.computeOverallState(summary);
        const keyArtifacts = this.collectKeyArtifacts(subtasks);
        const qualityAssessment = this.assessQuality(summary);
        return {
            type: 'aggregated_report',
            parentTaskId,
            overallState,
            summary: tlSummary,
            subtaskSummary: summary,
            ...(keyArtifacts.length > 0 ? { keyArtifacts } : {}),
            qualityAssessment,
            reportedBy: tlSession,
            timestamp: new Date().toISOString(),
        };
    }
    /**
     * Get stored worker reports for a parent task.
     *
     * @param parentTaskId - The parent task ID
     * @returns Array of stored worker reports
     */
    getWorkerReports(parentTaskId) {
        return this.workerReports.get(parentTaskId) ?? [];
    }
    /**
     * Clear all stored reports (for cleanup/testing).
     */
    clearReports() {
        this.workerReports.clear();
    }
    /**
     * Serialize an AggregatedReport to markdown for PTY delivery.
     *
     * @param report - The aggregated report to serialize
     * @returns Markdown-formatted string with [AGGREGATED REPORT] header
     */
    serializeAggregatedReport(report) {
        const lines = [
            '---',
            '[AGGREGATED REPORT]',
            `Parent Task: ${report.parentTaskId}`,
            `Overall Status: ${report.overallState}`,
            ...(report.qualityAssessment ? [`Quality: ${report.qualityAssessment}`] : []),
            `Reported by: ${report.reportedBy}`,
            '---',
            '',
            '## Summary',
            report.summary,
            '',
            '## Subtask Breakdown',
            `- Total: ${report.subtaskSummary.total} | Completed: ${report.subtaskSummary.completed} | Failed: ${report.subtaskSummary.failed} | In Progress: ${report.subtaskSummary.inProgress} | Blocked: ${report.subtaskSummary.blocked}`,
        ];
        if (report.keyArtifacts && report.keyArtifacts.length > 0) {
            lines.push('', '## Key Deliverables');
            for (const artifact of report.keyArtifacts) {
                lines.push(`- ${artifact.content} (${artifact.type})`);
            }
        }
        if (report.escalations && report.escalations.length > 0) {
            lines.push('', '## Escalations');
            for (const esc of report.escalations) {
                lines.push(`- ${esc}`);
            }
        }
        return lines.join('\n');
    }
    // ===========================================================================
    // Private helpers
    // ===========================================================================
    /**
     * Compute the subtask summary counts from task list.
     */
    computeSubtaskSummary(subtasks) {
        let completed = 0;
        let failed = 0;
        let inProgress = 0;
        let blocked = 0;
        for (const task of subtasks) {
            switch (task.status) {
                case 'completed':
                    completed++;
                    break;
                case 'failed':
                case 'cancelled':
                    failed++;
                    break;
                case 'blocked':
                case 'input_required':
                    blocked++;
                    break;
                case 'active':
                case 'working':
                case 'assigned':
                case 'submitted':
                case 'verifying':
                    inProgress++;
                    break;
                default:
                    inProgress++;
                    break;
            }
        }
        return {
            total: subtasks.length,
            completed,
            failed,
            inProgress,
            blocked,
        };
    }
    /**
     * Determine the overall state from subtask summary.
     */
    computeOverallState(summary) {
        if (summary.total === 0)
            return 'pending_assignment';
        if (summary.completed === summary.total)
            return 'completed';
        if (summary.failed > 0 && summary.inProgress === 0 && summary.completed + summary.failed === summary.total)
            return 'failed';
        if (summary.blocked > 0 && summary.inProgress === 0)
            return 'blocked';
        return 'working';
    }
    /**
     * Collect key artifacts from completed subtasks.
     */
    collectKeyArtifacts(subtasks) {
        const artifacts = [];
        for (const task of subtasks) {
            if (task.artifacts) {
                artifacts.push(...task.artifacts);
            }
        }
        return artifacts;
    }
    /**
     * Assess overall quality from subtask completion rates.
     */
    assessQuality(summary) {
        if (summary.total === 0)
            return 'fail';
        if (summary.completed === summary.total)
            return 'pass';
        if (summary.failed === summary.total)
            return 'fail';
        return 'partial';
    }
}
//# sourceMappingURL=hierarchy-reporting.service.js.map