/**
 * Reasoning Phase Processor
 * Handles LLM interaction for the REASON phase of agent execution
 */

import type { IterationContext } from '../core/types'
import type { LLMIterationResponse } from './types'
import { buildReasoningRequest } from './request-builder'
import { callLLMForAgentIteration } from './adapters/agent-adapter-helpers'

/**
 * Process reasoning phase - Query LLM for next actions
 * Handles adapter resolution, request building, LLM call, logging, and memory storage
 *
 * @param iterationContext - Agent execution context
 * @returns LLM's reasoning and planned actions
 */
export async function processReasoning(iterationContext: IterationContext): Promise<LLMIterationResponse> {
  // Create adapter via injected factory (stateless, per-iteration)
  // API process: factory wraps with UniversalLLMAdapter for retry, circuit breaker, observability
  // SDK worker: factory creates PostMessageLLMAdapter that proxies via platform.call()
  const adapter = iterationContext.adapterFactory(
    iterationContext.modelConfig,
    iterationContext.executionContext.aiUsageCollector,
    'agent-reasoning',
    {
      type: 'agent-reasoning',
      iteration: iterationContext.iteration,
      sessionId: iterationContext.executionContext.sessionId,
      turnNumber: iterationContext.executionContext.sessionTurnNumber
    }
  )

  // Build agent iteration request
  const request = buildReasoningRequest(iterationContext)

  // Track timing for LLM call
  const startTime = Date.now()

  // Get LLM iteration response using agent-specific helper
  const { reasoning, memoryOps, nextActions } = await callLLMForAgentIteration(adapter, {
    systemPrompt: request.systemPrompt,
    memoryContext: request.memoryContext,
    tools: request.tools,
    constraints: request.constraints,
    model: iterationContext.modelConfig.model,
    includeMessageAction: request.includeMessageAction,
    includeNavigateKnowledge: request.includeNavigateKnowledge,
    includeMemoryOps: request.includeMemoryOps,
    signal: iterationContext.executionContext.signal
  })

  const endTime = Date.now()
  const duration = endTime - startTime

  const response: LLMIterationResponse = { reasoning, memoryOps, nextActions }

  // Emit reasoning event (for session message persistence)
  await iterationContext.executionContext.onMessageEvent?.({
    type: 'agent:reasoning',
    iteration: iterationContext.iteration,
    reasoning: response.reasoning
  })

  // Log reasoning event (always present in universal protocol)
  iterationContext.logger.reasoning(response.reasoning, iterationContext.iteration, startTime, endTime, duration)

  // Store reasoning in memory (always, even when completing)
  // This preserves the LLM's thought process for future iterations
  const memoryStartTime = Date.now()

  iterationContext.memoryManager.addToHistory({
    type: 'reasoning',
    content: response.reasoning,
    turnNumber: iterationContext.executionContext.sessionTurnNumber ?? null,
    iterationNumber: iterationContext.iteration
  })

  const memoryEndTime = Date.now()
  const memoryDuration = memoryEndTime - memoryStartTime

  iterationContext.logger.action(
    'memory-reasoning',
    `Stored reasoning (${response.reasoning.length} chars), history size: ${iterationContext.memoryManager.getHistoryLength()}, actions: ${response.nextActions.map((a) => a.type).join(', ')}`,
    iterationContext.iteration,
    memoryStartTime,
    memoryEndTime,
    memoryDuration
  )

  return response
}
