using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Xunit;

namespace Homework.Tests
{
    public class FakeLogger : Logger.ILogger
    {
        public readonly List<(Logger.LogLevel level, string message)> Messages = new();

        public void Trace(string message) => Log(Logger.LogLevel.Trace, message);
        public void Debug(string message) => Log(Logger.LogLevel.Debug, message);
        public void Info(string message) => Log(Logger.LogLevel.Info, message);
        public void Warning(string message) => Log(Logger.LogLevel.Warning, message);
        public void Error(string message) => Log(Logger.LogLevel.Error, message);
        public void Fatal(string message) => Log(Logger.LogLevel.Fatal, message);

        public void Log(Logger.LogLevel level, string message)
        {
            Messages.Add((level, message));
        }
    }

    public class AuthControllerTests
    {
        [Fact]
        public void Login_ReturnsOkWithToken()
        {
            var logger = new FakeLogger();
            var jwtOptions = Options.Create(new JwtSettings
            {
                Key = "test-secret-key-very-long-and-secure",
                Issuer = "homework",
                Audience = "homework",
                ExpireMinutes = 60
            });

            var jwtService = new JwtService(jwtOptions);
            var controller = new AuthController(jwtService, logger);

            var request = new LoginRequest
            {
                Email = "user@example.com",
                Password = "password123"
            };

            var result = controller.Login(request);

            Assert.IsType<OkObjectResult>(result);

            var okResult = (OkObjectResult)result;
            Assert.NotNull(okResult.Value);

            var tokenProperty = okResult.Value.GetType().GetProperty("token");
            Assert.NotNull(tokenProperty);

            var tokenValue = tokenProperty.GetValue(okResult.Value) as string;
            Assert.False(string.IsNullOrWhiteSpace(tokenValue));
            Assert.Contains("ey", tokenValue); // JWT tokens start with ey

            Assert.Contains(logger.Messages, x => x.level == Logger.LogLevel.Info && x.message.Contains("Login attempt"));
            Assert.Contains(logger.Messages, x => x.level == Logger.LogLevel.Info && x.message.Contains("successfully logged in"));
        }
    }
}
