using System.Collections.Generic; using System.Linq; using Prefab.Shared.Catalog.Products; namespace Prefab.Web.Client.Models.Catalog; /// /// UI-facing projection of the catalog product detail configuration payload. /// public sealed class ProductDisplayModel { public Guid Id { get; init; } public string Slug { get; init; } = string.Empty; public string Name { get; init; } = string.Empty; public string? Description { get; init; } public decimal? BasePrice { get; init; } public string? Sku { get; init; } public IReadOnlyList Categories { get; init; } = Array.Empty(); public IReadOnlyList Options { get; init; } = Array.Empty(); public IReadOnlyList Specs { get; init; } = Array.Empty(); public IReadOnlyDictionary? GenericAttributes { get; init; } public sealed record OptionDefinition( Guid Id, string Code, string Name, int DataType, bool IsVariantAxis, string? Unit, decimal? Min, decimal? Max, decimal? Step, decimal? PricePerUnit, IReadOnlyList Tiers, IReadOnlyList Values); public sealed record OptionValue( Guid Id, string Code, string Label, decimal? PriceDelta, int PriceDeltaKind); public sealed record Tier( decimal FromInclusive, decimal? ToInclusive, decimal UnitRate, decimal? FlatDelta); public sealed record Spec( string Name, string? Value, decimal? NumericValue, string? UnitCode); public sealed record CategoryRef( Guid Id, string Name, string Slug); public static ProductDisplayModel From(GetProductDetail.ProductDetailDto product) { ArgumentNullException.ThrowIfNull(product); var options = product.Options? .Select(option => new OptionDefinition( option.Id, option.Code, option.Name, option.DataType, option.IsVariantAxis, option.Unit, option.Min, option.Max, option.Step, option.PricePerUnit, option.Tiers? .Select(tier => new Tier( tier.FromInclusive, tier.ToInclusive, tier.UnitRate, tier.FlatDelta)) .ToList() ?? new List(), option.Values? .Select(value => new OptionValue( value.Id, value.Code, value.Label, value.PriceDelta, value.PriceDeltaKind)) .ToList() ?? new List())) .ToList() ?? new List(); var specs = product.Specs? .Select(spec => new Spec( spec.Name, spec.Value, spec.NumericValue, spec.UnitCode)) .ToList() ?? new List(); var categories = product.Categories? .Select(category => new CategoryRef( category.Id, category.Name, category.Slug)) .ToList() ?? new List(); return new ProductDisplayModel { Id = product.Id, Slug = product.Slug, Name = product.Name, Description = product.Description, BasePrice = product.Price, Sku = product.Sku, Categories = categories, Options = options, Specs = specs, GenericAttributes = product.GenericAttributes }; } }