using System.Text.Json;
using System.Text.RegularExpressions;
using FoodLabeling.Application.Contracts.Dtos.LabelTemplate;
namespace FoodLabeling.Application.Helpers;
///
/// 模板「Entered Automatically → Label ID」控件识别与展示文案填充。
///
public static class LabelTemplateLabelIdHelper
{
private static readonly Regex LabelIdElementNameRe = new(
"^labelid\\d*$",
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
public static bool IsLabelIdElement(
string? typeAdd,
string? elementName,
string? valueSourceType,
string? elementType)
{
var ta = (typeAdd ?? string.Empty).Trim().ToLowerInvariant();
if (ta.StartsWith("auto_", StringComparison.Ordinal) && ta.Contains("label id", StringComparison.Ordinal))
{
return true;
}
var slug = Regex.Replace((elementName ?? string.Empty).Trim().ToLowerInvariant(), "[^a-z0-9]", string.Empty);
if (LabelIdElementNameRe.IsMatch(slug))
{
return true;
}
if (string.Equals(valueSourceType, "AUTO_DB", StringComparison.OrdinalIgnoreCase)
&& string.Equals(elementType, "TEXT_STATIC", StringComparison.OrdinalIgnoreCase)
&& slug.StartsWith("labelid", StringComparison.Ordinal))
{
return true;
}
return false;
}
public static bool TemplateContainsLabelId(IEnumerable? elements) =>
elements?.Any(e => IsLabelIdElement(e.TypeAdd, e.ElementName, e.ValueSourceType, e.ElementType)) == true;
public static string FormatDisplayLine(string rawId, IReadOnlyDictionary? config)
{
var id = (rawId ?? string.Empty).Trim();
var prefix = ReadConfigString(config, "prefix", "Prefix", "LABEL ID: ").Trim();
if (string.IsNullOrWhiteSpace(id))
{
return string.IsNullOrWhiteSpace(prefix) ? "—" : $"{prefix}—";
}
if (!string.IsNullOrWhiteSpace(prefix)
&& id.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
return id;
}
if (string.IsNullOrWhiteSpace(prefix))
{
return id;
}
var needsSpace = !prefix.EndsWith(':') && !prefix.EndsWith(' ');
return needsSpace ? $"{prefix} {id}" : $"{prefix}{id}";
}
public static void ApplyLabelIdToElements(
IList elements,
string rawDisplayId)
{
if (elements.Count == 0 || string.IsNullOrWhiteSpace(rawDisplayId))
{
return;
}
foreach (var el in elements)
{
if (!IsLabelIdElement(el.TypeAdd, el.ElementName, el.ValueSourceType, el.ElementType))
{
continue;
}
var cfg = ParseConfigDictionary(el.ConfigJson);
var line = FormatDisplayLine(rawDisplayId, cfg);
UpsertConfigValue(cfg, "text", line);
UpsertConfigValue(cfg, "Text", line);
el.ConfigJson = cfg;
}
}
private static string ReadConfigString(
IReadOnlyDictionary? config,
string key1,
string key2,
string fallback)
{
if (config is null)
{
return fallback;
}
if (config.TryGetValue(key1, out var v1) && v1 != null)
{
return v1.ToString() ?? fallback;
}
if (config.TryGetValue(key2, out var v2) && v2 != null)
{
return v2.ToString() ?? fallback;
}
return fallback;
}
private static Dictionary ParseConfigDictionary(object? configJson)
{
if (configJson is null)
{
return new Dictionary();
}
if (configJson is Dictionary dict)
{
return new Dictionary(dict);
}
if (configJson is JsonElement je && je.ValueKind == JsonValueKind.Object)
{
return JsonSerializer.Deserialize>(je.GetRawText())
?? new Dictionary();
}
try
{
return JsonSerializer.Deserialize>(JsonSerializer.Serialize(configJson))
?? new Dictionary();
}
catch
{
return new Dictionary();
}
}
private static void UpsertConfigValue(Dictionary cfg, string key, object? value)
{
if (cfg.ContainsKey(key))
{
cfg[key] = value;
return;
}
cfg.Add(key, value);
}
}