@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel>
@using System.Collections.Generic
@using System.Linq
@using Dynamicweb.Ecommerce.ProductCatalog
@using Dynamicweb.Ecommerce.Variants
@using Dynamicweb.Frontend

@functions {
	//Find contrast color (white, black)
	public static string GetContrastColor(string hexString)
	{
		System.Drawing.Color bg = System.Drawing.ColorTranslator.FromHtml(hexString);

		int nThreshold = 105;
		int bgDelta = Convert.ToInt32((bg.R * 0.299) + (bg.G * 0.587) +
									(bg.B * 0.114));

		string foreColor = (255 - bgDelta < nThreshold) ? "#333" : "#fff";
		return foreColor;
	}

	public string GetLayoutForVariantGroup(string variantGroupId)
	{
		string showVariantGroups = Model.Item?.GetRawValueString("ShowVariantGroupOptions");
		var selectedVariantGroupsList = Model.Item?.GetItems("VariantGroups") ?? new List<ItemViewModel>();
		bool showAllVariantGroupsDefault = string.IsNullOrEmpty(showVariantGroups) || selectedVariantGroupsList == null || !selectedVariantGroupsList.Any();
		string defaultVariantGroupLayout = Model.Item?.GetRawValueString("DefaultVariantGroupLayout");
		defaultVariantGroupLayout = !string.IsNullOrEmpty(defaultVariantGroupLayout) ? defaultVariantGroupLayout : "button";

		if (showAllVariantGroupsDefault) return defaultVariantGroupLayout;
		
		foreach (var selectedVariantGroupListItem in selectedVariantGroupsList)
		{
			var variantGroups = selectedVariantGroupListItem.GetList("VariantGroups").GetRawValue().OfType<string>().ToList();
			if (variantGroups.Any(s => s.Equals(variantGroupId))) return selectedVariantGroupListItem.GetRawValueString("VariantGroupLayout");
		}

		return defaultVariantGroupLayout;
	}

	//Collect all variant images
	public static Dictionary<string, string> GetVariantImages(List<VariantInfoViewModel> variantInfo, Dictionary<string, string> list)
	{
		foreach (var variantGroup in variantInfo)
		{
			if (variantGroup.Image?.Value != null && !list.ContainsKey(variantGroup.OptionID))
			{
				list.Add(variantGroup.OptionID, variantGroup.Image.Value);
			}

			if (variantGroup.VariantInfo != null)
			{
				GetVariantImages(variantGroup.VariantInfo, list);
			}
		}

		return list;
	}

	private string GetDefaultOrVariantGroupValue(string variantGroupId, string itemField, string itemFieldDefaultValue, Dictionary<string, string> fieldValueMapping)
	{
		if (!string.IsNullOrEmpty(variantGroupId)) {
			string itemFieldValue = Model.Item?.GetRawValueString(itemField, itemFieldDefaultValue);
			string itemFieldParameter = GetViewParameterString(itemField);
			itemFieldValue = string.IsNullOrEmpty(itemFieldValue) && !string.IsNullOrEmpty(itemFieldParameter) ? itemFieldParameter : itemFieldValue;

			if (fieldValueMapping != null && !string.IsNullOrEmpty(itemFieldValue) && fieldValueMapping.Any()) {
				itemFieldValue = fieldValueMapping.ContainsKey(itemFieldValue) ? fieldValueMapping[itemFieldValue] : itemFieldValue;
			}

			// If no variantGroup (i.e. Visual Editor), return default value
			if (string.IsNullOrEmpty(variantGroupId)) return itemFieldValue;

			string showVariantGroups = Model.Item?.GetString("ShowVariantGroupOptions", "all");
			var selectedVariantGroupsList = Model.Item?.GetItems("VariantGroups") ?? new List<ItemViewModel>();
			// If no exceptions or settings are all the same, return default value
			if (showVariantGroups == "all" || selectedVariantGroupsList == null || !selectedVariantGroupsList.Any()) return itemFieldValue;

			// Get specific value for variant group
			foreach (var selectedVariantGroupListItem in selectedVariantGroupsList)
			{
				var variantGroups = selectedVariantGroupListItem.GetList("VariantGroups").GetRawValue().OfType<string>().ToList();
				if (!variantGroups.Any(s => s.Equals(variantGroupId))) continue;

				itemFieldValue = selectedVariantGroupListItem.GetRawValueString(itemField, itemFieldDefaultValue);
				itemFieldValue = fieldValueMapping.ContainsKey(itemFieldValue) ? fieldValueMapping[itemFieldValue] : itemFieldValue;
			}

			return itemFieldValue;
		}
		else
		{
			return string.Empty;
		}
	}

	private bool GetDefaultOrVariantGroupValue(string variantGroupId, string itemField)
	{
		if (!string.IsNullOrEmpty(variantGroupId)) {
			bool itemFieldValue = Model.Item?.GetBoolean(itemField) ?? false;

			// If no variantGroup (i.e. Visual Editor), return default value
			if (string.IsNullOrEmpty(variantGroupId)) return itemFieldValue;

			string showVariantGroups = Model.Item?.GetString("ShowVariantGroupOptions", "all");
			var selectedVariantGroupsList = Model.Item?.GetItems("VariantGroups") ?? new List<ItemViewModel>();
			// If no exceptions or settings are all the same, return default value
			if (showVariantGroups == "all" || selectedVariantGroupsList == null || !selectedVariantGroupsList.Any()) return itemFieldValue;

			// Get specific value for variant group
			foreach (var selectedVariantGroupListItem in selectedVariantGroupsList)
			{
				var variantGroups = selectedVariantGroupListItem.GetList("VariantGroups").GetRawValue().OfType<string>().ToList();
				if (!variantGroups.Any(s => s.Equals(variantGroupId))) continue;

				itemFieldValue = selectedVariantGroupListItem.GetBoolean(itemField);
			}

			return itemFieldValue;
		}
		else
		{
			return false;
		}
	}
		}

