// ==============================================================================
// Multi-Agent System - Contracts
// Interfaces, DTOs e Enums para sistema multi-agente
// ==============================================================================

using Microsoft.SemanticKernel;

namespace MultiAgent.Contracts;

// ==============================================================================
// ENUMS
// ==============================================================================

public enum MessageRole
{
    User,
    Assistant,
    System
}

public enum TaskStatus
{
    Pending,
    Running,
    Completed,
    Failed,
    Cancelled
}

public enum AgentType
{
    Orchestrator,
    Research,
    Analysis,
    Writing,
    Custom
}

// ==============================================================================
// DTOs - CHAT
// ==============================================================================

public record ChatRequest(
    string Message,
    string? SessionId = null,
    bool Stream = false,
    ChatOptions? Options = null
);

public record ChatOptions(
    int? MaxTokens = null,
    double? Temperature = null,
    string[]? PreferredAgents = null
);

public record ChatResponse(
    string SessionId,
    string Message,
    AgentExecution[] Executions,
    TokenUsage Usage
);

public record StreamEvent(
    string Type, // thinking, agent, content, error, done
    string? Content = null,
    string? AgentId = null,
    string? Status = null,
    TokenUsage? Usage = null
);

// ==============================================================================
// DTOs - AGENT
// ==============================================================================

public record AgentInfo(
    string Id,
    string Name,
    string Description,
    string[] Capabilities,
    AgentType Type
);

public record AgentExecution(
    string AgentId,
    string Task,
    TaskStatus Status,
    string? Output,
    string? Error,
    TimeSpan Duration,
    TokenUsage Usage
);

public record AgentTask(
    string Id,
    string AgentId,
    string Description,
    string? Input,
    Dictionary<string, object>? Context = null
);

public record AgentResult(
    string TaskId,
    bool Success,
    string? Output,
    string? Error,
    TokenUsage Usage,
    Dictionary<string, object>? Metadata = null
);

// ==============================================================================
// DTOs - ORCHESTRATION
// ==============================================================================

public record TaskPlan(
    string Understanding,
    SubTask[] SubTasks
);

public record SubTask(
    string AgentId,
    string Task,
    string[]? Dependencies = null,
    int Priority = 0
);

public record ExecutionPlan(
    string RequestId,
    SubTask[] Tasks,
    bool AllowParallel,
    TimeSpan Timeout
);

public record ExecutionResult(
    string RequestId,
    bool Success,
    AgentResult[] Results,
    string? AggregatedOutput,
    TimeSpan TotalDuration,
    TokenUsage TotalUsage
);

// ==============================================================================
// DTOs - MEMORY
// ==============================================================================

public record Conversation(
    string Id,
    string? UserId,
    List<Message> Messages,
    Dictionary<string, object>? Metadata,
    DateTime CreatedAt,
    DateTime UpdatedAt
);

public record Message(
    string Id,
    MessageRole Role,
    string Content,
    string? AgentId,
    TokenUsage? Usage,
    DateTime Timestamp
);

public record ConversationSummary(
    string Id,
    string Preview,
    int MessageCount,
    DateTime CreatedAt,
    DateTime LastMessageAt
);

// ==============================================================================
// DTOs - PLUGINS
// ==============================================================================

public record SearchResults(
    string Query,
    List<SearchResult> Items,
    int TotalResults
);

public record SearchResult(
    string Title,
    string Snippet,
    string Url,
    DateTime? PublishedDate = null
);

public record DocumentResult(
    string Id,
    string Title,
    string Content,
    double Score,
    string? Source,
    Dictionary<string, object>? Metadata = null
);

// ==============================================================================
// DTOs - USAGE & METRICS
// ==============================================================================

public record TokenUsage(
    int PromptTokens,
    int CompletionTokens,
    int TotalTokens
)
{
    public static TokenUsage Zero => new(0, 0, 0);

    public static TokenUsage operator +(TokenUsage a, TokenUsage b) =>
        new(
            a.PromptTokens + b.PromptTokens,
            a.CompletionTokens + b.CompletionTokens,
            a.TotalTokens + b.TotalTokens
        );
}

public record UsageMetrics(
    string SessionId,
    DateTime Date,
    int TotalRequests,
    TokenUsage TotalUsage,
    Dictionary<string, int> AgentUsage,
    Dictionary<string, int> PluginUsage,
    decimal EstimatedCost
);

// ==============================================================================
// INTERFACES - AGENTS
// ==============================================================================

public interface IAgent
{
    string Id { get; }
    string Name { get; }
    AgentType Type { get; }
    string[] Capabilities { get; }

    Task<AgentResult> ExecuteAsync(
        AgentTask task,
        CancellationToken ct = default);
}

