using System.Data;
using OpenWarehouse.warehouse.api.Common.Warehouse;

namespace OpenWarehouse.warehouse.api.Common.Inventory;

public class InventoryManger(ILogger<InventoryManger> logger,
    ApplicationDbContext context, IWarehouseManager warehouseManager,
    IItemManager itemManager) : IInventoryManger
{
    public async Task<List<ItemInWarehouse>> GetListOfItemInWarehouse(Data.Item item)
    {
        return await context.ItemInWarehouses
            .Where(q => q.Item == item)
            .ToListAsync();
    }

    public async Task<ItemInWarehouse?> GetPositionById(string id)
    {
        return await context.ItemInWarehouses
            .Where(q => q.Id == Guid.Parse(id))
            .FirstOrDefaultAsync();
    }

    public async Task<List<ItemInWarehouse>> GetPositionByPosition(string position)
    {
        return await context.ItemInWarehouses
            .Where(q => q.Positions == position)
            .ToListAsync();
    }

    public async Task<bool> CreateAsync(ItemInWarehouse itemInWarehouse)
    {
        context.ItemInWarehouses.Add(itemInWarehouse);

        var res = await context.SaveChangesAsync();

        return res > 0;
    }

    public async Task<bool> AddClaims(ItemInWarehouse itemInWarehouse, List<Claim> claims)
    {
        foreach (Claim claim in claims)
        {
            if (itemInWarehouse.ItemInWarehouseClaims.Any(q => q.ClaimType == claim.Type))
            {
                var itemInWarehouseClaims = itemInWarehouse.ItemInWarehouseClaims
                    .FirstOrDefault(warehouseClaims => warehouseClaims.ClaimType == claim.Type);
                if (itemInWarehouseClaims == null) return false;
                itemInWarehouseClaims.ClaimValue = claim.Value;
            }
            else
            {
                itemInWarehouse.ItemInWarehouseClaims.Add(new ItemInWarehouseClaims(){ClaimType = claim.Type, ClaimValue = claim.Value});
            }
        }

        var res = await context.SaveChangesAsync();
        
        return res == claims.Count;
    }

    public async Task<bool> AddClaim(ItemInWarehouse itemInWarehouse, Claim claim)
    {
        if (itemInWarehouse.ItemInWarehouseClaims.Any(q => q.ClaimType == claim.Type))
        {
            var itemInWarehouseClaims = itemInWarehouse.ItemInWarehouseClaims
                .FirstOrDefault(warehouseClaims => warehouseClaims.ClaimType == claim.Type);
            if (itemInWarehouseClaims == null) return false;
            itemInWarehouseClaims.ClaimValue = claim.Value;
        }
        else
        {
            itemInWarehouse.ItemInWarehouseClaims.Add(new ItemInWarehouseClaims(){ClaimType = claim.Type, ClaimValue = claim.Value});
        }

        var res = await context.SaveChangesAsync();
        return res > 0;
    }

    public async Task<bool> DeleteClaim(ItemInWarehouse itemInWarehouse, string claimType)
    {
        var res = await context.ItemInWarehousesClaims
            .Where(q => q.ClaimType == claimType && q.Item == itemInWarehouse)
            .ExecuteDeleteAsync();
        if (res > 1) throw new DataException("Deleted more than one record!!");
        return res == 1;
    }
}