using BuildingBlock.Catalog.Contracts.Conventions;
using BuildingBlock.Catalog.Contracts.Products;
using BuildingBlock.Catalog.Contracts.Responses;
using BuildingBlock.Inventory.Contracts.Conventions;
using BuildingBlock.Inventory.Contracts.Requests;
using BuildingBlock.Inventory.Contracts.Responses;
using Furniture.Domain.Contracts;

namespace Furniture.Domain.Decisions;

/// <summary>
/// Default domain implementation for furniture availability composition decisions.
/// </summary>
public sealed class FurnitureAvailabilityDecisionService : IFurnitureAvailabilityDecisionService
{
    private const string ContractVersion = "1.0.0";

    /// <inheritdoc />
    public InventoryItemLookupRequest BuildInventoryRequest(FurnitureAvailabilityDecisionRequest request)
    {
        return new InventoryItemLookupRequest(
            new InventoryContractEnvelope(ContractVersion, ResolveCorrelationId(request.CorrelationId)),
            request.FurnitureId);
    }

    /// <inheritdoc />
    public ProductContract BuildCatalogRequest(FurnitureAvailabilityDecisionRequest request)
    {
        return new ProductContract(
            new CatalogContractEnvelope(ContractVersion, ResolveCorrelationId(request.CorrelationId)),
            request.FurnitureId,
            string.Empty);
    }

    /// <inheritdoc />
    public FurnitureAvailabilityDecisionResponse ComposeResponse(
        FurnitureAvailabilityDecisionRequest request,
        ProductContractResponse catalogResponse,
        InventoryItemLookupResponse inventoryResponse)
    {
        return new FurnitureAvailabilityDecisionResponse(
            request.FurnitureId,
            catalogResponse.DisplayName,
            inventoryResponse.QuantityAvailable);
    }

    private static string ResolveCorrelationId(string correlationId)
    {
        if (!string.IsNullOrWhiteSpace(correlationId))
        {
            return correlationId;
        }

        return $"corr-{Guid.NewGuid():N}";
    }
}
