/// Example usage of Agent API endpoints
///
/// This file demonstrates how to use the Agent CRUD operations
/// with the CQRS API client.
library;

import '../api.dart';

/// Example: Create and manage an AI agent
Future<void> agentExample() async {
  // Initialize API client
  final CqrsApiClient client = CqrsApiClient(
    config: ApiClientConfig.development,
  );

  try {
    // 1. Create a new agent
    print('Creating new agent...');
    final Result<void> createResult = await client.createAgent(
      CreateAgentCommand(
        name: 'Code Generator',
        description: 'AI agent for code generation tasks',
        type: AgentType.codeGenerator,
        modelProvider: 'ollama',
        modelName: 'phi',
        providerType: ModelProviderType.localEndpoint,
        modelEndpoint: 'http://localhost:11434',
        temperature: 0.7,
        maxTokens: 4000,
        systemPrompt: 'You are a helpful code generation assistant.',
        enableMemory: true,
        conversationWindowSize: 10,
      ),
    );

    createResult.when(
      success: (_) => print('✓ Agent created successfully'),
      error: (ApiErrorInfo error) =>
          print('✗ Failed to create agent: ${error.message}'),
    );

    // 2. Get agent by ID
    print('\nFetching agent details...');
    final String agentId = 'your-agent-uuid-here'; // Replace with actual ID
    final Result<AgentDto> getResult = await client.getAgent(agentId);

    getResult.when(
      success: (AgentDto agent) {
        print('✓ Agent found:');
        print('  Name: ${agent.name}');
        print('  Type: ${agent.type.value}');
        print('  Status: ${agent.status.value}');
        print('  Model: ${agent.modelProvider}/${agent.modelName}');
        print('  Created: ${agent.createdAt}');
      },
      error: (ApiErrorInfo error) =>
          print('✗ Failed to fetch agent: ${error.message}'),
    );

    // 3. Update agent
    print('\nUpdating agent...');
    final Result<void> updateResult = await client.updateAgent(
      UpdateAgentCommand(
        id: agentId,
        name: 'Advanced Code Generator',
        temperature: 0.8,
        status: AgentStatus.active,
      ),
    );

    updateResult.when(
      success: (_) => print('✓ Agent updated successfully'),
      error: (ApiErrorInfo error) =>
          print('✗ Failed to update agent: ${error.message}'),
    );

    // 4. Delete agent
    print('\nDeleting agent...');
    final Result<void> deleteResult = await client.deleteAgent(
      DeleteAgentCommand(id: agentId),
    );

    deleteResult.when(
      success: (_) => print('✓ Agent deleted successfully'),
      error: (ApiErrorInfo error) =>
          print('✗ Failed to delete agent: ${error.message}'),
    );

    // 5. Pattern matching example with switch expression
    final String message = switch (getResult) {
      ApiSuccess(value: final AgentDto agent) =>
        'Agent "${agent.name}" is ${agent.status.value}',
      ApiError(error: final ApiErrorInfo err) => 'Error: ${err.message}',
    };
    print('\nPattern match result: $message');
  } finally {
    // Always dispose client when done
    client.dispose();
  }
}

/// Example: Error handling patterns
Future<void> errorHandlingExample() async {
  final CqrsApiClient client = CqrsApiClient(
    config: ApiClientConfig.development,
  );

  try {
    final Result<AgentDto> result = await client.getAgent('invalid-uuid');

    // Pattern 1: when() method
    result.when(
      success: (AgentDto agent) {
        print('Success: ${agent.name}');
      },
      error: (ApiErrorInfo error) {
        switch (error.type) {
          case ApiErrorType.network:
            print('No internet connection');
          case ApiErrorType.timeout:
            print('Request timed out');
          case ApiErrorType.http:
            if (error.statusCode == 404) {
              print('Agent not found');
            } else if (error.statusCode == 401) {
              print('Unauthorized - check API key');
            } else {
              print('HTTP error: ${error.statusCode}');
            }
          case ApiErrorType.validation:
            print('Validation error: ${error.details}');
          case ApiErrorType.serialization:
            print('JSON parsing failed');
          case ApiErrorType.unknown:
            print('Unexpected error: ${error.message}');
        }
      },
    );

    // Pattern 2: Switch expression
    final String statusMessage = switch (result) {
      ApiSuccess() => 'Agent loaded successfully',
      ApiError(error: final ApiErrorInfo err) when err.statusCode == 404 =>
        'Agent not found',
      ApiError(error: final ApiErrorInfo err) =>
        'Error: ${err.type.name} - ${err.message}',
    };
    print(statusMessage);
  } finally {
    client.dispose();
  }
}

/// Example: Creating agents with different configurations
Future<void> agentVariationsExample() async {
  final CqrsApiClient client = CqrsApiClient(
    config: ApiClientConfig.development,
  );

  try {
    // Local Ollama model
    final CreateAgentCommand localAgent = CreateAgentCommand(
      name: 'Local Code Reviewer',
      description: 'Reviews code using local Ollama model',
      type: AgentType.codeReviewer,
      modelProvider: 'ollama',
      modelName: 'codellama:7b',
      providerType: ModelProviderType.localEndpoint,
      modelEndpoint: 'http://localhost:11434',
      systemPrompt: 'You are a code review expert.',
      temperature: 0.5,
      maxTokens: 2000,
    );

    // Cloud API model (OpenAI)
    final CreateAgentCommand cloudAgent = CreateAgentCommand(
      name: 'Cloud Debugger',
      description: 'Advanced debugging assistant using GPT-4',
      type: AgentType.debugger,
      modelProvider: 'openai',
      modelName: 'gpt-4o',
      providerType: ModelProviderType.cloudApi,
      apiKey: 'your-openai-api-key-here',
      systemPrompt: 'You are an expert debugger.',
      temperature: 0.3,
      maxTokens: 8000,
    );

    // Custom model
    final CreateAgentCommand customAgent = CreateAgentCommand(
      name: 'Documentation Writer',
      description: 'Generates comprehensive documentation',
      type: AgentType.documenter,
      modelProvider: 'custom',
      modelName: 'custom-model-v1',
      providerType: ModelProviderType.custom,
      modelEndpoint: 'https://api.example.com/v1/chat',
      apiKey: 'custom-api-key',
      systemPrompt: 'You are a technical documentation expert.',
      temperature: 0.6,
      maxTokens: 6000,
      conversationWindowSize: 20,
    );

    // Create all agents
    await client.createAgent(localAgent);
    await client.createAgent(cloudAgent);
    await client.createAgent(customAgent);
  } finally {
    client.dispose();
  }
}
