@page "/components/agent-message-list"
@implements IDisposable

<PageTitle>AgentMessageList — Lumeo</PageTitle>

<PageHeader Title="AgentMessageList"
            Description="Auto-scrolling chat-style message list for AI agent conversations. Distinguishes user, assistant, and tool turns." />

<div class="mt-10 space-y-3">
    <Heading Id="when-to-use" Level="2" Class="scroll-mt-20">When to Use</Heading>
    <ul class="list-disc list-inside space-y-1 text-muted-foreground text-sm">
        <li>Rendering an LLM conversation where user, assistant, and tool messages need distinct styling.</li>
        <li>Streaming multi-turn responses — <code class="text-xs bg-muted px-1 py-0.5 rounded">AutoScroll</code> sticks to the bottom as new tokens arrive.</li>
        <li>Composing with <code class="text-xs bg-muted px-1 py-0.5 rounded">&lt;StreamingText&gt;</code>, <code class="text-xs bg-muted px-1 py-0.5 rounded">&lt;ToolCallCard&gt;</code>, and <code class="text-xs bg-muted px-1 py-0.5 rounded">&lt;ReasoningDisplay&gt;</code> for a full agent UI.</li>
    </ul>
</div>

<Stack Gap="8" Class="mt-8">
    <ComponentDemo Title="Live Chat Transcript" Code="@_demoCode">
        <div class="flex h-[520px] flex-col gap-3 rounded-lg border border-border/60 bg-background p-3">
            <AgentMessageList Class="flex-1 pr-1">
                <AgentMessage Role="AgentMessage.AgentMessageRole.System">
                    Session started @DateTime.Now.ToString("HH:mm")
                </AgentMessage>

                <AgentMessage Role="AgentMessage.AgentMessageRole.User" Name="You" Timestamp="DateTimeOffset.Now.AddMinutes(-2)">
                    Summarise the quarterly revenue numbers for EMEA and tell me which region grew fastest.
                </AgentMessage>

                <AgentMessage Role="AgentMessage.AgentMessageRole.Assistant" Name="Lumeo Copilot" Timestamp="DateTimeOffset.Now.AddMinutes(-2)">
                    <ReasoningDisplay Text="User wants EMEA revenue breakdown. I should call the sales tool to pull Q1–Q4 numbers, then compute growth per sub-region. DACH looked strong last quarter."
                                      DurationMs="2400" />
                </AgentMessage>

                <AgentMessage Role="AgentMessage.AgentMessageRole.Tool">
                    <ToolCallCard ToolName="query_sales_db"
                                  Status="ToolCallCard.ToolCallStatus.Success"
                                  Input="@("{\n  \"region\": \"EMEA\",\n  \"period\": \"2026-Q1\"\n}")"
                                  Output="@("{\n  \"DACH\": 12_400_000,\n  \"UK\": 9_800_000,\n  \"Nordics\": 4_200_000,\n  \"Iberia\": 3_100_000\n}")"
                                  DurationMs="842" />
                </AgentMessage>

                <AgentMessage Role="AgentMessage.AgentMessageRole.Assistant" Name="Lumeo Copilot" IsStreaming="@_isStreaming">
                    <StreamingText Text="@_streamedText" IsStreaming="@_isStreaming" />
                </AgentMessage>
            </AgentMessageList>

            <PromptInput @bind-Value="_promptValue"
                         Placeholder="Ask a follow-up…"
                         IsLoading="@_isStreaming"
                         OnSend="HandleSend">
                <LeadingContent>
                    <button type="button" class="inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground" aria-label="Attach file">
                        <Icon Name="Paperclip" Size="Icon.IconSize.Sm" />
                    </button>
                </LeadingContent>
                <TrailingContent>
                    <span class="tabular-nums">@(_promptValue?.Length ?? 0) / 2000</span>
                </TrailingContent>
            </PromptInput>
        </div>
    </ComponentDemo>

    <ComponentDemo Title="Role Switcher — interactive" Description="Pick a role to see how a single AgentMessage renders for each turn type." Code="@_roleSwitcherCode">
        <Stack Gap="4" Class="w-full max-w-xl">
            <Segmented @bind-Value="_agentRole">
                <SegmentedItem Value="User">User</SegmentedItem>
                <SegmentedItem Value="Assistant">Assistant</SegmentedItem>
                <SegmentedItem Value="System">System</SegmentedItem>
                <SegmentedItem Value="Tool">Tool</SegmentedItem>
            </Segmented>
            <AgentMessageList>
                @if (_agentRole == "Tool")
                {
                    <AgentMessage Role="AgentMessage.AgentMessageRole.Tool">
                        <ToolCallCard ToolName="example_tool" Status="ToolCallCard.ToolCallStatus.Success"
                                      Input="@("{}")" Output="OK" DurationMs="12" />
                    </AgentMessage>
                }
                else
                {
                    <AgentMessage Role="@_agentRoleEnum"
                                  Name="@(_agentRole == "User" ? "You" : _agentRole == "Assistant" ? "Copilot" : null)">
                        This is a <strong>@_agentRole</strong> message. Its bubble style, alignment, and label adapt to the selected role.
                    </AgentMessage>
                }
            </AgentMessageList>
        </Stack>
    </ComponentDemo>

    <ComponentDemo Title="Roles at a Glance" Code="@_rolesCode">
        <div class="w-full max-w-xl">
            <AgentMessageList>
                <AgentMessage Role="AgentMessage.AgentMessageRole.System">
                    System-level notice — session info, warnings, or injected context.
                </AgentMessage>
                <AgentMessage Role="AgentMessage.AgentMessageRole.User" Name="Alice">
                    A user turn — right-aligned bubble with name.
                </AgentMessage>
                <AgentMessage Role="AgentMessage.AgentMessageRole.Assistant" Name="Assistant">
                    An assistant turn — left-aligned with optional streaming caret.
                </AgentMessage>
                <AgentMessage Role="AgentMessage.AgentMessageRole.Tool">
                    <ToolCallCard ToolName="example_tool" Status="ToolCallCard.ToolCallStatus.Success"
                                  Input="@("{}")" Output="OK" DurationMs="12" />
                </AgentMessage>
            </AgentMessageList>
        </div>
    </ComponentDemo>
