@page "/components/charts/treemap"

<PageTitle>Treemap Chart — Lumeo</PageTitle>

<PageHeader Title="Treemap Chart" Description="Visualize hierarchical data as nested rectangles. The area of each rectangle is proportional to its value, making it easy to spot the largest categories." />

<Stack Gap="8">
    <ComponentDemo Title="Department Budget Treemap" Description="Annual operating budget broken down by department and sub-team. Nested children show how each department's allocation is split internally." Code="@_basicCode">
        <Container>
            <TreemapChart Data="_data" />
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="Disk Usage" Description="Filesystem usage breakdown by directory. A flat (non-hierarchical) treemap quickly surfaces the largest consumers of storage space." Code="@_diskCode">
        <Container>
            <TreemapChart Data="_diskData" ShowLegend="false" />
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="Product Revenue Mix" Description="Revenue by product category and individual SKU. Data labels enabled so each tile shows its name without hovering." Code="@_revenueCode">
        <Container>
            <TreemapChart Data="_revenueData" ShowDataLabels="true" Toolbox="true" />
        </Container>
    </ComponentDemo>

    <ComponentDemo Title="Org Headcount by Business Unit" Description="Headcount by business unit with a violet-to-indigo palette override and Toolbox for screenshot export." Code="@_headcountCode">
        <Container>
            <TreemapChart Data="_headcountData" Toolbox="true" Colors="_violetPalette" />
        </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>
                <TreemapChart Data="_data" PhantomCycleMs="@_phantomCycleMs" IsLoading="@LoadingComputed" Height="320px" />
            </Stack>
        </Container>
    </ComponentDemo>
</Stack>

<!-- API Reference -->
<Stack Gap="6" Class="mt-12">
    <Heading Level="2">API Reference</Heading>
    <Stack Gap="8">
        <Stack>
            <Heading Level="3" Class="mb-3">TreemapChart</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">Data</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">List&lt;TreemapData&gt;</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">[]</td>
                            <td class="p-3 text-muted-foreground">Hierarchical data with Name, Value, and optional Children.</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">Shows or hides the chart legend.</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">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">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">Chart container width as a CSS length.</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">Chart container height as a CSS length.</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">ECharts theme name applied to this chart instance.</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">Named palette used to seed tile colors.</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 or hides hover tooltips on treemap tiles.</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">Show value labels on tiles.</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">"inside"</td>
                            <td class="p-3 text-muted-foreground">Position of data labels relative to each tile.</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 label formatter template string.</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">Enable interactive zoom controls.</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">Show ECharts toolbox with save, restore, and zoom utilities.</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">Animation length in milliseconds when rendering.</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 animations.</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 while loading.</td>
                        </tr>
                    </tbody>
                </table>
            </Stack>
        </Stack>
    </Stack>
</Stack>

@code {
    // Demo 1 — department budget
    private List<TreemapChart.TreemapData> _data = new()
    {
        new() { Name = "Engineering", Value = 580, Children = new()
        {
            new() { Name = "Frontend",  Value = 210 },
            new() { Name = "Backend",   Value = 240 },
            new() { Name = "DevOps",    Value = 130 }
        }},
        new() { Name = "Marketing", Value = 320, Children = new()
        {
            new() { Name = "Content",   Value = 130 },
            new() { Name = "SEO",       Value = 100 },
            new() { Name = "Paid Ads",  Value = 90  }
        }},
        new() { Name = "Design", Value = 230, Children = new()
        {
            new() { Name = "Product UI", Value = 140 },
            new() { Name = "Brand",      Value = 90  }
        }},
        new() { Name = "Sales", Value = 280 }
    };

    // Demo 2 — disk usage (flat)
    private List<TreemapChart.TreemapData> _diskData = new()
    {
        new() { Name = "/var/log",   Value = 42  },
        new() { Name = "/home",      Value = 128 },
        new() { Name = "/usr",       Value = 85  },
        new() { Name = "/opt",       Value = 64  },
        new() { Name = "/tmp",       Value = 18  },
        new() { Name = "/srv",       Value = 220 },
        new() { Name = "/etc",       Value = 5   },
        new() { Name = "/var/cache", Value = 37  }
    };

    // Demo 3 — product revenue
    private List<TreemapChart.TreemapData> _revenueData = new()
    {
        new() { Name = "SaaS", Value = 1240, Children = new()
        {
            new() { Name = "Starter",    Value = 310 },
            new() { Name = "Growth",     Value = 480 },
            new() { Name = "Enterprise", Value = 450 }
        }},
        new() { Name = "Professional Services", Value = 540, Children = new()
        {
            new() { Name = "Implementation", Value = 280 },
            new() { Name = "Training",       Value = 160 },
            new() { Name = "Support",        Value = 100 }
        }},
        new() { Name = "Marketplace", Value = 380 },
        new() { Name = "API Usage",   Value = 210 }
    };

    // Demo 4 — headcount
    private List<TreemapChart.TreemapData> _headcountData = new()
    {
        new() { Name = "Product",          Value = 42  },
        new() { Name = "Engineering",      Value = 118 },
        new() { Name = "Sales",            Value = 67  },
        new() { Name = "Marketing",        Value = 28  },
        new() { Name = "Customer Success", Value = 35  },
        new() { Name = "Finance & Ops",    Value = 22  },
        new() { Name = "HR & Legal",       Value = 18  }
    };
    private List<string> _violetPalette = new() { "#7c3aed", "#6d28d9", "#5b21b6", "#4c1d95", "#a78bfa", "#c4b5fd" };

    private string _basicCode     = @"<TreemapChart Data=""_data"" />";
    private string _diskCode      = @"<TreemapChart Data=""_diskData"" ShowLegend=""false"" />";
    private string _revenueCode   = @"<TreemapChart Data=""_revenueData"" ShowDataLabels=""true"" Toolbox=""true"" />";
    private string _headcountCode = @"<TreemapChart Data=""_headcountData"" Toolbox=""true"" Colors=""_violetPalette"" />";

    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;
    }
}
