'use client';
import { jsx as _jsx } from "react/jsx-runtime";
import { createContext, useContext } from 'react';
import { NotificationEventType, } from '../../../../packages/core/src/domain/generated/output.js';
import { useAgentEvents, } from './use-agent-events.js';
export const AgentEventsContext = createContext(null);
/**
 * Single SSE connection for agent events shared across all consumers.
 * Wrap the app once; use `useAgentEventsContext()` to read.
 */
export function AgentEventsProvider({ children, runId }) {
    const result = useAgentEvents({ runId });
    return _jsx(AgentEventsContext.Provider, { value: result, children: children });
}
export function useAgentEventsContext() {
    const ctx = useContext(AgentEventsContext);
    if (!ctx) {
        throw new Error('useAgentEventsContext must be used within an <AgentEventsProvider>');
    }
    return ctx;
}
/**
 * Like {@link useAgentEventsContext} but returns `null` instead of throwing
 * when no provider is mounted — use this from components that also need to
 * render in isolated contexts (Storybook, unit tests) where the global
 * SSE provider is not available.
 */
export function useOptionalAgentEventsContext() {
    return useContext(AgentEventsContext);
}
/**
 * Latest `ApplicationUpdated` event scoped to one `applicationId`, or `null`.
 * Returns the payload (not the full `NotificationEvent`) because callers
 * only need the patchable fields.
 */
export function useApplicationUpdate(applicationId) {
    const ctx = useContext(AgentEventsContext);
    const last = ctx?.lastEvent;
    if (!last)
        return null;
    if (last.eventType !== NotificationEventType.ApplicationUpdated)
        return null;
    const payload = last.applicationUpdate;
    if (!payload)
        return null;
    if (payload.applicationId !== applicationId)
        return null;
    return payload;
}
/**
 * Latest `OperationLogAppended` entry scoped to one `applicationId`, or
 * `null`. Entries are scoped by `entry.operationId === applicationId`.
 */
export function useOperationLogAppend(applicationId) {
    const ctx = useContext(AgentEventsContext);
    const last = ctx?.lastEvent;
    if (!last)
        return null;
    if (last.eventType !== NotificationEventType.OperationLogAppended)
        return null;
    const entry = last.operationLogAppend?.entry;
    if (!entry)
        return null;
    if (entry.operationId !== applicationId)
        return null;
    return entry;
}
export function useAgentMessages(scope) {
    const ctx = useContext(AgentEventsContext);
    if (!ctx)
        return { messages: [], last: null };
    const messages = ctx.agentMessages.filter((m) => matchesMessageScope(m, scope));
    const last = ctx.lastAgentMessage && matchesMessageScope(ctx.lastAgentMessage, scope)
        ? ctx.lastAgentMessage
        : null;
    return { messages, last };
}
/**
 * Spec 093 — agent question stream scoped by scope type/id/feature.
 */
export function useAgentQuestions(scope) {
    const ctx = useContext(AgentEventsContext);
    if (!ctx)
        return { questions: [], last: null };
    const questions = ctx.agentQuestions.filter((q) => matchesMessageScope(q, scope));
    const last = ctx.lastAgentQuestion && matchesMessageScope(ctx.lastAgentQuestion, scope)
        ? ctx.lastAgentQuestion
        : null;
    return { questions, last };
}
/**
 * Spec 093 — supervisor decision stream scoped by scope type/id/feature.
 */
export function useSupervisorDecisions(scope) {
    const ctx = useContext(AgentEventsContext);
    if (!ctx)
        return { decisions: [], last: null };
    const decisions = ctx.supervisorDecisions.filter((d) => matchesDecisionScope(d, scope));
    const last = ctx.lastSupervisorDecision && matchesDecisionScope(ctx.lastSupervisorDecision, scope)
        ? ctx.lastSupervisorDecision
        : null;
    return { decisions, last };
}
function matchesMessageScope(event, scope) {
    if (scope.scopeType === 'app' && scope.scopeId && event.appId !== scope.scopeId)
        return false;
    if (scope.scopeType === 'repo' && scope.scopeId && event.repositoryId !== scope.scopeId)
        return false;
    if (scope.featureId !== undefined && event.featureId !== scope.featureId)
        return false;
    return true;
}
function matchesDecisionScope(event, scope) {
    if (scope.scopeType !== event.scopeType)
        return false;
    if (scope.scopeId && event.scopeId !== scope.scopeId)
        return false;
    if (scope.featureId !== undefined && event.featureId !== scope.featureId)
        return false;
    return true;
}
