@page "/monitoring/event-logs"
@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">
    <div class="d-flex justify-content-between align-items-center mb-3">
        <h4 class="mb-0">Site Event Logs</h4>
        <button class="btn btn-outline-secondary btn-sm"
                type="button"
                data-bs-toggle="collapse"
                data-bs-target="#event-logs-filters"
                aria-expanded="true"
                aria-controls="event-logs-filters">
            Filter options (@ActiveFilterCount active)
        </button>
    </div>

    <ToastNotification @ref="_toast" />

    <div class="collapse show" id="event-logs-filters">
        <div class="row mb-3 g-2 align-items-end">
            <div class="col-md-2">
                <label class="form-label small" for="filter-site">Site</label>
                <select id="filter-site" class="form-select form-select-sm" aria-label="Site" @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">
                <label class="form-label small" for="filter-event-type">Event Type</label>
                <input id="filter-event-type"
                       type="text"
                       class="form-control form-control-sm"
                       aria-label="Event type"
                       @bind="_filterEventType"
                       placeholder="e.g. ScriptError" />
            </div>
            <div class="col-md-1">
                <label class="form-label small" for="filter-severity">Severity</label>
                <select id="filter-severity"
                        class="form-select form-select-sm"
                        aria-label="Severity"
                        @bind="_filterSeverity">
                    <option value="">All</option>
                    <option>Info</option>
                    <option>Warning</option>
                    <option>Error</option>
                </select>
            </div>
            <div class="col-md-2">
                <label class="form-label small" for="filter-from">From</label>
                <input id="filter-from"
                       type="datetime-local"
                       class="form-control form-control-sm"
                       aria-label="From timestamp"
                       @bind="_filterFrom" />
            </div>
            <div class="col-md-2">
                <label class="form-label small" for="filter-to">To</label>
                <input id="filter-to"
                       type="datetime-local"
                       class="form-control form-control-sm"
                       aria-label="To timestamp"
                       @bind="_filterTo" />
            </div>
            <div class="col-md-1">
                <label class="form-label small" for="filter-keyword">Message contains</label>
                <input id="filter-keyword"
                       type="text"
                       class="form-control form-control-sm"
                       aria-label="Message contains"
                       @bind="_filterKeyword" />
            </div>
            <div class="col-md-2">
                <label class="form-label small" for="filter-instance">Instance</label>
                <input id="filter-instance"
                       type="text"
                       class="form-control form-control-sm"
                       aria-label="Instance name"
                       @bind="_filterInstanceName"
                       placeholder="Instance name" />
            </div>
            <div class="col-md-12 d-flex gap-2">
                <button class="btn btn-primary btn-sm" @onclick="Search" disabled="@(string.IsNullOrEmpty(_selectedSiteId) || _searching)">
                    @if (_searching) { <span class="spinner-border spinner-border-sm me-1" role="status"></span> }
                    Search
                </button>
            </div>
        </div>
    </div>

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

    @if (_entries != null)
    {
        <table class="table table-sm table-striped table-hover">
            <thead class="table-dark">
                <tr>
                    <th style="width: 1%;"></th>
                    <th>Timestamp</th>
                    <th>Type</th>
                    <th>Severity</th>
                    <th>Instance</th>
                    <th>Source</th>
                    <th>Message</th>
                </tr>
            </thead>
            <tbody>
                @if (_entries.Count == 0)
                {
                    <tr><td colspan="7" class="text-muted text-center">No events found.</td></tr>
                }
                @for (int i = 0; i < _entries.Count; i++)
                {
                    var idx = i;
                    var entry = _entries[idx];
                    var rowClass = entry.Severity == "Error" ? "table-danger"
                                   : entry.Severity == "Warning" ? "table-warning"
                                   : "";
                    var expanded = _expandedRows.Contains(idx);
                    <tr class="@rowClass">
                        <td>
                            <button class="btn btn-link btn-sm p-0"
                                    @onclick="() => ToggleRow(idx)"
                                    aria-label="@(expanded ? "Hide full message" : "View full message")">
                                @(expanded ? "Hide" : "View")
                            </button>
                        </td>
                        <td class="small"><TimestampDisplay Value="@entry.Timestamp" /></td>
                        <td class="small">@entry.EventType</td>
                        <td>
                            <span class="badge @GetSeverityBadge(entry.Severity)" aria-label="Severity: @entry.Severity">
                                @SeverityGlyph(entry.Severity) @entry.Severity
                            </span>
                        </td>
                        <td class="small">@(entry.InstanceId ?? "—")</td>
                        <td class="small">@entry.Source</td>
                        <td class="small text-truncate" style="max-width: 380px;">@entry.Message</td>
                    </tr>
                    @if (expanded)
                    {
                        <tr class="@rowClass">
                            <td colspan="7">
                                <pre class="small mb-0">@entry.Message</pre>
                            </td>
                        </tr>
                    }
                }
            </tbody>
        </table>

        <div class="d-flex justify-content-between align-items-center">
            <span class="text-muted small">Showing @_entries.Count entries</span>
            <div>
                @if (_hasMore)
                {
                    <button class="btn btn-outline-primary btn-sm" @onclick="LoadMore" disabled="@_searching">Load more</button>
                }
                else if (_entries.Count > 0)
                {
                    <span class="text-muted small">End of results</span>
                }
            </div>
        </div>
    }
