using Dapper;
using WretchedMachines.DataAccess.Entities;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Npgsql;

namespace WretchedMachines.DataAccess;

public class DataAccess: IDataAccess, IDisposable
{
    private readonly NpgsqlConnection connection;
    private readonly IMemoryCache cache;
    private bool disposedValue;


    public DataAccess(IConfiguration configuration, IMemoryCache cache)
    {
        var connectionString = configuration.GetConnectionString("Default");
        this.cache = cache;
        connection = new NpgsqlConnection(connectionString);
        connection.Open();
    }

    public User? GetUser(int id)
    {
        return GetFromCache<User>("select * from dbo.\"users\"")?.FirstOrDefault();
    }

    protected virtual void Dispose(bool disposing)
    {
        if(!disposedValue){
            if(disposing){
                connection?.Dispose();
            }
            disposedValue = true;
        }
    }

    public void Dispose()
    {
        Dispose(disposing: true);
        GC.SuppressFinalize(true);
    }

    private IEnumerable<T> GetFromDb<T>(string sql)
    {
        // TODO(Eero): Add params.
        return connection.Query<T>(sql);
    }

    private IEnumerable<T>? GetFromCache<T>(string sql)
    {
        var cacheKey = typeof(T).Name;
        IEnumerable<T>? entities = null;
        if(cache.TryGetValue(cacheKey, out entities))
        {
            return entities;
        }

        entities = GetFromDb<T>(sql);
        cache.Set(cacheKey, entities);
        return entities;
    }

    public IEnumerable<Item>? GetItems()
    {
        return GetFromCache<Item>("SELECT * FROM public.\"Items\";");
    }
}
