using AyCode.Core.Enums;
using AyCode.Core.Tests.TestModels;
using AyCode.Services.Server.SignalRs;
using AyCode.Services.SignalRs;

namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;

public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
    #region LoadItem Tests

    [TestMethod]
    public virtual async Task LoadItem_ReturnsSingleItem()
    {
        var dataSource = CreateDataSource(_client, _crudTags);
        var result = await dataSource.LoadItem(2);

        Assert.IsNotNull(result);
        Assert.AreEqual(2, result.Id);
        Assert.AreEqual("Product B", result.ProductName);
    }

    [TestMethod]
    public virtual async Task LoadItem_AddsToDataSource_WhenNotExists()
    {
        var dataSource = CreateDataSource(_client, _crudTags);
        Assert.AreEqual(0, dataSource.Count);

        await dataSource.LoadItem(1);

        Assert.AreEqual(1, dataSource.Count);
        Assert.AreEqual("Product A", dataSource[0].ProductName);
    }

    [TestMethod]
    public virtual async Task LoadItem_UpdatesExisting_WhenAlreadyLoaded()
    {
        var dataSource = CreateDataSource(_client, _crudTags);
        await dataSource.LoadDataSource();

        var originalItem = dataSource[0];
        var reloaded = await dataSource.LoadItem(originalItem.Id);

        Assert.AreEqual(3, dataSource.Count);
        Assert.IsNotNull(reloaded);
    }

    [TestMethod]
    public virtual async Task LoadItem_InvokesOnDataSourceItemChanged()
    {
        var dataSource = CreateDataSource(_client, _crudTags);

        ItemChangedEventArgs<TestOrderItem_All_True>? eventArgs = null;

        dataSource.OnDataSourceItemChanged = args => { eventArgs = args; return Task.CompletedTask; };
        await dataSource.LoadItem(1);

        Assert.IsNotNull(eventArgs);
        Assert.AreEqual(TrackingState.Get, eventArgs.TrackingState);
        Assert.AreEqual(1, eventArgs.Item.Id);
    }

    [TestMethod]
    public virtual async Task LoadItem_ReturnsNull_WhenNotFound()
    {
        var dataSource = CreateDataSource(_client, _crudTags);
        var result = await dataSource.LoadItem(9999);

        Assert.IsNull(result);
    }

    #endregion
}