</div>

@code {
    private List<Site> _sites = new();
    private string _selectedSiteId = string.Empty;
    private string? _filterEventType;
    private string _filterSeverity = string.Empty;
    private DateTime? _filterFrom;
    private DateTime? _filterTo;
    private string? _filterKeyword;
    private string? _filterInstanceName;

    private List<EventLogEntry>? _entries;
    private bool _hasMore;
    private long? _continuationToken;
    private bool _searching;
    private string? _errorMessage;
    private ToastNotification _toast = default!;
    private readonly HashSet<int> _expandedRows = new();

    private int ActiveFilterCount
    {
        get
        {
            var n = 0;
            if (!string.IsNullOrEmpty(_selectedSiteId)) n++;
            if (!string.IsNullOrWhiteSpace(_filterEventType)) n++;
            if (!string.IsNullOrEmpty(_filterSeverity)) n++;
            if (_filterFrom.HasValue) n++;
            if (_filterTo.HasValue) n++;
            if (!string.IsNullOrWhiteSpace(_filterKeyword)) n++;
            if (!string.IsNullOrWhiteSpace(_filterInstanceName)) n++;
            return n;
        }
    }

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

    private async Task Search()
    {
        _entries = new();
        _continuationToken = null;
        _expandedRows.Clear();
        await FetchPage();
    }

    private async Task LoadMore() => await FetchPage();

    private void ToggleRow(int idx)
    {
        if (!_expandedRows.Add(idx))
        {
            _expandedRows.Remove(idx);
        }
    }

    private async Task FetchPage()
    {
        _searching = true;
        _errorMessage = null;
        try
        {
            var request = new EventLogQueryRequest(
                CorrelationId: Guid.NewGuid().ToString("N"),
                SiteId: _selectedSiteId,
                From: _filterFrom.HasValue ? new DateTimeOffset(_filterFrom.Value, TimeSpan.Zero) : null,
                To: _filterTo.HasValue ? new DateTimeOffset(_filterTo.Value, TimeSpan.Zero) : null,
                EventType: string.IsNullOrWhiteSpace(_filterEventType) ? null : _filterEventType.Trim(),
                Severity: string.IsNullOrWhiteSpace(_filterSeverity) ? null : _filterSeverity,
                InstanceId: string.IsNullOrWhiteSpace(_filterInstanceName) ? null : _filterInstanceName.Trim(),
                KeywordFilter: string.IsNullOrWhiteSpace(_filterKeyword) ? null : _filterKeyword.Trim(),
                ContinuationToken: _continuationToken,
                PageSize: 50,
                Timestamp: DateTimeOffset.UtcNow);

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

            if (response.Success)
            {
                _entries ??= new();
                _entries.AddRange(response.Entries);
                _hasMore = response.HasMore;
                _continuationToken = response.ContinuationToken;
            }
            else
            {
                _errorMessage = response.ErrorMessage ?? "Query failed.";
            }
        }
        catch (Exception ex)
        {
            _errorMessage = $"Query failed: {ex.Message}";
        }
        _searching = false;
    }

    private static string GetSeverityBadge(string severity) => severity switch
    {
        "Error" => "bg-danger",
        "Warning" => "bg-warning text-dark",
        "Info" => "bg-info text-dark",
        _ => "bg-secondary"
    };

    private static string SeverityGlyph(string severity) => severity switch
    {
        "Error" => "⛔",
        "Warning" => "⚠",
        "Info" => "ℹ",
        _ => "•"
    };
}