public interface IAgentFactory
{
    IAgent CreateAgent(AgentType type);
    IAgent CreateAgent(string agentId);
    IEnumerable<AgentInfo> GetAvailableAgents();
}

// ==============================================================================
// INTERFACES - ORCHESTRATION
// ==============================================================================

public interface IOrchestrator
{
    Task<ExecutionResult> ProcessAsync(
        string userMessage,
        Conversation? conversation = null,
        ChatOptions? options = null,
        CancellationToken ct = default);

    IAsyncEnumerable<StreamEvent> ProcessStreamAsync(
        string userMessage,
        Conversation? conversation = null,
        ChatOptions? options = null,
        CancellationToken ct = default);
}

public interface ITaskDecomposer
{
    Task<TaskPlan> DecomposeAsync(
        string userMessage,
        string? context = null,
        CancellationToken ct = default);
}

public interface IResultAggregator
{
    Task<string> AggregateAsync(
        string originalRequest,
        AgentResult[] results,
        CancellationToken ct = default);
}

// ==============================================================================
// INTERFACES - MEMORY
// ==============================================================================

public interface IConversationMemory
{
    Task<Conversation> GetOrCreateAsync(
        string? sessionId,
        CancellationToken ct = default);

    Task AddMessageAsync(
        string sessionId,
        Message message,
        CancellationToken ct = default);

    Task<IReadOnlyList<Message>> GetRecentMessagesAsync(
        string sessionId,
        int count = 10,
        CancellationToken ct = default);
}

public interface ISemanticMemory
{
    Task SaveAsync(
        string collection,
        string id,
        string text,
        Dictionary<string, object>? metadata = null,
        CancellationToken ct = default);

    Task<IReadOnlyList<DocumentResult>> SearchAsync(
        string collection,
        string query,
        int limit = 5,
        CancellationToken ct = default);
}

// ==============================================================================
// INTERFACES - PLUGINS
// ==============================================================================

public interface IWebSearchService
{
    Task<SearchResults> SearchAsync(
        string query,
        int maxResults = 5,
        CancellationToken ct = default);
}

public interface IDocumentService
{
    Task<IReadOnlyList<DocumentResult>> SearchAsync(
        string query,
        int limit = 3,
        CancellationToken ct = default);

    Task IndexAsync(
        string id,
        string title,
        string content,
        Dictionary<string, object>? metadata = null,
        CancellationToken ct = default);
}

// ==============================================================================
// INTERFACES - INFRASTRUCTURE
// ==============================================================================

public interface ILlmService
{
    Task<(string Response, TokenUsage Usage)> GenerateAsync(
        string systemPrompt,
        string userMessage,
        string? model = null,
        int? maxTokens = null,
        double? temperature = null,
        CancellationToken ct = default);

    IAsyncEnumerable<string> GenerateStreamAsync(
        string systemPrompt,
        string userMessage,
        string? model = null,
        int? maxTokens = null,
        double? temperature = null,
        CancellationToken ct = default);
}

public interface IEmbeddingService
{
    Task<float[]> GetEmbeddingAsync(
        string text,
        CancellationToken ct = default);

    Task<float[][]> GetEmbeddingsAsync(
        string[] texts,
        CancellationToken ct = default);
}

public interface IVectorStore
{
    Task UpsertAsync(
        string collection,
        string id,
        float[] embedding,
        string content,
        Dictionary<string, object>? metadata = null,
        CancellationToken ct = default);

    Task<IReadOnlyList<(string Id, string Content, double Score, Dictionary<string, object>? Metadata)>> SearchAsync(
        string collection,
        float[] queryEmbedding,
        int limit = 5,
        CancellationToken ct = default);
}

// ==============================================================================
// CONFIGURATION
// ==============================================================================

public record AzureOpenAIConfig
{
    public string Endpoint { get; init; } = string.Empty;
    public string ApiKey { get; init; } = string.Empty;
    public DeploymentConfig Deployments { get; init; } = new();
}

public record DeploymentConfig
{
    public string Chat { get; init; } = "gpt-4";
    public string ChatFast { get; init; } = "gpt-35-turbo";
    public string Embedding { get; init; } = "text-embedding-ada-002";
}

public record AgentConfig
{
    public string Model { get; init; } = "gpt-35-turbo";
    public int MaxTokens { get; init; } = 1500;
    public double Temperature { get; init; } = 0.5;
    public string SystemPrompt { get; init; } = string.Empty;
}

public record OrchestratorConfig
{
    public TimeSpan DefaultTimeout { get; init; } = TimeSpan.FromSeconds(60);
    public int MaxSubTasks { get; init; } = 5;
    public bool AllowParallelExecution { get; init; } = true;
    public int MaxRetries { get; init; } = 2;
}
