@page "/monitoring/audit-log"
@using ScadaLink.Security
@using ScadaLink.Commons.Entities.Audit
@using ScadaLink.Commons.Interfaces.Repositories
@attribute [Authorize(Policy = AuthorizationPolicies.RequireAdmin)]
@inject ICentralUiRepository CentralUiRepository

<div class="container-fluid mt-3">
    <h4 class="mb-3">Audit Log</h4>

    <ToastNotification @ref="_toast" />

    <div class="row mb-3 g-2">
        <div class="col-md-2">
            <label class="form-label small">User</label>
            <input type="text" class="form-control form-control-sm" @bind="_filterUser" placeholder="Username" />
        </div>
        <div class="col-md-2">
            <label class="form-label small">Entity Type</label>
            <input type="text" class="form-control form-control-sm" @bind="_filterEntityType" placeholder="e.g. Template" />
        </div>
        <div class="col-md-2">
            <label class="form-label small">Action</label>
            <input type="text" class="form-control form-control-sm" @bind="_filterAction" placeholder="e.g. Create" />
        </div>
        <div class="col-md-2">
            <label class="form-label small">From</label>
            <input type="datetime-local" class="form-control form-control-sm" @bind="_filterFrom" />
        </div>
        <div class="col-md-2">
            <label class="form-label small">To</label>
            <input type="datetime-local" class="form-control form-control-sm" @bind="_filterTo" />
        </div>
        <div class="col-md-2 d-flex align-items-end">
            <button class="btn btn-primary btn-sm" @onclick="Search" disabled="@_searching">
                @if (_searching) { <span class="spinner-border spinner-border-sm"></span> }
                Search
            </button>
        </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>Timestamp</th>
                    <th>User</th>
                    <th>Action</th>
                    <th>Entity Type</th>
                    <th>Entity ID</th>
                    <th>Entity Name</th>
                    <th>State</th>
                </tr>
            </thead>
            <tbody>
                @if (_entries.Count == 0)
                {
                    <tr><td colspan="7" class="text-muted text-center">No audit entries found.</td></tr>
                }
                @foreach (var entry in _entries)
                {
                    <tr>
                        <td class="small"><TimestampDisplay Value="@entry.Timestamp" /></td>
                        <td class="small">@entry.User</td>
                        <td><span class="badge @GetActionBadge(entry.Action)">@entry.Action</span></td>
                        <td class="small">@entry.EntityType</td>
                        <td class="small"><code>@entry.EntityId</code></td>
                        <td class="small">@entry.EntityName</td>
                        <td>
                            @if (!string.IsNullOrWhiteSpace(entry.AfterStateJson))
                            {
                                <button class="btn btn-outline-info btn-sm py-0 px-1"
                                        @onclick="() => ToggleStateView(entry.Id)">
                                    @(_expandedEntryId == entry.Id ? "Hide" : "View")
                                </button>
                            }
                            else
                            {
                                <span class="text-muted small">—</span>
                            }
                        </td>
                    </tr>
                    @if (_expandedEntryId == entry.Id && !string.IsNullOrWhiteSpace(entry.AfterStateJson))
                    {
                        <tr>
                            <td colspan="7">
                                <pre class="bg-light p-2 rounded small mb-0" style="max-height: 200px; overflow: auto;">@FormatJson(entry.AfterStateJson)</pre>
                            </td>
                        </tr>
                    }
                }
            </tbody>
        </table>

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

@code {
    private string? _filterUser;
    private string? _filterEntityType;
    private string? _filterAction;
    private DateTime? _filterFrom;
    private DateTime? _filterTo;

    private List<AuditLogEntry>? _entries;
    private int _totalCount;
    private int _page = 1;
    private int _pageSize = 50;
    private bool _searching;
    private string? _errorMessage;
    private int? _expandedEntryId;

    private ToastNotification _toast = default!;

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

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

    private async Task FetchPage()
    {
        _searching = true;
        _errorMessage = null;
        try
        {
            var (entries, totalCount) = await CentralUiRepository.GetAuditLogEntriesAsync(
                user: string.IsNullOrWhiteSpace(_filterUser) ? null : _filterUser.Trim(),
                entityType: string.IsNullOrWhiteSpace(_filterEntityType) ? null : _filterEntityType.Trim(),
                action: string.IsNullOrWhiteSpace(_filterAction) ? null : _filterAction.Trim(),
                from: _filterFrom.HasValue ? new DateTimeOffset(_filterFrom.Value, TimeSpan.Zero) : null,
                to: _filterTo.HasValue ? new DateTimeOffset(_filterTo.Value, TimeSpan.Zero) : null,
                page: _page,
                pageSize: _pageSize);

            _entries = entries.ToList();
            _totalCount = totalCount;
        }
        catch (Exception ex)
        {
            _errorMessage = $"Query failed: {ex.Message}";
        }
        _searching = false;
    }

    private void ToggleStateView(int entryId)
    {
        _expandedEntryId = _expandedEntryId == entryId ? null : entryId;
    }

    private static string GetActionBadge(string action) => action switch
    {
        "Create" => "bg-success",
        "Update" => "bg-primary",
        "Delete" => "bg-danger",
        "Deploy" => "bg-info text-dark",
        _ => "bg-secondary"
    };

    private static string FormatJson(string json)
    {
        try
        {
            var doc = System.Text.Json.JsonDocument.Parse(json);
            return System.Text.Json.JsonSerializer.Serialize(doc, new System.Text.Json.JsonSerializerOptions { WriteIndented = true });
        }
        catch
        {
            return json;
        }
    }
}
