@page "/can"
@inject ICanService CanService
@implements IDisposable

<div class="container mt-4">
    <div class="card shadow-sm">

        <!-- HEADER -->
        <div class="card-header d-flex justify-content-between align-items-center">
            <h5 class="mb-0">CAN Monitor (Live View)</h5>

            <div>
                <button class="btn btn-success btn-sm me-2"
                        @onclick="Start"
                        disabled="@isRunning">
                    ▶ Start
                </button>

                <button class="btn btn-danger btn-sm"
                        @onclick="Stop"
                        disabled="@(!isRunning)">
                    ■ Stop
                </button>
            </div>
        </div>

        <!-- TABLE -->
        <div class="card-body p-0" style="max-height: 420px; overflow-y: auto;">
            <table class="table table-striped table-hover table-sm mb-0">
                <thead class="table-dark sticky-top">
                    <tr>
                        <th style="width:140px">Time</th>
                        <th style="width:80px">CAN-ID</th>
                        <th style="width:120px">Meaning</th>
                        <th style="width:60px">Length</th>
                        <th>Raw Data</th>
                        <th style="width:200px">Result</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var msg in messages.Values.OrderBy(m => m.Id))
                    {
                        <tr>
                            <td>@msg.Timestamp.ToString("HH:mm:ss.fff")</td>
                            <td class="fw-bold text-primary">
                                @msg.Id.ToString("X3")
                            </td>
                            <td>@msg.Meaning</td>
                            <td>@msg.Length</td>
                            <td class="font-monospace">
                                @BitConverter.ToString(
                                msg.Data.Take(msg.Length).ToArray())
                        </td>
                        <td class="fw-semibold">
                            @msg.ValueText
                        </td>
                    </tr>
                                        }
                </tbody>
            </table>
        </div>

        <!-- FOOTER -->
        <div class="card-footer text-muted small d-flex justify-content-between">
            <span>Total CAN IDs: <b>@messages.Count</b></span>
            <span>Status: <b>@status</b></span>
        </div>
    </div>
</div>

@code {
    // DATA STORAGE (1 ID = 1 ROW)
    private Dictionary<uint, CanMessage> messages = new();

    private bool isRunning = false;
    private string status = "STOPPED";

    // INIT
    protected override void OnInitialized()
    {
        CanService.OnMessageReceived += OnCanMessage;
    }

    // RECEIVE CAN FRAME
    private void OnCanMessage(CanMessage msg)
    {
        InvokeAsync(() =>
        {
            // 🔴 Update data on the SAME row by CAN-ID
            messages[msg.Id] = msg;

            StateHasChanged();
        });
    }

    // START
    private async Task Start()
    {
        if (isRunning) return;

        status = "INITIALIZING...";
        StateHasChanged();

        await CanService.InitAsync();   // BẮT BUỘC
        CanService.StartStream();

        isRunning = true;
        status = "RUNNING";
    }

    // STOP
    private void Stop()
    {
        if (!isRunning) return;

        CanService.StopStream();
        isRunning = false;
        status = "STOPPED";
    }

    // CLEANUP
    public void Dispose()
    {
        CanService.OnMessageReceived -= OnCanMessage;
        CanService.StopStream();
    }
}
