import { agentProcessManager, llmRequestAbortManager, state, agentSessionStateManager, toolApprovalManager } from "./state"
import { emitAgentProgress } from "./emit-agent-progress"
import { agentSessionTracker } from "./agent-session-tracker"
import { messageQueueService } from "./message-queue-service"
import { acpService } from "./acp-service"

/**
 * Centralized emergency stop: abort LLM requests, kill tracked child processes,
 * and reset agent state.
 *
 * NOTE: This does NOT stop MCP servers - they are persistent infrastructure
 * that should remain running across agent mode sessions.
 *
 * Returns before/after counts for logging.
 */
export async function emergencyStopAll(): Promise<{ before: number; after: number }> {
  // Signal all sessions to stop ASAP (both new session-based and legacy global)
  agentSessionStateManager.stopAllSessions()

  // Mark all active agent sessions as stopped in the tracker and emit progress updates
  try {
    const activeSessions = agentSessionTracker.getActiveSessions()
    for (const session of activeSessions) {
      // Cancel any pending tool approvals for this session
      toolApprovalManager.cancelSessionApprovals(session.id)

      // Pause the message queue for this conversation to prevent processing the next queued message
      // The user can resume the queue later if they want to continue
      if (session.conversationId) {
        messageQueueService.pauseQueue(session.conversationId)
      }

      // Emit a final progress update so the UI shows "Stopped" state
      // This allows users to see the stopped state and send follow-up messages
      // Note: pendingToolApproval is explicitly set to undefined to clear any stale
      // approval bubble from the UI since updateSessionProgress preserves fields not
      // present in the update (spreads existing state)
      await emitAgentProgress({
        sessionId: session.id,
        conversationId: session.conversationId,
        conversationTitle: session.conversationTitle,
        currentIteration: 0,
        maxIterations: 0,
        steps: [
          {
            id: `stop_${Date.now()}`,
            type: "completion",
            title: "Agent stopped",
            description: "Agent mode was stopped by emergency kill switch. Queue paused.",
            status: "error",
            timestamp: Date.now(),
          },
        ],
        isComplete: true,
        finalContent: "(Agent mode was stopped by emergency kill switch)",
        pendingToolApproval: undefined,
      })

      // We do NOT call agentSessionTracker.stopSession(session.id) here anymore.
      // Doing so bypasses the normal completion flow and can cause the UI to
      // abruptly hide the session from the sidebar before tipc.ts handles the error.
      // The session will be naturally stopped or completed by the tipc.ts caller
      // after the abort signals propagate.
    }
  } catch {
    // ignore
  }

  // Abort any in-flight LLM HTTP requests (handled by session state manager)
  // This is already done in stopAllSessions(), but we keep the legacy call for safety
  try {
    llmRequestAbortManager.abortAll()
  } catch {
    // ignore
  }

  // NOTE: We do NOT stop MCP servers here - they are persistent infrastructure
  // that should remain running. Only agent-spawned child processes are killed.

  const before = agentProcessManager.getActiveProcessCount()

  // Kill all tracked child processes immediately
  try {
    agentProcessManager.emergencyStop()
  } catch {
    // ignore
  }

  const after = agentProcessManager.getActiveProcessCount()

	  // Clean up all session states while preserving cached response history so
	  // stopped sessions can still render prior conversation context in the UI.
  for (const [sessionId] of state.agentSessions) {
    agentSessionStateManager.cleanupSession(sessionId)
  }

  // Reset some core agent state flags for clean state
  // NOTE: We intentionally do NOT reset state.shouldStopAgent here!
  // It should remain true to block any late/in-flight progress updates that may
  // arrive after cleanup. It will be reset to false when a new session is created.
  // This prevents a race condition where stray updates slip through after emergency stop.
  state.isAgentModeActive = false
  state.agentIterationCount = 0

  // Stop all acpx-managed agents/sessions - isolated so failures don't prevent rest of cleanup
  try {
    await acpService.shutdown()
  } catch (error) {
    // Log but don't fail - emergency stop should be best-effort
    console.error('[EmergencyStop] Error shutting down acpx service:', error)
  }

  return { before, after }
}

