using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using Predictalytics.Application.Services;
using Predictalytics.Domain.Entities;
using Predictalytics.Domain.Enums;
using Predictalytics.Domain.Interfaces;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

namespace Predictalytics.Application.Tests.Services;

public class ScoringServiceTests
{
    [Fact]
    public async Task CalculateScoreAsync_RecentAiStrategy_DoesNotOverwriteStrategy()
    {
        // Arrange
        var traderRepoMock = new Mock<ITraderRepository>();
        var tradeRepoMock = new Mock<ITradeRepository>();

        var trader = new Trader 
        { 
            Id = 1, 
            DisplayName = "Test",
            Strategy = StrategyType.Scalper, // AI set this
            AiStrategyUpdatedAt = DateTime.UtcNow.AddDays(-2), // 2 days ago (recent)
            IsSuspectedBot = false
        };

        traderRepoMock.Setup(x => x.GetByIdAsync(1, It.IsAny<CancellationToken>()))
            .ReturnsAsync(trader);
            
        // Return some trades that look like a bot or hedger
        var trades = new List<Trade> 
        {
            new Trade { Id = 1, Amount = 15000, ExecutedAt = DateTime.UtcNow }, // Large size > 10000 => Whale heuristic
            new Trade { Id = 2, Amount = 15000, ExecutedAt = DateTime.UtcNow.AddSeconds(2) }
        };

        tradeRepoMock.Setup(x => x.GetByTraderIdAsync(1, 0, 200, It.IsAny<CancellationToken>()))
            .ReturnsAsync(trades);

        var scoringService = new ScoringService(traderRepoMock.Object, tradeRepoMock.Object, NullLogger<ScoringService>.Instance);

        // Act
        await scoringService.CalculateScoreAsync(1);

        // Assert
        // The heuristic would normally classify this as Whale because avgSize > 10000.
        // However, because AiStrategyUpdatedAt is within 7 days, it should NOT overwrite it!
        Assert.Equal(StrategyType.Scalper, trader.Strategy);
    }
    
    [Fact]
    public async Task CalculateScoreAsync_OldAiStrategy_OverwritesStrategy()
    {
        // Arrange
        var traderRepoMock = new Mock<ITraderRepository>();
        var tradeRepoMock = new Mock<ITradeRepository>();

        var trader = new Trader 
        { 
            Id = 1, 
            DisplayName = "Test",
            Strategy = StrategyType.Unknown,
            AiStrategyUpdatedAt = DateTime.UtcNow.AddDays(-10), // 10 days ago (old)
            IsSuspectedBot = false
        };

        traderRepoMock.Setup(x => x.GetByIdAsync(1, It.IsAny<CancellationToken>()))
            .ReturnsAsync(trader);
            
        var trades = new List<Trade> 
        {
            new Trade { Id = 1, Amount = 15000, ExecutedAt = DateTime.UtcNow }, // Large size > 10000 => Whale heuristic
            new Trade { Id = 2, Amount = 15000, ExecutedAt = DateTime.UtcNow.AddSeconds(2) }
        };

        tradeRepoMock.Setup(x => x.GetByTraderIdAsync(1, 0, 200, It.IsAny<CancellationToken>()))
            .ReturnsAsync(trades);

        var scoringService = new ScoringService(traderRepoMock.Object, tradeRepoMock.Object, NullLogger<ScoringService>.Instance);

        // Act
        await scoringService.CalculateScoreAsync(1);

        // Assert
        // The heuristic SHOULD overwrite this because AI data is old.
        Assert.Equal(StrategyType.Whale, trader.Strategy);
    }
}
