using Nexus.Api.Services;
using Nexus.Api.Integrations;
using Nexus.Api.Data;
using Microsoft.Extensions.Configuration;
using Xunit;

namespace Nexus.Api.Tests;

public class AgentServiceTests
{
    [Fact]
    public async Task GetAgentsAsync_ReturnsCorrectCount()
    {
        var configPath = CreateAgentConfigFile();
        var config = CreateConfiguration(configPath);
        var runtime = new FakeRuntime();
        var service = new AgentService(config, runtime);

        var agents = await service.GetAgentsAsync(CancellationToken.None);
        Assert.True(agents.Count >= 4, $"Expected at least 4 agents, got {agents.Count}");
    }

    [Fact]
    public async Task GetAgentAsync_Iris_ReturnsOrchestrator()
    {
        var configPath = CreateAgentConfigFile();
        var config = CreateConfiguration(configPath);
        var runtime = new FakeRuntime();
        var service = new AgentService(config, runtime);

        var agent = await service.GetAgentAsync("iris", CancellationToken.None);
        Assert.NotNull(agent);
        Assert.Equal("Orchestrator", agent.Role);
    }

    [Fact]
    public async Task GetAgentAsync_Unknown_ReturnsNull()
    {
        var configPath = CreateAgentConfigFile();
        var config = CreateConfiguration(configPath);
        var runtime = new FakeRuntime();
        var service = new AgentService(config, runtime);

        var agent = await service.GetAgentAsync("nonexistent", CancellationToken.None);
        Assert.Null(agent);
    }

    private static IConfiguration CreateConfiguration(string configPath)
        => new ConfigurationBuilder()
            .AddInMemoryCollection(new Dictionary<string, string?>
            {
                ["AgentConfigPath"] = configPath
            })
            .Build();

    private static string CreateAgentConfigFile()
    {
        var path = Path.Combine(Path.GetTempPath(), $"agent-config-{Guid.NewGuid():N}.json");
        File.WriteAllText(path,
            """
            {
              "agents": {
                "defaults": {
                  "workspace": "/workspace/default",
                  "model": {
                    "primary": "deepseek/deepseek-v4-flash"
                  }
                },
                "list": [
                  {
                    "id": "iris",
                    "name": "iris"
                  },
                  {
                    "id": "programmer",
                    "name": "programmer"
                  },
                  {
                    "id": "reviewer",
                    "name": "reviewer"
                  },
                  {
                    "id": "architekt",
                    "name": "architekt"
                  }
                ]
              }
            }
            """);

        return path;
    }
}

public sealed class FakeRuntime : IAgentRuntime
{
    public string Name => "FakeRuntime";

    public Task<AgentRuntimeStatus> GetStatusAsync(CancellationToken cancellationToken = default)
        => Task.FromResult(new AgentRuntimeStatus(
            Runtime: "OpenClaw",
            Status: OperationalStatus.Online,
            Latency: TimeSpan.FromMilliseconds(10),
            Detail: "Fake runtime for testing"));

    public Task<AgentChatResult> ChatAsync(string message, string conversationId, string agentId, CancellationToken cancellationToken = default)
        => Task.FromResult(new AgentChatResult(
            Runtime: "OpenClaw",
            AgentId: agentId,
            ConversationId: conversationId,
            Content: "Echo: " + message));
}
