@page "/monitoring/parked-messages"
@attribute [Authorize]
@using ScadaLink.Commons.Entities.Sites
@using ScadaLink.Commons.Interfaces.Repositories
@using ScadaLink.Commons.Messages.RemoteQuery
@using ScadaLink.Communication
@inject ISiteRepository SiteRepository
@inject CommunicationService CommunicationService

<div class="container-fluid mt-3">
    <h4 class="mb-3">Parked Messages</h4>

    <ToastNotification @ref="_toast" />
    <ConfirmDialog @ref="_confirmDialog" />

    <div class="row mb-3 g-2">
        <div class="col-md-3">
            <label class="form-label small">Site</label>
            <select class="form-select form-select-sm" @bind="_selectedSiteId">
                <option value="">Select site...</option>
                @foreach (var site in _sites)
                {
                    <option value="@site.SiteIdentifier">@site.Name</option>
                }
            </select>
        </div>
        <div class="col-md-2 d-flex align-items-end">
            <button class="btn btn-primary btn-sm" @onclick="Search"
                    disabled="@(string.IsNullOrEmpty(_selectedSiteId) || _searching)">
                @if (_searching) { <span class="spinner-border spinner-border-sm"></span> }
                Query
            </button>
        </div>
    </div>

    @if (_errorMessage != null)
    {
        <div class="alert alert-danger">@_errorMessage</div>
    }

    @if (_messages != null)
    {
        <table class="table table-sm table-striped table-hover">
            <thead class="table-dark">
                <tr>
                    <th>Message ID</th>
                    <th>Target System</th>
                    <th>Method</th>
                    <th>Error</th>
                    <th>Attempts</th>
                    <th>Original</th>
                    <th>Last Attempt</th>
                    <th style="width: 120px;">Actions</th>
                </tr>
            </thead>
            <tbody>
                @if (_messages.Count == 0)
                {
                    <tr><td colspan="8" class="text-muted text-center">No parked messages.</td></tr>
                }
                @foreach (var msg in _messages)
                {
                    <tr>
                        <td class="small"><code>@msg.MessageId[..Math.Min(12, msg.MessageId.Length)]</code></td>
                        <td class="small">@msg.TargetSystem</td>
                        <td class="small">@msg.MethodName</td>
                        <td class="small text-danger">@msg.ErrorMessage</td>
                        <td class="small text-center">@msg.AttemptCount</td>
                        <td class="small"><TimestampDisplay Value="@msg.OriginalTimestamp" /></td>
                        <td class="small"><TimestampDisplay Value="@msg.LastAttemptTimestamp" /></td>
                        <td>
                            <button class="btn btn-outline-success btn-sm py-0 px-1 me-1"
                                    @onclick="() => RetryMessage(msg)" disabled="@_actionInProgress"
                                    title="Retry message (move back to pending)">Retry</button>
                            <button class="btn btn-outline-danger btn-sm py-0 px-1"
                                    @onclick="() => DiscardMessage(msg)" disabled="@_actionInProgress"
                                    title="Permanently discard message">Discard</button>
                        </td>
                    </tr>
                }
            </tbody>
        </table>

        @if (_totalCount > 0)
        {
            <div class="d-flex justify-content-between align-items-center">
                <span class="text-muted small">Page @_pageNumber of @((_totalCount + _pageSize - 1) / _pageSize) (@_totalCount total)</span>
                <div>
                    <button class="btn btn-outline-secondary btn-sm me-1" @onclick="PrevPage" disabled="@(_pageNumber <= 1)">Previous</button>
                    <button class="btn btn-outline-secondary btn-sm" @onclick="NextPage" disabled="@(_messages.Count < _pageSize)">Next</button>
                </div>
            </div>
        }
    }
</div>

@code {
    private List<Site> _sites = new();
    private string _selectedSiteId = string.Empty;
    private List<ParkedMessageEntry>? _messages;
    private int _totalCount;
    private int _pageNumber = 1;
    private int _pageSize = 25;
    private bool _searching;
    private string? _errorMessage;

    private bool _actionInProgress;
    private ToastNotification _toast = default!;
    private ConfirmDialog _confirmDialog = default!;

    protected override async Task OnInitializedAsync()
    {
        _sites = (await SiteRepository.GetAllSitesAsync()).ToList();
    }

    private async Task Search()
    {
        _pageNumber = 1;
        await FetchPage();
    }

    private async Task PrevPage() { _pageNumber--; await FetchPage(); }
    private async Task NextPage() { _pageNumber++; await FetchPage(); }

    private async Task FetchPage()
    {
        _searching = true;
        _errorMessage = null;
        try
        {
            var request = new ParkedMessageQueryRequest(
                CorrelationId: Guid.NewGuid().ToString("N"),
                SiteId: _selectedSiteId,
                PageNumber: _pageNumber,
                PageSize: _pageSize,
                Timestamp: DateTimeOffset.UtcNow);

            var response = await CommunicationService.QueryParkedMessagesAsync(_selectedSiteId, request);

            if (response.Success)
            {
                _messages = response.Messages.ToList();
                _totalCount = response.TotalCount;
            }
            else
            {
                _errorMessage = response.ErrorMessage ?? "Query failed.";
            }
        }
        catch (Exception ex)
        {
            _errorMessage = $"Query failed: {ex.Message}";
        }
        _searching = false;
    }

    private async Task RetryMessage(ParkedMessageEntry msg)
    {
        _actionInProgress = true;
        try
        {
            var request = new ParkedMessageRetryRequest(
                CorrelationId: Guid.NewGuid().ToString("N"),
                SiteId: _selectedSiteId,
                MessageId: msg.MessageId,
                Timestamp: DateTimeOffset.UtcNow);
            var response = await CommunicationService.RetryParkedMessageAsync(_selectedSiteId, request);
            if (response.Success)
            {
                _toast.ShowSuccess($"Message {msg.MessageId[..Math.Min(12, msg.MessageId.Length)]} queued for retry.");
                await FetchPage();
            }
            else
            {
                _toast.ShowError(response.ErrorMessage ?? "Retry failed.");
            }
        }
        catch (Exception ex)
        {
            _toast.ShowError($"Retry failed: {ex.Message}");
        }
        _actionInProgress = false;
    }

    private async Task DiscardMessage(ParkedMessageEntry msg)
    {
        var confirmed = await _confirmDialog.ShowAsync(
            $"Permanently discard message {msg.MessageId[..Math.Min(12, msg.MessageId.Length)]}? This cannot be undone.",
            "Discard Parked Message");
        if (!confirmed) return;

        _actionInProgress = true;
        try
        {
            var request = new ParkedMessageDiscardRequest(
                CorrelationId: Guid.NewGuid().ToString("N"),
                SiteId: _selectedSiteId,
                MessageId: msg.MessageId,
                Timestamp: DateTimeOffset.UtcNow);
            var response = await CommunicationService.DiscardParkedMessageAsync(_selectedSiteId, request);
            if (response.Success)
            {
                _toast.ShowSuccess($"Message {msg.MessageId[..Math.Min(12, msg.MessageId.Length)]} discarded.");
                await FetchPage();
            }
            else
            {
                _toast.ShowError(response.ErrorMessage ?? "Discard failed.");
            }
        }
        catch (Exception ex)
        {
            _toast.ShowError($"Discard failed: {ex.Message}");
        }
        _actionInProgress = false;
    }
}