@{
	ProductViewModel product = null;
	if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
	{
		product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"];
	}
}

@if ((product is object))
{
		bool hideGroupHeaders = !string.IsNullOrEmpty(Model?.Item?.GetString("HideGroupHeaders")) ? Model.Item.GetBoolean("HideGroupHeaders") : false;
		var productVariantGroups = product.VariantGroups();

		string itemId = Model?.Item?.SystemName != null ? $"item_{Model.Item.SystemName.ToLower()}" : string.Empty;

		bool isModalSelector = Model?.Item == null;
		string target = isModalSelector ? "data-response-target-element=\"DynamicModalContent\"" : string.Empty;

		string variantSelectorServicePageId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("VariantSelectorServicePage")) ? Dynamicweb.Context.Current.Request.Form.Get("VariantSelectorServicePage") : string.Empty;
		string formAction = isModalSelector ? $"action=\"/Default.aspx?ID={variantSelectorServicePageId}\"" : string.Empty;

		string getProductInfo = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["getproductinfo"]) ? Dynamicweb.Context.Current.Request.Form["getproductinfo"] : string.Empty;

		if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null)
		{
			string[] variantId = product.VariantId.Split('.');
			int groupNumber = 1;

			string baseUrl = $"/Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}";
			string variantUrl = string.Empty;
			if (!string.IsNullOrEmpty(product.VariantId) && !isModalSelector)
			{
				variantUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl($"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}&VariantID={product.VariantId}");
			}

			Dictionary<string, string> variantImages = new Dictionary<string, string>();
			variantImages = GetVariantImages(product.VariantInfo.VariantInfo, variantImages);

		<form @formAction class="d-flex flex-column gap-2 js-variant-selector @itemId" @target data-combinations="@string.Join(",", product.VariantCombinations())" data-base-url="@baseUrl" data-friendly-url="@variantUrl">
			@if (isModalSelector)
			{
				<input type="hidden" name="productId" value="@product.Id">
				<input type="hidden" name="variantid" value="@product.VariantId">
				<input type="hidden" name="QuantitySelector" value="true">
				<input type="hidden" name="VariantSelectorServicePage" value="@variantSelectorServicePageId">
				<input type="hidden" name="ViewType" value="ModalContent">

				if (GetViewParameter("ButtonLayout") != null) {
					<input type="hidden" name="ButtonLayout" value="@GetViewParameter("ButtonLayout")">
				}

		if (GetViewParameter("ButtonAspectRatio") != null) {
					<input type="hidden" name="ButtonAspectRatio" value="@GetViewParameter("ButtonAspectRatio")">
				}

		if (!string.IsNullOrEmpty(getProductInfo))
		{
					<input type="hidden" name="getproductinfo" value="@getProductInfo">
				}
	}

	@foreach (var variantGroup in productVariantGroups)
			{
		VariantGroupViewModel group = variantGroup;
		string variantGroupLayout = GetLayoutForVariantGroup(variantGroup.Id) ?? "button";
		string horizontalAlign = GetDefaultOrVariantGroupValue(variantGroup.Id, "HorizontalAlignment", "", new Dictionary<string, string> { { "center", "justify-content-center" }, { "end", "justify-content-end" } });
		string horizontalTextAlign = GetDefaultOrVariantGroupValue(variantGroup.Id, "HorizontalAlignment", "", new Dictionary<string, string> { { "center", "text-center" }, { "end", "text-end" } });
		bool showSelectedOptionName = GetDefaultOrVariantGroupValue(variantGroup.Id, "ShowSelectedOptionName");

				<div>
					@if (!hideGroupHeaders)
					{
						<h3 class="h6 @horizontalTextAlign">
							@group.Name

							@if (showSelectedOptionName)
							{
		string selectedOptionName = group.Options.FirstOrDefault(opt => variantId.Contains(opt.Id))?.Name ?? string.Empty;
								<span class="fw-light px-1 swift-selected-option-name">@selectedOptionName</span>
							}
						</h3>
					}
					<div class="d-flex gap-2 @horizontalAlign flex-wrap js-variant-group" data-group-id="@groupNumber">
						@if (variantGroupLayout == "button")
						{
		foreach (var option in group.Options)
		{
			string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty;
			string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}";
			string contrastColor = string.Empty;
			string buttonAspectRatio = GetDefaultOrVariantGroupValue(variantGroup.Id, "ButtonAspectRatio", "100%", new Dictionary<string, string> { { "100%", "--bs-aspect-ratio:100%" }, { "56%", "--bs-aspect-ratio:56%" }, { "177%", "--bs-aspect-ratio:177%" }, { "75%", "--bs-aspect-ratio:75%" }, { "133%", "--bs-aspect-ratio:133%" } });
			buttonAspectRatio = buttonAspectRatio == string.Empty ? "--bs-aspect-ratio:100%" : buttonAspectRatio;

			string buttonLayout = GetDefaultOrVariantGroupValue(variantGroup.Id, "ButtonLayout", "rounded-circle", new Dictionary<string, string> { { "round", "rounded-circle" }, { "square", "rounded-0" }, { "square-rounded", "rounded-3" } });

			var displayType = group.DisplayType;
			displayType = displayType == VariantGroupDisplayType.NothingSelected && !string.IsNullOrEmpty(option.Color) ? VariantGroupDisplayType.VariantColor : displayType;
			displayType = displayType == VariantGroupDisplayType.NothingSelected && string.IsNullOrEmpty(option.OptionImage.Value) && string.IsNullOrEmpty(option.Color) ? VariantGroupDisplayType.VariantName : displayType;
			displayType = displayType == VariantGroupDisplayType.NothingSelected && !string.IsNullOrEmpty(option.OptionImage.Value) ? VariantGroupDisplayType.VariantOptionImage : displayType;

			var btnWidth = displayType == VariantGroupDisplayType.VariantColor || displayType == VariantGroupDisplayType.VariantImage || displayType == VariantGroupDisplayType.VariantOptionImage ? $"style=\"width:64px\"" : string.Empty;
			var btnClasses = string.Empty;

			btnClasses = displayType == VariantGroupDisplayType.VariantColor ? $"overflow-hidden colorbox colorbox-auto p-0 border {buttonLayout}" : btnClasses;
			btnClasses = displayType == VariantGroupDisplayType.VariantImage ? $"overflow-hidden p-0 {buttonLayout}" : btnClasses;
			btnClasses = displayType == VariantGroupDisplayType.VariantOptionImage ? $"overflow-hidden colorbox colorbox-auto {buttonLayout} p-0" : btnClasses;

								<button type="button" class="btn @btnClasses d-inline-block variant-option js-variant-option @active" @btnWidth onclick="swift.VariantSelector.OptionClick(event)" data-variant-id="@option.Id" id="@(product.Id)_@(option.Id)_@Pageview.CurrentParagraph.ID">
									<span class="@(displayType == VariantGroupDisplayType.VariantName ? string.Empty : "ratio d-block")" style="@(buttonAspectRatio)">

										@switch (displayType)
										{
											case VariantGroupDisplayType.VariantOptionImage:
												if (!string.IsNullOrEmpty(option.OptionImage.Value))
												{
													<img style="object-fit:cover;--variantoption-check-color:@(contrastColor)" src="/Admin/Public/GetImage.ashx?image=@(option.OptionImage.Value)&width=64&format=webp">
												}
												else if (!string.IsNullOrEmpty(option.Color))
												{
													<span class="" style="background-color:@(option.Color);--variantoption-check-color:@(contrastColor)"><span class="visually-hidden">@option.Color</span></span>
												}
												else
												{
													<span class="d-flex align-items-center justify-content-center">@(option.Name)</span>
												}
												break;

											case VariantGroupDisplayType.VariantImage:
												if (variantImages.TryGetValue(option.Id, out var variantImage) && variantImage != string.Empty) {

													<img style="object-fit:contain" src="/Admin/Public/GetImage.ashx?image=@(variantImage)&width=64&format=webp">
												}
												break;

											case VariantGroupDisplayType.VariantColor:
												contrastColor = GetContrastColor(option.Color);
												<span style="background-color:@(option.Color);--variantoption-check-color:@(contrastColor)"><span class="visually-hidden">@option.Color</span></span>
												break;

											case VariantGroupDisplayType.VariantName:
												<span class="d-flex align-items-center justify-content-center">@(option.Name)</span>
												break;

										}
									</span>
								</button>
							}
						}
						else
	{
							<select class="form-select" id="VariantDropdown_@variantGroup.Id" aria-label="@variantGroup.Name" onchange="swift.VariantSelector.OptionClick(event)">
								@if (string.IsNullOrEmpty(product.VariantId))
								{
									<option value="" class="variant-option js-variant-option" data-variant-id="">@Translate("Nothing selected")</option>
								}

								@foreach (var option in variantGroup.Options)
								{
		string active = variantId != null && variantId.Contains(option.Id) ? "active" : "";
		var selected = variantId != null && variantId.Contains(option.Id) ? "selected" : "";
		var value = $"{product.Id}_{option.Id}";

									<option value="@(value)" class="variant-option js-variant-option @active" data-variant-id="@option.Id" id="@(value)_@(Pageview.CurrentParagraph.ID)" @selected>@option.Name</option>
								}
							</select>
						}
					</div>
				</div>

				groupNumber++;
			}
		</form>

		<script type="module">
			swift.VariantSelector.init();
		</script>
	}
	else if (Pageview.IsVisualEditorMode)
	{
		string horizontalAlign = GetDefaultOrVariantGroupValue("", "HorizontalAlignment", "", new Dictionary<string, string> { { "center", "justify-content-center" }, { "end", "justify-content-end" } });
		string horizontalTextAlign = GetDefaultOrVariantGroupValue("", "HorizontalAlignment", "", new Dictionary<string, string> { { "center", "text-center" }, { "end", "text-end" } });

		<form class="d-flex flex-column js-variant-selector @itemId" data-combinations="VO1,VO2,VO3,VO4">
			<div>
				@if (!hideGroupHeaders)
				{
					<h3 class="h6 @horizontalTextAlign">@Translate("Sizes")</h3>
				}
				<div class="mb-3 @horizontalAlign js-variant-group" data-group-id="0">
					<button type="button" class="btn btn-secondary d-inline-block mb-2 variant-option js-variant-option" data-dw-button="secondary" onclick="swift.VariantSelector.OptionClick(event)" data-variant-id="VO1" id="@(product.Id)_VO1_@Pageview.CurrentParagraph.ID">S</button>
					<button type="button" class="btn btn-secondary d-inline-block mb-2 variant-option js-variant-option" data-dw-button="secondary" onclick="swift.VariantSelector.OptionClick(event)" data-variant-id="VO2" id="@(product.Id)_VO2_@Pageview.CurrentParagraph.ID">M</button>
					<button type="button" class="btn btn-secondary d-inline-block mb-2 variant-option js-variant-option" data-dw-button="secondary" onclick="swift.VariantSelector.OptionClick(event)" data-variant-id="VO3" id="@(product.Id)_VO3_@Pageview.CurrentParagraph.ID">L</button>
					<button type="button" class="btn btn-secondary d-inline-block mb-2 variant-option js-variant-option" data-dw-button="secondary" onclick="swift.VariantSelector.OptionClick(event)" data-variant-id="VO4" id="@(product.Id)_VO4_@Pageview.CurrentParagraph.ID">XL</button>
				</div>
			</div>
		</form>

		<script type="module">
			swift.VariantSelector.init();
		</script>
	}
}
else if (Pageview.IsVisualEditorMode)
	{
	<div class="alert alert-dark m-0" role="alert">
		<span>@Translate("The variant selector will be shown here, if any variants are available")</span>
	</div>
}
