using DbFirst.Application.Repositories;
using DbFirst.Domain.Entities;
using Microsoft.EntityFrameworkCore;

namespace DbFirst.Infrastructure.Repositories;

public class LayoutRepository : ILayoutRepository
{
    private readonly ApplicationDbContext _db;

    public LayoutRepository(ApplicationDbContext db)
    {
        _db = db;
    }

    public async Task<SmfLayout?> GetAsync(string layoutType, string layoutKey, string userName, CancellationToken cancellationToken = default)
    {
        return await _db.SmfLayouts.AsNoTracking()
            .FirstOrDefaultAsync(x => x.LayoutType == layoutType && x.LayoutKey == layoutKey && x.UserName == userName, cancellationToken);
    }

    public async Task<SmfLayout> UpsertAsync(string layoutType, string layoutKey, string userName, byte[] layoutData, CancellationToken cancellationToken = default)
    {
        var entity = await _db.SmfLayouts
            .FirstOrDefaultAsync(x => x.LayoutType == layoutType && x.LayoutKey == layoutKey && x.UserName == userName, cancellationToken);

        if (entity == null)
        {
            entity = new SmfLayout
            {
                Active = true,
                LayoutType = layoutType,
                LayoutKey = layoutKey,
                UserName = userName,
                LayoutData = layoutData,
                AddedWho = userName,
                AddedWhen = DateTime.UtcNow
            };
            _db.SmfLayouts.Add(entity);
        }
        else
        {
            entity.Active = true;
            entity.LayoutData = layoutData;
            entity.ChangedWho = userName;
        }

        await _db.SaveChangesAsync(cancellationToken);
        return entity;
    }

    public async Task<bool> DeleteAsync(string layoutType, string layoutKey, string userName, CancellationToken cancellationToken = default)
    {
        var entity = await _db.SmfLayouts
            .FirstOrDefaultAsync(x => x.LayoutType == layoutType && x.LayoutKey == layoutKey && x.UserName == userName, cancellationToken);

        if (entity == null)
        {
            return false;
        }

        _db.SmfLayouts.Remove(entity);
        await _db.SaveChangesAsync(cancellationToken);
        return true;
    }
}
