@namespace Lumeo

<div class="@CssClass" @attributes="AdditionalAttributes">
    @if (!string.IsNullOrEmpty(Title))
    {
        <p class="@TitleClass">@Title</p>
    }
    <div class="flex items-baseline gap-1">
        @if (Prefix is not null)
        {
            <span class="@ValueClass">@Prefix</span>
        }
        <span class="@ValueClass">@FormattedValue</span>
        @if (Suffix is not null)
        {
            <span class="@SuffixClass">@Suffix</span>
        }
    </div>
    @if (ShowTrend)
    {
        <div class="mt-1 flex items-center gap-1 text-sm @TrendClasses">
            @if (TrendDirection == TrendType.Up)
            {
                <Blazicon Svg="Lucide.TrendingUp" class="h-4 w-4" />
            }
            else
            {
                <Blazicon Svg="Lucide.TrendingDown" class="h-4 w-4" />
            }
            @if (!string.IsNullOrEmpty(TrendValue))
            {
                <span>@TrendValue</span>
            }
        </div>
    }
</div>

@code {
    [Parameter] public string? Title { get; set; }
    [Parameter] public string? Value { get; set; }
    [Parameter] public RenderFragment? Prefix { get; set; }
    [Parameter] public RenderFragment? Suffix { get; set; }
    [Parameter] public int? Precision { get; set; }

    /// <summary>
    /// Culture used when <see cref="Precision"/> is set. Default (null) falls back to
    /// <see cref="System.Globalization.CultureInfo.CurrentCulture"/> so a <c>de-DE</c>
    /// user sees <c>12,34</c> and an <c>en-US</c> user sees <c>12.34</c> automatically.
    /// </summary>
    [Parameter] public System.Globalization.CultureInfo? Culture { get; set; }

    private System.Globalization.CultureInfo EffectiveCulture => Culture ?? System.Globalization.CultureInfo.CurrentCulture;
    [Parameter] public bool ShowTrend { get; set; }
    [Parameter] public string? TrendValue { get; set; }
    [Parameter] public TrendType TrendDirection { get; set; } = TrendType.Up;
    [Parameter] public StatisticSize Size { get; set; } = StatisticSize.Medium;
    [Parameter] public StatisticVariant Variant { get; set; } = StatisticVariant.Default;
    [Parameter] public string? Class { get; set; }
    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }

    private string CssClass => $"{VariantClass} {Class}".Trim();

    private string VariantClass => Variant switch
    {
        StatisticVariant.Minimal => "",
        StatisticVariant.Bordered => "rounded-lg border border-border/60 p-4",
        _ => ""
    };

    private string TitleClass => Size switch
    {
        StatisticSize.Small => "text-xs text-muted-foreground",
        StatisticSize.Large => "text-base text-muted-foreground",
        _ => "text-sm text-muted-foreground"
    };

    private string ValueClass => Size switch
    {
        StatisticSize.Small => "text-lg font-semibold text-foreground",
        StatisticSize.Large => "text-4xl font-semibold text-foreground",
        _ => "text-2xl font-semibold text-foreground"
    };

    private string SuffixClass => Size switch
    {
        StatisticSize.Small => "text-xs text-muted-foreground",
        StatisticSize.Large => "text-base text-muted-foreground",
        _ => "text-sm text-muted-foreground"
    };

    private string FormattedValue
    {
        get
        {
            if (Value is null) return "";
            if (Precision.HasValue)
            {
                // Accept either invariant or the user's culture for the input string (both
                // "1234.5" and "1234,5" parse for a de-DE user). Render via the effective
                // culture so the thousands/decimal separators match the request locale.
                if (double.TryParse(Value, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out var numericValue)
                    || double.TryParse(Value, System.Globalization.NumberStyles.Any, EffectiveCulture, out numericValue))
                {
                    return numericValue.ToString($"N{Precision.Value}", EffectiveCulture);
                }
            }
            return Value;
        }
    }

    private string TrendClasses => TrendDirection switch
    {
        TrendType.Up => "text-success",
        TrendType.Down => "text-destructive",
        _ => ""
    };

    public enum TrendType { Up, Down }
    public enum StatisticSize { Small, Medium, Large }
    /// <summary>
    /// Default = plain (no decoration). Minimal = alias for Default (explicit opt-in to no chrome).
    /// Bordered = rounded border card wrapper.
    /// </summary>
    public enum StatisticVariant { Default, Minimal, Bordered }
}
