@namespace Lumeo

<Chart Option="@_option" Width="@Width" Height="@Height" Theme="@Theme" Class="@Class" IsLoading="@IsLoading" ShowLoadingSkeleton="@ShowLoadingSkeleton" SkeletonKind="@SkeletonKind" SkeletonStyle="@SkeletonStyle" ShowLoadingLabel="@ShowLoadingLabel" LoadingText="@LoadingText" PhantomCycleMs="@PhantomCycleMs" @attributes="AdditionalAttributes" />

@code {
    [Parameter] public object? Data { get; set; }
    [Parameter] public int Year { get; set; } = DateTime.Now.Year;
    [Parameter] public double VisualMapMin { get; set; } = 0;
    [Parameter] public double VisualMapMax { get; set; } = 10;
    [Parameter] public List<string>? Colors { get; set; }
    [Parameter] public bool ShowTooltip { get; set; } = true;
    [Parameter] public string Width { get; set; } = "100%";
    [Parameter] public string Height { get; set; } = "350px";
    [Parameter] public string? Theme { get; set; }
    [Parameter] public string? Class { get; set; }
    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }
    /// <summary>When true, overlays a shape-aware loading skeleton on top of the chart (consumer is fetching data). Flips back to the real chart once set to false.</summary>
    [Parameter] public bool IsLoading { get; set; }
    /// <summary>When true (default), renders a shape-aware skeleton while the chart has not yet mounted and whenever <see cref="IsLoading"/> is true. Set to <c>false</c> to opt out.</summary>
    [Parameter] public bool ShowLoadingSkeleton { get; set; } = true;
    /// <summary>Shape family for the loading skeleton. Defaults to <c>ChartSkeletonKind.Grid</c> for this chart type; override if you want a different silhouette.</summary>
    [Parameter] public ChartSkeletonKind SkeletonKind { get; set; } = ChartSkeletonKind.Grid;
    /// <summary>Phantom (default) renders the real chart with placeholder data and morphs to real data via ECharts' option-change animation. Silhouette falls back to the legacy SVG skeleton overlay.</summary>
    [Parameter] public ChartSkeletonStyle SkeletonStyle { get; set; } = ChartSkeletonStyle.Phantom;
    /// <summary>Phantom-mode refresh interval in milliseconds. Lower = faster data cycling while loading. Defaults to 1400.</summary>
    [Parameter] public int PhantomCycleMs { get; set; } = 1400;
    /// <summary>When true (default), shows a small "Loading…" pill in the top-right corner whenever <see cref="IsLoading"/> is active. Works on top of any <see cref="SkeletonStyle"/>.</summary>
    [Parameter] public bool ShowLoadingLabel { get; set; } = true;
    /// <summary>Label rendered next to the spinner inside the loading pill. Set to empty to hide. Defaults to "Loading…".</summary>
    [Parameter] public string? LoadingText { get; set; } = "Loading…";

    [Parameter] public bool ShowDataLabels { get; set; }
    [Parameter] public string LabelPosition { get; set; } = "inside";
    [Parameter] public string? LabelFormat { get; set; }
    [Parameter] public bool DataZoom { get; set; }
    [Parameter] public bool Toolbox { get; set; }
    [Parameter] public List<string>? ColorPalette { get; set; }
    [Parameter] public int? AnimationDuration { get; set; }
    [Parameter] public string? AnimationEasing { get; set; }
    [Parameter] public Dictionary<string, object>? OptionOverride { get; set; }

    private EChartOption _option = new();

    protected override void OnParametersSet()
    {
        var series = new EChartSeries
        {
            Type = "heatmap",
            CoordinateSystem = "calendar",
            CalendarIndex = 0,
            Data = Data
        };

        if (ShowDataLabels)
            series.Label = new EChartLabel { Show = true, Position = LabelPosition, Formatter = LabelFormat };

        var visualColors = Colors is { Count: > 0 }
            ? Colors
            : new List<string> { "#ebedf0", "#c6e48b", "#7bc96f", "#239a3b", "#196127" };

        _option = new EChartOption
        {
            Calendar = new EChartCalendar
            {
                Range = Year.ToString(),
                Left = "10%",
                Right = "5%",
                Top = "15%",
                CellSize = 13
            },
            VisualMap = new EChartVisualMap
            {
                Min = VisualMapMin,
                Max = VisualMapMax,
                Calculable = true,
                Orient = "horizontal",
                Left = "center",
                Top = "3%",
                InRange = new EChartVisualMapInRange { Color = visualColors }
            },
            Series = new List<EChartSeries> { series },
            Color = ColorPalette
        };

        if (ShowTooltip)
            _option.Tooltip = new EChartTooltip { Trigger = "item" };

        if (Toolbox)
            _option.Toolbox = new EChartToolbox { Show = true, Feature = new EChartToolboxFeature { SaveAsImage = new() { Show = true }, Restore = new() { Show = true } } };

        if (AnimationDuration.HasValue) _option.AnimationDuration = AnimationDuration;
        if (!string.IsNullOrEmpty(AnimationEasing)) _option.AnimationEasing = AnimationEasing;

        ChartHelper.ApplyOptionOverride(_option, OptionOverride);
    }
}
