/**
 * Interactive Session Service — THIN FACADE (Phase 7 of 7)
 *
 * Implements `IInteractiveSessionService` by delegating every public method
 * to the appropriate collaborator. Contains NO business logic of its own.
 *
 * Collaborator map:
 * - `SessionBootstrapper`        — startSession
 * - `SessionTerminator`          — stopSession, stopByFeature, clearMessages
 * - `MessageDispatcher`          — sendMessage, sendUserMessage
 * - `IInteractiveMessageRepository` — getMessages
 * - `IInteractiveSessionRepository` — getSession, getTurnStatuses, getAllActiveTurnStatuses
 * - `StreamEventDispatcher`      — subscribe, subscribeByFeature, subscribeAll
 * - `ChatStateAssembler`         — getChatState
 * - `SessionPersistence`         — markRead
 * - `UserInteractionCoordinator` — respondToInteraction
 * - `WorkflowHooks`              — setActiveStep, clearActiveStep, notifyWorkflowStep, waitForTurnDone
 *
 * See `docs/plans/2026-04-14-interactive-session-service-refactor.md` for
 * the full strangler-refactor history (phases 1–7).
 */
/**
 * Core service managing interactive agent session lifecycles.
 * Must be registered as a singleton in the DI container.
 *
 * **Polymorphic `featureId` scope key:** The `featureId` parameter accepted
 * by public methods (`sendUserMessage`, `getChatState`, `subscribeByFeature`,
 * etc.) is a polymorphic scope key — not necessarily a feature UUID:
 * - Feature chat: actual feature UUID (e.g. `"feat-abc123"`)
 * - Repository chat: repo identifier (e.g. `"repo-<repoId>"`)
 * - Global chat: literal string `"global"`
 *
 * Sessions and messages are isolated by this key regardless of chat type.
 *
 * @todo Consider renaming to `scopeId` + adding a `scopeType` discriminator.
 */
export class InteractiveSessionService {
    sessionRepo;
    messageRepo;
    dispatcher;
    persistence;
    bootstrapper;
    terminator;
    interactionCoordinator;
    messageDispatcher;
    chatStateAssembler;
    workflowHooks;
    constructor(sessionRepo, messageRepo, _featureRepo, // owned by SessionBootstrapper — kept for signature arity
    _contextBuilder, // owned by BootPromptResolver — kept for signature arity
    _workflowStepRepo, // owned by SessionTerminator — kept for signature arity
    _registry, // owned by collaborators — kept for signature arity
    dispatcher, persistence, _logger, // owned by collaborators — kept for signature arity
    bootstrapper, terminator, _turnExecutor, // owned by MessageDispatcher — kept for signature arity
    interactionCoordinator, messageDispatcher, chatStateAssembler, workflowHooks) {
        this.sessionRepo = sessionRepo;
        this.messageRepo = messageRepo;
        this.dispatcher = dispatcher;
        this.persistence = persistence;
        this.bootstrapper = bootstrapper;
        this.terminator = terminator;
        this.interactionCoordinator = interactionCoordinator;
        this.messageDispatcher = messageDispatcher;
        this.chatStateAssembler = chatStateAssembler;
        this.workflowHooks = workflowHooks;
    }
    // ---------------------------------------------------------------------------
    // Session lifecycle
    // ---------------------------------------------------------------------------
    async startSession(featureId, worktreePath, model, agentType, systemPrompt, initialUserMessage) {
        return this.bootstrapper.startSession(featureId, worktreePath, model, agentType, systemPrompt, initialUserMessage);
    }
    async stopSession(sessionId) {
        return this.terminator.stop(sessionId);
    }
    async stopByFeature(featureId) {
        return this.terminator.stopByFeature(featureId);
    }
    // ---------------------------------------------------------------------------
    // Messaging
    // ---------------------------------------------------------------------------
    async sendMessage(sessionId, content) {
        return this.messageDispatcher.sendMessage(sessionId, content);
    }
    async sendUserMessage(featureId, content, worktreePath, model, agentType, systemPrompt, agentKickoffOverride, persistUserMessage = true) {
        return this.messageDispatcher.sendUserMessage(featureId, content, worktreePath, model, agentType, systemPrompt, agentKickoffOverride, persistUserMessage);
    }
    async getMessages(featureId, limit) {
        return this.messageRepo.findByFeatureId(featureId, limit);
    }
    async clearMessages(featureId) {
        return this.terminator.clearFeatureMessages(featureId);
    }
    // ---------------------------------------------------------------------------
    // Session reads
    // ---------------------------------------------------------------------------
    async getSession(sessionId) {
        return this.sessionRepo.findById(sessionId);
    }
    async getTurnStatuses(featureIds) {
        return this.sessionRepo.getTurnStatuses(featureIds);
    }
    async getAllActiveTurnStatuses() {
        return this.sessionRepo.getAllActiveTurnStatuses();
    }
    // ---------------------------------------------------------------------------
    // Subscriptions
    // ---------------------------------------------------------------------------
    subscribe(sessionId, onChunk) {
        return this.dispatcher.subscribeSession(sessionId, onChunk);
    }
    subscribeByFeature(featureId, onChunk) {
        return this.dispatcher.subscribeByFeature(featureId, onChunk);
    }
    subscribeAll(onChunk) {
        return this.dispatcher.subscribeAll(onChunk);
    }
    // ---------------------------------------------------------------------------
    // Chat state & read tracking
    // ---------------------------------------------------------------------------
    async getChatState(featureId) {
        return this.chatStateAssembler.assemble(featureId);
    }
    async markRead(featureId) {
        return this.persistence.markRead(featureId);
    }
    // ---------------------------------------------------------------------------
    // Interaction handling
    // ---------------------------------------------------------------------------
    async respondToInteraction(featureId, answers) {
        return this.interactionCoordinator.respondToInteractionByFeature(featureId, answers);
    }
    // ---------------------------------------------------------------------------
    // Workflow orchestrator hooks — delegated to WorkflowHooks
    // ---------------------------------------------------------------------------
    setActiveStep(featureId, stepId) {
        this.workflowHooks.setActiveStep(featureId, stepId);
    }
    clearActiveStep(featureId) {
        this.workflowHooks.clearActiveStep(featureId);
    }
    notifyWorkflowStep(featureId, step) {
        this.workflowHooks.notifyWorkflowStep(featureId, step);
    }
    async waitForTurnDone(featureId, signal) {
        return this.workflowHooks.waitForTurnDone(featureId, signal);
    }
}
