@page "/components/charts/area"

<PageTitle>Area Chart — Lumeo</PageTitle>

<PageHeader Title="Area Chart" Description="Emphasize the magnitude of change over time. The filled area makes it easy to visualize volume or cumulative data." />

<Stack Gap="8">
    <ComponentDemo Title="Gradient Area" Description="Smooth curves with a gradient fill — the default look that works well for a single metric like total visits." Code="@_basicCode">
        <Container>
            <AreaChart Categories="_categories" Series="_series" Smooth="true" Gradient="true" />
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="Stacked Area" Description="Stack multiple series to show cumulative volume. The filled areas make the combined total immediately visible." Code="@_stackedCode">
        <Container>
            <AreaChart Categories="_categories" Series="_series" Smooth="true" Stacked="true" Gradient="false" />
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="Multi-Channel Traffic" Description="Compare three traffic channels over a full year with gradient fills. Overlapping areas reveal seasonality patterns." Code="@_multiCode">
        <Container>
            <AreaChart Categories="_months" Series="_channelSeries" Smooth="true" Gradient="true" />
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="Stacked Gradient — Revenue Breakdown" Description="Stacked gradient fill shows how three revenue streams compose total ARR month over month." Code="@_stackedGradientCode">
        <Container>
            <AreaChart Categories="_months" Series="_revenueSeries" Smooth="true" Stacked="true" Gradient="true" />
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="Daily Bandwidth with DataZoom" Description="Dense daily data becomes navigable with the DataZoom slider. Disable dots to keep the chart clean." Code="@_zoomCode">
        <Container>
            <AreaChart Categories="_days" Series="_bandwidthSeries" Smooth="true" Gradient="true" ShowDots="false" DataZoom="true" />
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="Loading state" Description="Shape-aware skeleton with reserved space for legend and axes — no layout shift when real data arrives.">
        <Container>
            <Stack Gap="4">
                <Stack Direction="Stack.StackDirection.Horizontal" Gap="4" Align="center" Wrap="true">
                    <Button OnClick="SimulateLoadingAsync" Disabled="@_loading">Simulate loading</Button>
                    <Stack Direction="Stack.StackDirection.Horizontal" Gap="2" Align="center">
                        <Switch @bind-Value="_keepLoading" Id="keep-loading" />
                        <label for="keep-loading" class="text-sm text-muted-foreground cursor-pointer">Hold skeleton open</label>
                    </Stack>
                    <Stack Direction="Stack.StackDirection.Horizontal" Gap="2" Align="center">
                        <label class="text-sm text-muted-foreground">Duration: @(_simulateDurationMs / 1000.0)s</label>
                        <input type="range" min="500" max="10000" step="500" @bind-value="_simulateDurationMs" @bind-value:event="oninput" class="w-32 accent-primary" />
                    </Stack>
                    <Stack Direction="Stack.StackDirection.Horizontal" Gap="2" Align="center">
                        <label class="text-sm text-muted-foreground">Cycle: @_phantomCycleMs ms</label>
                        <input type="range" min="300" max="3000" step="100" @bind-value="_phantomCycleMs" @bind-value:event="oninput" class="w-32 accent-primary" />
                    </Stack>
                </Stack>
                <AreaChart Categories="_categories" Series="_series" Smooth="true" Gradient="true" PhantomCycleMs="@_phantomCycleMs" IsLoading="@LoadingComputed" Height="320px" />
            </Stack>
        </Container>
    </ComponentDemo>
</Stack>

