/**
 * Mock LLM Adapter
 * Provides a simple mock implementation for testing purposes
 */

import type { LLMAdapter, LLMGenerateRequest, LLMGenerateResponse } from '../types'
import type { AgentAction } from '../../agent/actions/types'

/**
 * Mock response for agent iteration scenarios
 */
export interface MockIterationResponse {
  reasoning?: string
  memoryOps?: { set?: Record<string, string>, delete?: string[] }
  nextActions?: AgentAction[]
}

/**
 * Configuration for MockAdapter
 * Supports multi-iteration scenarios via response queue
 */
export interface MockAdapterConfig {
  // Queue of responses for multi-iteration scenarios
  responses?: MockIterationResponse[]

  // Completion phase output
  completionOutput?: unknown
}

/**
 * Check if the model and provider combination is for Mock
 *
 * @param model - Model identifier (e.g., 'mock')
 * @param provider - Provider name
 * @returns True if this is a mock model configuration
 */
export function isMockModel(model: string, provider: string): boolean {
  return model === 'mock' || provider === 'mock'
}

/**
 * Mock adapter that returns appropriate responses based on request schema
 * Used for testing and development without making real API calls
 *
 * Supports:
 * - Response queue for multi-iteration testing
 * - Call count tracking
 * - Realistic token usage simulation
 * - Backward compatible default behavior
 */
/**
 * Minimal JSON Schema interface for checking schema structure
 */
interface JsonSchemaWithProperties {
  properties?: Record<string, unknown>
}

export class MockAdapter implements LLMAdapter {
  private responseQueue: MockIterationResponse[] = []
  private callCount = 0

  constructor(private config: MockAdapterConfig = {}) {
    this.responseQueue = [...(config.responses || [])]
  }

  async generate<T = unknown>(request: LLMGenerateRequest): Promise<LLMGenerateResponse<T>> {
    // Check if this is an agent iteration request (has reasoning + nextActions)
    const schema = request.responseSchema as JsonSchemaWithProperties | undefined
    const isAgentIteration = schema?.properties?.reasoning && schema?.properties?.nextActions

    this.callCount++

    if (isAgentIteration) {
      // Use next response from queue, or default to immediate completion
      const response = this.responseQueue.shift() || {
        reasoning: 'Mock reasoning',
        nextActions: [{ type: 'complete' }]
      }

      // Return agent iteration response
      return {
        output: {
          reasoning: response.reasoning || 'Mock reasoning',
          memoryOps: response.memoryOps || {},
          nextActions: response.nextActions || [{ type: 'complete' }]
        } as T,
        usage: {
          inputTokens: 100 * this.callCount,
          outputTokens: 50 * this.callCount,
          totalTokens: 150 * this.callCount
        }
      }
    }

    // Return generic completion response
    return {
      output: (this.config.completionOutput || {
        response: 'Mock response',
        processedAt: new Date().toISOString()
      }) as T,
      usage: {
        inputTokens: 50,
        outputTokens: 25,
        totalTokens: 75
      }
    }
  }

  /**
   * Get total number of generate() calls made
   * Useful for verifying expected iteration counts in tests
   */
  getCallCount(): number {
    return this.callCount
  }
}
