import type { Tool, ToolExecutionOptions } from '../../types'
import { serviceUnavailable } from '../../types'
import type { CreateTaskParams, ActionConfig } from '../../../../../commands/queue/types'
import { getToolServices } from '../../registry'
import type { ApprovalToolConfig } from '../types'

/**
 * Create an approval tool that sends tasks to the command queue for human approval
 *
 * Approval tools enable human-in-the-loop workflows by creating tasks that require
 * human approval before proceeding. The task contains the input payload and routes
 * to specified agents based on approval/rejection.
 *
 * @param config - Configuration for the approval tool
 * @returns Tool that creates approval tasks in the command queue
 *
 * @example
 * const approvalTool = createApprovalTool({
 *   name: 'request_payment_approval',
 *   description: 'Request approval for high-value payment',
 *   inputSchema: z.object({ amount: z.number(), recipient: z.string() }),
 *   outputSchema: z.object({ taskId: z.string() }),
 *   approveTargetResourceId: 'payment-processor-agent',
 *   rejectTargetResourceId: 'payment-rejection-handler',
 *   priority: 8
 * })
 */
export function createApprovalTool(config: ApprovalToolConfig): Tool {
  return {
    name: config.name,
    description: config.description,
    inputSchema: config.inputSchema,
    outputSchema: config.outputSchema,

    async execute(options: ToolExecutionOptions): Promise<unknown> {
      // ExecutionContext is required for platform tools
      if (!options.executionContext) {
        throw serviceUnavailable('ExecutionContext', { tool: config.name, reason: 'organizationId required for multi-tenant isolation' })
      }

      // Get command queue service from global registry
      const { commandQueueService: commandQueue } = getToolServices()
      if (!commandQueue) {
        throw serviceUnavailable('CommandQueueService', {
          message: 'Ensure toolServicesRegistry.initialize() was called in apps/api/src/main.ts',
          tool: config.name
        })
      }

      // Build task parameters using execution context
      // Convert old approve/reject pattern to new action-based schema
      const actions: ActionConfig[] = [
        {
          id: 'approve',
          label: 'Approve',
          type: 'primary',
          icon: 'IconCheck',
          color: 'green',
          target: {
            resourceType: 'agent',
            resourceId: config.approveTargetResourceId
          }
        }
      ]

      // Add reject action if configured
      if (config.rejectTargetResourceId) {
        actions.push({
          id: 'reject',
          label: 'Reject',
          type: 'danger',
          icon: 'IconX',
          color: 'red',
          target: {
            resourceType: 'agent',
            resourceId: config.rejectTargetResourceId
          }
        })
      }

      const params: CreateTaskParams = {
        organizationId: options.executionContext.organizationId,
        originExecutionId: options.executionContext.executionId,
        originResourceType: 'agent',
        originResourceId: options.executionContext.resourceId,
        actions,
        context: options.input,
        priority: config.priority ?? 5,
        expiresAt: config.expiresAt
      }

      // Create task in command queue
      const task = await commandQueue.createTask(params)

      // Return task ID for tracking
      return { taskId: task.id }
    }
  }
}