<Stack Gap="6" Class="mt-12">
    <Heading Level="2">API Reference</Heading>
    <Stack Gap="8">
        <Stack>
            <Heading Level="3" Class="mb-3">AreaChart</Heading>
            <Stack Class="rounded-lg border border-border/40 overflow-x-auto">
                <table class="w-full min-w-[600px] text-sm">
                    <thead>
                        <tr class="border-b border-border/40 bg-muted/40">
                            <th class="text-left p-3 font-medium text-foreground">Property</th>
                            <th class="text-left p-3 font-medium text-foreground">Type</th>
                            <th class="text-left p-3 font-medium text-foreground">Default</th>
                            <th class="text-left p-3 font-medium text-foreground">Description</th>
                        </tr>
                    </thead>
                    <tbody class="divide-y divide-border/40">
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Categories</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">List&lt;string&gt;</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">[]</td>
                            <td class="p-3 text-muted-foreground">X-axis labels for each data point.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Series</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">List&lt;ChartSeriesData&gt;</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">[]</td>
                            <td class="p-3 text-muted-foreground">Data series with filled areas.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Smooth</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">false</td>
                            <td class="p-3 text-muted-foreground">Uses bezier curves for smooth edges.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Gradient</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">true</td>
                            <td class="p-3 text-muted-foreground">Applies a gradient fade to the filled area.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Stacked</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">false</td>
                            <td class="p-3 text-muted-foreground">Stacks series areas cumulatively.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">ShowDots</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">true</td>
                            <td class="p-3 text-muted-foreground">Shows dot markers on the line.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">DataZoom</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">false</td>
                            <td class="p-3 text-muted-foreground">Enables zoom slider for long time-series.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Colors</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">List&lt;string&gt;?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Custom color palette.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">LabelStrategy</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">ChartLabelStrategy</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">Smart</td>
                            <td class="p-3 text-muted-foreground">How category-axis labels are rendered. Smart auto-rotates at higher densities; ShowAll forces all horizontal; Auto thins overlapping labels.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">LabelRotate</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">int?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Manual rotation override in degrees on top of LabelStrategy.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">IsLoading</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">false</td>
                            <td class="p-3 text-muted-foreground">When true, renders a shape-matched loading skeleton in place of the chart. Bind to your async fetch state.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">ShowLoadingSkeleton</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">true</td>
                            <td class="p-3 text-muted-foreground">Set to false to opt out of the skeleton (chart area stays empty while IsLoading is true).</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">SkeletonKind</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">ChartSkeletonKind</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">(chart default)</td>
                            <td class="p-3 text-muted-foreground">Override the skeleton silhouette (Bars, Line, Area, Pie, Scatter, Grid, Generic).</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">SkeletonStyle</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">ChartSkeletonStyle</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">Phantom</td>
                            <td class="p-3 text-muted-foreground">Phantom renders the real chart with placeholder data and morphs to real data via ECharts animation. Silhouette falls back to the legacy SVG skeleton overlay.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">ShowLoadingLabel</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">true</td>
                            <td class="p-3 text-muted-foreground">Shows a small "Loading&hellip;" pill in the top-right corner whenever <code class="rounded bg-muted px-1 py-0.5 text-xs font-mono">IsLoading</code> is true. Layered on top of any <code class="rounded bg-muted px-1 py-0.5 text-xs font-mono">SkeletonStyle</code>. Set to false for bare visuals. <strong>(rc.18)</strong></td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">LoadingText</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">"Loading&hellip;"</td>
                            <td class="p-3 text-muted-foreground">Label rendered next to the spinner inside the loading pill. Set to empty to show the spinner alone. <strong>(rc.18)</strong></td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">ShowLegend</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">true</td>
                            <td class="p-3 text-muted-foreground">Toggles the series legend above the area chart.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">ShowTooltip</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">true</td>
                            <td class="p-3 text-muted-foreground">Shows the cross-series tooltip on hover.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Width</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">"100%"</td>
                            <td class="p-3 text-muted-foreground">CSS width applied to the chart container.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Height</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">"350px"</td>
                            <td class="p-3 text-muted-foreground">CSS height applied to the chart container.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Theme</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Overrides the ECharts theme; null follows the app's light/dark mode.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">PhantomCycleMs</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">int</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">1400</td>
                            <td class="p-3 text-muted-foreground">Phantom-mode refresh interval in milliseconds. Lower = faster data cycling while loading.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">ShowDataLabels</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">false</td>
                            <td class="p-3 text-muted-foreground">Renders the numeric value at each data point on the area.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">LabelPosition</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">"top"</td>
                            <td class="p-3 text-muted-foreground">Position of data labels relative to each point (e.g. top, inside).</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">LabelFormat</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">ECharts format string applied to point data labels.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Toolbox</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">bool</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">false</td>
                            <td class="p-3 text-muted-foreground">Shows the toolbox with save-as-image, restore, and view controls.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">ColorPalette</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">List&lt;string&gt;?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Overrides the chart's base color palette across all area series.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">AnimationDuration</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">int?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Override entry animation duration (ms); null uses the ECharts default.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">AnimationEasing</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">ECharts easing function name applied to entry animations.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">MarkLine</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">EChartMarkLine?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Optional mark line(s) overlaid on the area chart (e.g. averages, thresholds).</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">MarkPoint</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">EChartMarkPoint?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Optional mark point annotations highlighting min/max or specific points.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">MarkArea</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">EChartMarkArea?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Optional mark area shading to highlight x or y ranges.</td>
                        </tr>
                    </tbody>
                </table>
            </Stack>
        </Stack>
    </Stack>
