namespace OpenWarehouse.warehouse.api.Common.Warehouse;

public class WarehouseManager(ApplicationDbContext context) : IWarehouseManager
{
    public async Task<Data.Warehouse?> GetWarehouse(string id)
    {
        var warehouse = await context.Warehouses
            .Include(warehouse1 => warehouse1.Image)
            .FirstOrDefaultAsync(warehouse1 => warehouse1.Id != null && warehouse1.Id.Equals(id));
        return warehouse;
    }

    public async Task<ActionResult> EditWarehouse(Data.Warehouse warehouse, string? newName = null,
        string? newFiestLineAdres = null, string? newSecondLineAdress = null,
        Image? image = null)
    {
        ActionResult? res = null;
        
        var error = new Dictionary<string, string>();
        
        var warehouseEntry = await context.Warehouses
            .Include(warehouse1 => warehouse.Image)
            .FirstOrDefaultAsync(warehouse1 => warehouse1 == warehouse);
        
        if (warehouseEntry == null)
        {
            error["Database"] = "Not found";
            return new ActionResult(false, error);
        }
        
        if (newName != null)
        {
            warehouseEntry.Name = newName;
        }

        if (newFiestLineAdres != null)
        {
            warehouse.FiestLineAdress = newFiestLineAdres;
        }

        if (newSecondLineAdress != null)
        {
            warehouse.SecondLineAdress = newSecondLineAdress;
        }

        if (image != null)
        {
            var imageToDel = warehouse.Image;
            warehouse.Image = image;
            if (imageToDel != null)
            {
                await context.Images.Where(image1 => image1 == imageToDel).ExecuteDeleteAsync();
            }
        }
        
        
        try
        {
            res= new ActionResult((await context.SaveChangesAsync()) > 0);
        }
        catch (OperationCanceledException e)
        {
            error[e.Source ?? "Uknow"] = e.Message;
        }
        catch (DbUpdateConcurrencyException e)
        {
            error[e.Source ?? "Uknow"] = e.Message;
        }
        catch (DbUpdateException e)
        {
            error[e.Source ?? "Uknow"] = e.Message;
        }

        if (res == null)
        {
            res = new ActionResult(false, error);
        }
        
        return res;
    }

    public async Task<ActionResult> CreateWarehouse(Data.Warehouse warehouse)
    {
        ActionResult? res = null;
        
        var error = new Dictionary<string, string>();
        
        context.Warehouses
            .Add(warehouse);
        try
        {
            res= new ActionResult((await context.SaveChangesAsync()) == 1);
        }
        catch (OperationCanceledException e)
        {
            error[e.Source ?? "Uknow"] = e.Message;
        }
        catch (DbUpdateConcurrencyException e)
        {
            error[e.Source ?? "Uknow"] = e.Message;
        }
        catch (DbUpdateException e)
        {
            error[e.Source ?? "Uknow"] = e.Message;
        }

        if (res == null)
        {
            res = new ActionResult(false, error);
        }
        
        return res;
    }

    public async Task<ActionResult> AddWarehouseClaim(Data.Warehouse warehouse, Claim claim)
    {
        ActionResult? res = null;
        var error = new Dictionary<string, string>();
        
        var claimData = new WarehouseClaims(warehouse, claim);
        context.WarehouseClaims.Add(claimData);
        try
        {
            res = new ActionResult((await context.SaveChangesAsync()) == 1);
        }
        catch (OperationCanceledException e)
        {
            error[e.Source ?? "Uknow"] = e.Message;
        }
        catch (DbUpdateConcurrencyException e)
        {
            error[e.Source ?? "Uknow"] = e.Message;
        }
        catch (DbUpdateException e)
        {
            error[e.Source ?? "Uknow"] = e.Message;
        }

        if (res == null)
        {
            res = new ActionResult(false, error);
        }

        return res;
    }

    public async Task<ActionResult> AddWarehouseClaims(Data.Warehouse warehouse, List<Claim> claims)
    {
        ActionResult? res = null;
        var error = new Dictionary<string, string>();

        foreach (var claim in claims)
        {
            var claimData = new WarehouseClaims(warehouse, claim);
            context.WarehouseClaims.Add(claimData);
        }
        
        try
        {
            res = new ActionResult((await context.SaveChangesAsync()) == 1);
        }
        catch (OperationCanceledException e)
        {
            error[e.Source ?? "Uknow"] = e.Message;
        }
        catch (DbUpdateConcurrencyException e)
        {
            error[e.Source ?? "Uknow"] = e.Message;
        }
        catch (DbUpdateException e)
        {
            error[e.Source ?? "Uknow"] = e.Message;
        }

        if (res == null)
        {
            res = new ActionResult(false, error);
        }

        return res;
        
    }

    public async Task<List<Claim>> GetWarehouseClaim(Data.Warehouse warehouse)
    {
        var claims = await context.WarehouseClaims
            .Where(warehouseClaims => warehouseClaims.Warehouse == warehouse)
            .Select(warehouseClaims => new Claim(warehouseClaims.ClaimType ?? "Uknow", warehouseClaims.ClaimValue ?? "Uknow"))
            .ToListAsync();

        return claims;
    }
}