using System.Collections.Concurrent;
using AyCode.Core.Extensions;
using AyCode.Interfaces.Entities;

namespace FruitBank.Common.Databases;

public abstract class DatabaseLocalBase
{
    //private ObservableCollection<IEntityInt> a = new ObservableCollection<IEntityInt>();
    private readonly ConcurrentDictionary<Type, object> _database = new();

    protected void AddTable<TEntity>(IList<TEntity> table)where TEntity: class, IEntityInt
    {
        if (GetTableObject<TEntity>() == null)
        {
            if (!_database.TryAdd(typeof(TEntity), table))
                return;
        }

        return;
    }

    protected IList<T>? GetTableObject<T>() where T : class, IEntityInt
    {
        return _database.GetValueOrDefault(typeof(T)) as IList<T>;
    }

    public IEnumerable<T>? GetRows<T>() where T : class, IEntityInt
    {
        return GetTableObject<T>();
    }

    public T? GetRow<T>(int id) where T : class, IEntityInt
    {
        return GetTableObject<T>()?.FirstOrDefault(x => x.Id == id) as T;
    }

    public T AddRow<T>(T entity) where T : class, IEntityInt
        => AddRow(GetTableObject<T>()!, entity);

    protected T AddRow<T>(in IList<T> table, T entity) where T : class, IEntityInt
    {
        table.Add(entity);
        return entity;
    }

    public void AddRows<T>(IEnumerable<T> entities) where T : class, IEntityInt
    {
        var table = GetTableObject<T>()!;

        foreach (var entity in entities)
        {
            AddRow(table, entity);
        }
    }

    public T? DeleteRow<T>(int id) where T : class, IEntityInt
    {
        var table = GetTableObject<T>();
        if (table == null) return null;

        var index = table.FindIndex(x => x.Id == id);
        if (index < 0) return null;

        var entity = table[index];
        table.RemoveAt(index);

        return entity as T;
    }
}