</Stack>

@code {
    private List<string> _categories = new() { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
    private List<string> _months = new() { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

    private List<AreaChart.ChartSeriesData> _series = new()
    {
        new() { Name = "Unique Visitors", Values = new() { 3240, 4180, 3870, 5120, 6340, 4980, 3650 } },
        new() { Name = "Page Views",      Values = new() { 9810, 12540, 11200, 15870, 19420, 14730, 10900 } }
    };

    private List<AreaChart.ChartSeriesData> _channelSeries = new()
    {
        new() { Name = "Organic Search", Values = new() { 18400, 21300, 19800, 24700, 28100, 32600, 30200, 34800, 38400, 41900, 37600, 44200 } },
        new() { Name = "Direct",         Values = new() { 9200,  10800, 9900,  12300, 14100, 16400, 15100, 17400, 19200, 20900, 18800, 22100 } },
        new() { Name = "Paid Social",    Values = new() { 5100,  6300,  5800,  7200,  8400,  9700,  8900,  10300, 11400, 12600, 11100, 13400 } }
    };

    private List<AreaChart.ChartSeriesData> _revenueSeries = new()
    {
        new() { Name = "Enterprise",     Values = new() { 48300, 51200, 53700, 57400, 61800, 67200, 64900, 70300, 75800, 81400, 77200, 85600 } },
        new() { Name = "Professional",   Values = new() { 22100, 24300, 25800, 27600, 29900, 32400, 31200, 34100, 36800, 39500, 37400, 41800 } },
        new() { Name = "Starter",        Values = new() { 8400,  9100,  9700,  10400, 11200, 12100, 11700, 12800, 13700, 14700, 13900, 15600 } }
    };

    private List<string> _days = Enumerable.Range(1, 45)
        .Select(i => new DateTime(2025, 3, 1).AddDays(i - 1).ToString("MMM d"))
        .ToList();

    private List<AreaChart.ChartSeriesData> _bandwidthSeries = new()
    {
        new() { Name = "Inbound (GB)", Values = new()
        {
            1843, 2012, 1934, 2178, 2341, 2589, 2467, 2712, 2934, 3187,
            3042, 3298, 3512, 3789, 3634, 3912, 4123, 4389, 4234, 4523,
            4712, 4934, 4789, 5123, 5312, 5589, 5434, 5723, 5912, 6189,
            6034, 6323, 6512, 6789, 6634, 6923, 7112, 7389, 7234, 7523,
            7712, 7934, 7789, 8123, 8312
        }},
        new() { Name = "Outbound (GB)", Values = new()
        {
            921, 1006, 967, 1089, 1171, 1295, 1234, 1356, 1467, 1594,
            1521, 1649, 1756, 1895, 1817, 1956, 2062, 2195, 2117, 2262,
            2356, 2467, 2395, 2562, 2656, 2795, 2717, 2862, 2956, 3095,
            3017, 3162, 3256, 3395, 3317, 3462, 3556, 3695, 3617, 3762,
            3856, 3967, 3895, 4062, 4156
        }}
    };

    private string _basicCode = @"<AreaChart Categories=""_categories"" Series=""_series"" Smooth=""true"" Gradient=""true"" />";
    private string _stackedCode = @"<AreaChart Categories=""_categories"" Series=""_series"" Smooth=""true"" Stacked=""true"" Gradient=""false"" />";
    private string _multiCode = @"<AreaChart Categories=""_months"" Series=""_channelSeries"" Smooth=""true"" Gradient=""true"" />";
    private string _stackedGradientCode = @"<AreaChart Categories=""_months"" Series=""_revenueSeries"" Smooth=""true"" Stacked=""true"" Gradient=""true"" />";
    private string _zoomCode = @"<AreaChart Categories=""_days"" Series=""_bandwidthSeries"" Smooth=""true"" Gradient=""true"" ShowDots=""false"" DataZoom=""true"" />";

    private bool _loading;
    private bool _keepLoading;
    private bool LoadingComputed => _loading || _keepLoading;
    private int _simulateDurationMs = 2000;
    private int _phantomCycleMs = 1400;

    private async Task SimulateLoadingAsync()
    {
        _loading = true;
        await Task.Delay(_simulateDurationMs);
        _loading = false;
    }
}
