using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Xunit;
using CncCollector.Core;
using CncCollector.Api;
using CncCollector.Config;

namespace CncCollector.Tests
{
    /// <summary>
    /// CollectorApiServer 单元测试。
    /// 使用无效DB配置创建引擎和API服务器，通过HTTP客户端验证认证和路由行为。
    /// </summary>
    public class CollectorApiServerTests : IDisposable
    {
        private readonly CollectorEngine _engine;
        private readonly CollectorApiServer _server;
        private readonly HttpClient _client;
        private readonly int _port;
        private readonly string _apiKey = "test_api_key_123";

        public CollectorApiServerTests()
        {
            // 使用随机端口避免冲突
            _port = 15800 + new Random().Next(0, 1000);
            var config = new CollectorConfig
            {
                BusinessConnection = "Server=invalid;Database=invalid;User Id=invalid;Password=invalid;",
                LogConnection = "Server=invalid;Database=invalid;User Id=invalid;Password=invalid;",
                ApiPort = _port
            };
            _engine = new CollectorEngine(config);
            _server = new CollectorApiServer(_engine, _apiKey, _port);
            _server.Start();

            _client = new HttpClient { Timeout = TimeSpan.FromSeconds(5) };
        }

        public void Dispose()
        {
            _server?.Stop();
            _client?.Dispose();
        }

        // ===== 认证测试 =====

        [Fact]
        public async Task Status_无APIKey_返回401()
        {
            var resp = await _client.GetAsync($"http://localhost:{_port}/api/collector/status");
            Assert.Equal(HttpStatusCode.Unauthorized, resp.StatusCode);
        }

        [Fact]
        public async Task Status_错误APIKey_返回401()
        {
            var request = new HttpRequestMessage(HttpMethod.Get, $"http://localhost:{_port}/api/collector/status");
            request.Headers.Add("X-Api-Key", "wrong_key");
            var resp = await _client.SendAsync(request);
            Assert.Equal(HttpStatusCode.Unauthorized, resp.StatusCode);
        }

        [Fact]
        public async Task Status_正确APIKey_返回200()
        {
            var request = new HttpRequestMessage(HttpMethod.Get, $"http://localhost:{_port}/api/collector/status");
            request.Headers.Add("X-Api-Key", _apiKey);
            var resp = await _client.SendAsync(request);
            Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
        }

        // ===== 响应格式测试 =====

        [Fact]
        public async Task Status_响应体为标准JSON格式()
        {
            var request = new HttpRequestMessage(HttpMethod.Get, $"http://localhost:{_port}/api/collector/status");
            request.Headers.Add("X-Api-Key", _apiKey);
            var resp = await _client.SendAsync(request);
            var body = await resp.Content.ReadAsStringAsync();
            var json = JsonConvert.DeserializeObject<Dictionary<string, object>>(body);

            Assert.NotNull(json);
            Assert.True(json.ContainsKey("code"));
            Assert.True(json.ContainsKey("message"));
            Assert.True(json.ContainsKey("data"));
        }

        [Fact]
        public async Task Status_响应data包含预期字段()
        {
            var request = new HttpRequestMessage(HttpMethod.Get, $"http://localhost:{_port}/api/collector/status");
            request.Headers.Add("X-Api-Key", _apiKey);
            var resp = await _client.SendAsync(request);
            var body = await resp.Content.ReadAsStringAsync();
            dynamic json = JsonConvert.DeserializeObject(body);

            Assert.Equal(0, (int)json.code);
            Assert.NotNull(json.data);
            Assert.NotNull(json.data.isRunning);
            Assert.NotNull(json.data.workerCount);
            Assert.NotNull(json.data.workers);
        }

        // ===== 路由测试 =====

        [Fact]
        public async Task UnknownEndpoint_返回404()
        {
            var request = new HttpRequestMessage(HttpMethod.Get, $"http://localhost:{_port}/api/collector/nonexistent");
            request.Headers.Add("X-Api-Key", _apiKey);
            var resp = await _client.SendAsync(request);
            Assert.Equal(HttpStatusCode.NotFound, resp.StatusCode);
        }

        [Fact]
        public async Task Refresh_正确APIKey_返回200()
        {
            var request = new HttpRequestMessage(HttpMethod.Post, $"http://localhost:{_port}/api/collector/refresh");
            request.Headers.Add("X-Api-Key", _apiKey);
            var resp = await _client.SendAsync(request);
            Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
        }

        [Fact]
        public async Task Stop_正确APIKey_返回200()
        {
            var request = new HttpRequestMessage(HttpMethod.Post, $"http://localhost:{_port}/api/collector/stop");
            request.Headers.Add("X-Api-Key", _apiKey);
            var resp = await _client.SendAsync(request);
            Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
        }

        [Fact]
        public async Task Start_正确APIKey_返回200()
        {
            var request = new HttpRequestMessage(HttpMethod.Post, $"http://localhost:{_port}/api/collector/start");
            request.Headers.Add("X-Api-Key", _apiKey);
            var resp = await _client.SendAsync(request);
            Assert.Equal(HttpStatusCode.OK, resp.StatusCode);
        }

        // ===== 启停控制测试 =====

        [Fact]
        public async Task 启停顺序_状态正确切换()
        {
            // 停止
            var stopReq = new HttpRequestMessage(HttpMethod.Post, $"http://localhost:{_port}/api/collector/stop");
            stopReq.Headers.Add("X-Api-Key", _apiKey);
            await _client.SendAsync(stopReq);

            // 检查状态为停止
            var statusReq = new HttpRequestMessage(HttpMethod.Get, $"http://localhost:{_port}/api/collector/status");
            statusReq.Headers.Add("X-Api-Key", _apiKey);
            var statusResp = await _client.SendAsync(statusReq);
            var body = await statusResp.Content.ReadAsStringAsync();
            dynamic json = JsonConvert.DeserializeObject(body);
            Assert.False((bool)json.data.isRunning);

            // 启动
            var startReq = new HttpRequestMessage(HttpMethod.Post, $"http://localhost:{_port}/api/collector/start");
            startReq.Headers.Add("X-Api-Key", _apiKey);
            await _client.SendAsync(startReq);

            // 检查状态为运行
            statusReq = new HttpRequestMessage(HttpMethod.Get, $"http://localhost:{_port}/api/collector/status");
            statusReq.Headers.Add("X-Api-Key", _apiKey);
            statusResp = await _client.SendAsync(statusReq);
            body = await statusResp.Content.ReadAsStringAsync();
            json = JsonConvert.DeserializeObject(body);
            Assert.True((bool)json.data.isRunning);
        }
    }
}
