@implements IDisposable
@inject AuthenticationStateProvider AuthStateProvider
@inject NavigationManager Navigation

@code {
    private CancellationTokenSource? _cts;

    protected override async Task OnInitializedAsync()
    {
        var auth = await AuthStateProvider.GetAuthenticationStateAsync();
        if (auth.User.Identity?.IsAuthenticated != true) return;

        var claim = auth.User.FindFirst("expires_at")?.Value;
        if (!long.TryParse(claim, out var unix)) return;

        var remaining = DateTimeOffset.FromUnixTimeSeconds(unix) - DateTimeOffset.UtcNow;
        if (remaining <= TimeSpan.Zero)
        {
            Navigation.NavigateTo("/login", forceLoad: true);
            return;
        }

        _cts = new CancellationTokenSource();
        _ = ScheduleRedirectAsync(remaining + TimeSpan.FromSeconds(2), _cts.Token);
    }

    private async Task ScheduleRedirectAsync(TimeSpan delay, CancellationToken token)
    {
        try { await Task.Delay(delay, token); }
        catch (TaskCanceledException) { return; }
        await InvokeAsync(() => Navigation.NavigateTo("/login", forceLoad: true));
    }

    public void Dispose()
    {
        _cts?.Cancel();
        _cts?.Dispose();
    }
}