</Stack>

<!-- API Reference -->
<Stack Gap="6" Class="mt-12">
    <Heading Id="api-reference" Level="2" Class="scroll-mt-20">API Reference</Heading>

    <Stack Gap="8" Class="mt-8">
        <Stack>
            <Heading Level="3" Class="mb-3">AgentMessageList</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">ChildContent</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">RenderFragment?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">—</td>
                            <td class="p-3 text-muted-foreground">Usually one or more <code class="font-mono text-xs">&lt;AgentMessage&gt;</code> children.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">AutoScroll</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">Keeps the list scrolled to the bottom when new content arrives via a MutationObserver.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Class</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">—</td>
                            <td class="p-3 text-muted-foreground">Additional CSS classes on the root scroll container.</td>
                        </tr>
                    </tbody>
                </table>
            </Stack>
        </Stack>

        <Stack>
            <Heading Level="3" Class="mb-3">AgentMessage</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">Role</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">AgentMessageRole</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">Assistant</td>
                            <td class="p-3 text-muted-foreground">One of <code class="text-xs">User</code>, <code class="text-xs">Assistant</code>, <code class="text-xs">System</code>, <code class="text-xs">Tool</code>.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Name</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">—</td>
                            <td class="p-3 text-muted-foreground">Display name shown above the message bubble.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Timestamp</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">DateTimeOffset?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">—</td>
                            <td class="p-3 text-muted-foreground">Optional timestamp displayed next to the name.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">IsStreaming</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">Appends a pulsing caret to the body while the model is generating.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Avatar</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">RenderFragment?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">—</td>
                            <td class="p-3 text-muted-foreground">Optional avatar rendered alongside the bubble.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">ChildContent</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">RenderFragment?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">—</td>
                            <td class="p-3 text-muted-foreground">Message body — plain text, <code class="text-xs">&lt;StreamingText&gt;</code>, or any markup.</td>
                        </tr>
                    </tbody>
                </table>
            </Stack>
        </Stack>
    </Stack>
</Stack>

