/**
 * LLM Call Helper
 * Helper function for making LLM calls within workflow step handlers
 */

import { createLLMAdapter } from '../../../llm/adapters/server/adapter-factory'
import type { ModelConfig } from '../../../llm/model-info'
import type { ExecutionContext } from '../../../base/types'
import type { LLMMessage } from '../../../llm/types'

export interface LLMCallOptions {
  /** Model configuration (provider, model, API key) */
  modelConfig: ModelConfig
  /** Chat messages (system/user/assistant) */
  messages: LLMMessage[]
  /** JSON Schema for structured output */
  responseSchema: Record<string, unknown>
  /** Optional temperature override */
  temperature?: number
  /** Optional max output tokens override */
  maxOutputTokens?: number
  /** Optional step ID for observability context */
  stepId?: string
  /** Optional step name for observability context */
  stepName?: string
}

/**
 * Make an LLM call within a workflow step handler
 *
 * Automatically integrates with observability tracking via ExecutionContext.
 * Tracks calls with `callType: 'workflow-step'` in AI usage metrics.
 *
 * @example
 * ```typescript
 * const summarizeStep: WorkflowStep = {
 *   id: 'summarize',
 *   name: 'Summarize Data',
 *   handler: async (input, context) => {
 *     const result = await llmCall(context, {
 *       modelConfig: {
 *         provider: 'openrouter',
 *         model: 'openrouter/anthropic/claude-sonnet-4.5',
 *         apiKey: process.env.OPENROUTER_API_KEY!
 *       },
 *       messages: [
 *         { role: 'system', content: 'You are a summarization expert.' },
 *         { role: 'user', content: `Summarize: ${input.data}` }
 *       ],
 *       responseSchema: {
 *         type: 'object',
 *         properties: { summary: { type: 'string' } },
 *         required: ['summary']
 *       },
 *       stepId: 'summarize',
 *       stepName: 'Summarize Data'
 *     })
 *
 *     return { summary: result.summary }
 *   },
 *   inputSchema: z.object({ data: z.string() }),
 *   outputSchema: z.object({ summary: z.string() }),
 *   next: { type: StepType.LINEAR, target: 'next-step' }
 * }
 * ```
 */
export async function llmCall<T = unknown>(context: ExecutionContext, options: LLMCallOptions): Promise<T> {
  const { modelConfig, messages, responseSchema, temperature, maxOutputTokens, stepId, stepName } = options

  const adapter = createLLMAdapter(
    {
      ...modelConfig,
      ...(temperature !== undefined && { temperature }),
      ...(maxOutputTokens !== undefined && { maxOutputTokens })
    },
    context.aiUsageCollector,
    'workflow-step',
    {
      type: 'workflow-step',
      stepId: stepId ?? 'unknown',
      stepName
    }
  )

  const response = await adapter.generate<T>({
    messages,
    responseSchema,
    temperature,
    maxOutputTokens
  })

  return response.output
}
