using System.Collections.Generic;
using System.Linq;
using PolyTrader.Modules.CopyTrading.Persistence.Ef;
using PolyTrader.Tests.TestSupport;
using PolyTraderSharp.Models;
using Xunit;

namespace PolyTrader.Tests
{
    public class TrackedTraderRepositoryTests
    {
        private static EfTrackedTraderRepository NewRepo() =>
            new(new InMemoryContextFactory<CopyTradingDbContext>(o => new CopyTradingDbContext(o)));

        [Fact]
        public void Upsert_inserts_new_trader()
        {
            var repo = NewRepo();
            repo.Upsert(new TrackedTrader { Id = 1, DisplayName = "Alice" });

            var all = repo.GetAll();
            Assert.Single(all);
            Assert.Equal("Alice", all[0].DisplayName);
        }

        [Fact]
        public void Upsert_updates_existing_without_duplicating()
        {
            var repo = NewRepo();
            repo.Upsert(new TrackedTrader { Id = 1, DisplayName = "Alice", IsActive = true });
            repo.Upsert(new TrackedTrader { Id = 1, DisplayName = "Bob", IsActive = false });

            var all = repo.GetAll();
            Assert.Single(all);
            Assert.Equal("Bob", all[0].DisplayName);
            Assert.False(all[0].IsActive);
        }

        [Fact]
        public void AssignedAccountIds_round_trips_through_json_conversion()
        {
            var repo = NewRepo();
            repo.Upsert(new TrackedTrader { Id = 7, DisplayName = "X", AssignedAccountIds = new HashSet<int> { 1, 3 } });

            var loaded = repo.GetAll().Single();
            Assert.Equal(new HashSet<int> { 1, 3 }, loaded.AssignedAccountIds);
        }

        [Fact]
        public void AssignedAccountIds_update_replaces_the_set()
        {
            var repo = NewRepo();
            repo.Upsert(new TrackedTrader { Id = 7, AssignedAccountIds = new HashSet<int> { 1, 3 } });
            repo.Upsert(new TrackedTrader { Id = 7, AssignedAccountIds = new HashSet<int> { 2 } });

            var loaded = repo.GetAll().Single();
            Assert.Equal(new HashSet<int> { 2 }, loaded.AssignedAccountIds);
        }

        [Fact]
        public void Delete_removes_the_trader()
        {
            var repo = NewRepo();
            repo.Upsert(new TrackedTrader { Id = 1 });
            repo.Upsert(new TrackedTrader { Id = 2 });

            repo.Delete(1);

            var all = repo.GetAll();
            Assert.Single(all);
            Assert.Equal(2, all[0].Id);
        }
    }
}
