using Codex.Dal;
using Codex.Dal.Enums;
using Microsoft.EntityFrameworkCore;
using OpenHarbor.CQRS.Abstractions;

namespace Codex.CQRS.Queries;

/// <summary>
/// Query to get a single agent by ID
/// </summary>
public record GetAgentQuery
{
    /// <summary>
    /// ID of the agent to retrieve
    /// </summary>
    public Guid Id { get; init; }
}

/// <summary>
/// Response containing agent details
/// </summary>
public record GetAgentQueryResult
{
    public Guid Id { get; init; }
    public string Name { get; init; } = string.Empty;
    public string Description { get; init; } = string.Empty;
    public AgentType Type { get; init; }
    public string ModelProvider { get; init; } = string.Empty;
    public string ModelName { get; init; } = string.Empty;
    public ModelProviderType ProviderType { get; init; }
    public string? ModelEndpoint { get; init; }
    public double Temperature { get; init; }
    public int MaxTokens { get; init; }
    public string SystemPrompt { get; init; } = string.Empty;
    public bool EnableMemory { get; init; }
    public int ConversationWindowSize { get; init; }
    public AgentStatus Status { get; init; }
    public DateTime CreatedAt { get; init; }
    public DateTime UpdatedAt { get; init; }

    // Note: ApiKeyEncrypted is intentionally excluded from the response for security
}

/// <summary>
/// Handler for retrieving a single agent
/// </summary>
public class GetAgentQueryHandler(CodexDbContext dbContext)
    : IQueryHandler<GetAgentQuery, GetAgentQueryResult>
{
    public async Task<GetAgentQueryResult> HandleAsync(
        GetAgentQuery query,
        CancellationToken cancellationToken = default)
    {
        var agent = await dbContext.Agents
            .AsNoTracking()
            .Where(a => a.Id == query.Id && !a.IsDeleted)
            .Select(a => new GetAgentQueryResult
            {
                Id = a.Id,
                Name = a.Name,
                Description = a.Description,
                Type = a.Type,
                ModelProvider = a.ModelProvider,
                ModelName = a.ModelName,
                ProviderType = a.ProviderType,
                ModelEndpoint = a.ModelEndpoint,
                Temperature = a.Temperature,
                MaxTokens = a.MaxTokens,
                SystemPrompt = a.SystemPrompt,
                EnableMemory = a.EnableMemory,
                ConversationWindowSize = a.ConversationWindowSize,
                Status = a.Status,
                CreatedAt = a.CreatedAt,
                UpdatedAt = a.UpdatedAt
            })
            .FirstOrDefaultAsync(cancellationToken);

        if (agent == null)
        {
            throw new InvalidOperationException($"Agent with ID {query.Id} not found or has been deleted");
        }

        return agent;
    }
}