<div class="mt-12">
    <Heading Id="related" Level="2" Class="scroll-mt-20">Related Components</Heading>
    <ul class="mt-4 space-y-2 text-sm">
        <li><a href="/components/prompt-input" class="text-primary hover:underline">PromptInput</a> — Auto-grow textarea with send button, token count slot, and file attach slot.</li>
        <li><a href="/components/streaming-text" class="text-primary hover:underline">StreamingText</a> — Token-by-token text reveal with pulsing caret.</li>
        <li><a href="/components/tool-call-card" class="text-primary hover:underline">ToolCallCard</a> — Collapsible card showing tool name, input, output, and status.</li>
        <li><a href="/components/ai" class="text-primary hover:underline">AI Chat Primitives</a> — Overview of all AI chat components in Lumeo.</li>
    </ul>
</div>

@code {
    private string _agentRole = "Assistant";
    private AgentMessage.AgentMessageRole _agentRoleEnum =>
        Enum.TryParse<AgentMessage.AgentMessageRole>(_agentRole, out var r) ? r : AgentMessage.AgentMessageRole.Assistant;

    private const string _roleSwitcherCode = """
<Segmented @bind-Value="_role">
    <SegmentedItem Value="User">User</SegmentedItem>
    <SegmentedItem Value="Assistant">Assistant</SegmentedItem>
    <SegmentedItem Value="System">System</SegmentedItem>
    <SegmentedItem Value="Tool">Tool</SegmentedItem>
</Segmented>
<AgentMessageList>
    <AgentMessage Role="@Enum.Parse<AgentMessage.AgentMessageRole>(_role)"
                  Name="@(_role == "User" ? "You" : _role == "Assistant" ? "Copilot" : null)">
        This is a @_role message.
    </AgentMessage>
</AgentMessageList>

@code { private string _role = "Assistant"; }
""";

    private string? _promptValue;
    private string _streamedText = "The fastest grower was DACH at +18% YoY, driven mainly by…";
    private bool _isStreaming;

    private System.Threading.Timer? _timer;
    private static readonly string[] _chunks =
    {
        " enterprise licenses", " from two", " Fortune-500 accounts", ". UK grew +11%", ", Nordics held flat", ", and Iberia slipped", " -3% after a channel reshuffle."
    };
    private int _chunkIndex;

    protected override void OnInitialized()
    {
        _timer = new System.Threading.Timer(_ =>
        {
            if (!_isStreaming) return;
            if (_chunkIndex < _chunks.Length)
            {
                _streamedText += _chunks[_chunkIndex++];
                InvokeAsync(StateHasChanged);
            }
            else
            {
                _isStreaming = false;
                _chunkIndex = 0;
                InvokeAsync(StateHasChanged);
            }
        }, null, dueTime: System.Threading.Timeout.Infinite, period: 600);
    }

    private void HandleSend(string value)
    {
        if (string.IsNullOrWhiteSpace(value)) return;
        _promptValue = string.Empty;
        _streamedText = $"Received: \"{value}\". Let me pull the numbers…";
        _chunkIndex = 0;
        _isStreaming = true;
        _timer?.Change(0, 600);
    }

    public void Dispose() => _timer?.Dispose();

    private const string _demoCode = """
<AgentMessageList Class="flex-1">
    <AgentMessage Role="AgentMessage.AgentMessageRole.User" Name="You">
        Summarise the quarterly revenue for EMEA.
    </AgentMessage>
    <AgentMessage Role="AgentMessage.AgentMessageRole.Assistant" Name="Copilot" IsStreaming="@_isStreaming">
        <StreamingText Text="@_streamedText" IsStreaming="@_isStreaming" />
    </AgentMessage>
</AgentMessageList>

<PromptInput @bind-Value="_prompt" OnSend="HandleSend" IsLoading="@_isStreaming" />
""";

    private const string _rolesCode = """
<AgentMessageList>
    <AgentMessage Role="AgentMessage.AgentMessageRole.System">
        System notice.
    </AgentMessage>
    <AgentMessage Role="AgentMessage.AgentMessageRole.User" Name="Alice">
        A user turn.
    </AgentMessage>
    <AgentMessage Role="AgentMessage.AgentMessageRole.Assistant" Name="Assistant">
        An assistant turn.
    </AgentMessage>
    <AgentMessage Role="AgentMessage.AgentMessageRole.Tool">
        <ToolCallCard ToolName="example_tool" Status="ToolCallCard.ToolCallStatus.Success"
                      Input="{}" Output="OK" DurationMs="12" />
    </AgentMessage>
</AgentMessageList>
""";
}
