@page "/admin/sites"
@using ScadaLink.Security
@using ScadaLink.Commons.Entities.Sites
@using ScadaLink.Commons.Interfaces.Repositories
@using ScadaLink.Communication
@using ScadaLink.DeploymentManager
@attribute [Authorize(Policy = AuthorizationPolicies.RequireAdmin)]
@inject ISiteRepository SiteRepository
@inject ArtifactDeploymentService ArtifactDeploymentService
@inject CommunicationService CommunicationService
@inject AuthenticationStateProvider AuthStateProvider
@inject NavigationManager NavigationManager

<div class="container-fluid mt-3">
    <div class="d-flex justify-content-between align-items-center mb-3">
        <h4 class="mb-0">Site Management</h4>
        <div>
            <button class="btn btn-outline-warning btn-sm me-1" @onclick="DeployArtifactsToAllSites"
                    disabled="@_deploying">
                @if (_deploying)
                {
                    <span class="spinner-border spinner-border-sm me-1" role="status"></span>
                }
                Deploy Artifacts to All Sites
            </button>
            <button class="btn btn-primary btn-sm" @onclick='() => NavigationManager.NavigateTo("/admin/sites/create")'>Add Site</button>
        </div>
    </div>

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

    @if (_loading)
    {
        <LoadingSpinner IsLoading="true" />
    }
    else if (_errorMessage != null)
    {
        <div class="alert alert-danger">@_errorMessage</div>
    }
    else
    {
        <table class="table table-sm table-striped table-hover">
            <thead class="table-dark">
                <tr>
                    <th>ID</th>
                    <th>Name</th>
                    <th>Identifier</th>
                    <th>Description</th>
                    <th>Node A</th>
                    <th>Node B</th>
                    <th>gRPC Node A</th>
                    <th>gRPC Node B</th>
                    <th>Data Connections</th>
                    <th style="width: 260px;">Actions</th>
                </tr>
            </thead>
            <tbody>
                @if (_sites.Count == 0)
                {
                    <tr>
                        <td colspan="10" class="text-muted text-center">No sites configured.</td>
                    </tr>
                }
                @foreach (var site in _sites)
                {
                    <tr>
                        <td>@site.Id</td>
                        <td>@site.Name</td>
                        <td><code>@site.SiteIdentifier</code></td>
                        <td class="text-muted small">@(site.Description ?? "—")</td>
                        <td class="small text-truncate" style="max-width: 200px;" title="@site.NodeAAddress">@(site.NodeAAddress ?? "—")</td>
                        <td class="small text-truncate" style="max-width: 200px;" title="@site.NodeBAddress">@(site.NodeBAddress ?? "—")</td>
                        <td class="small text-truncate" style="max-width: 200px;" title="@site.GrpcNodeAAddress">@(site.GrpcNodeAAddress ?? "—")</td>
                        <td class="small text-truncate" style="max-width: 200px;" title="@site.GrpcNodeBAddress">@(site.GrpcNodeBAddress ?? "—")</td>
                        <td>
                            @{
                                var conns = _siteConnections.GetValueOrDefault(site.Id);
                            }
                            @if (conns != null && conns.Count > 0)
                            {
                                @foreach (var conn in conns)
                                {
                                    <span class="badge bg-info text-dark me-1">@conn.Name (@conn.Protocol)</span>
                                }
                            }
                            else
                            {
                                <span class="text-muted small">None</span>
                            }
                        </td>
                        <td>
                            <button class="btn btn-outline-primary btn-sm py-0 px-1 me-1"
                                    @onclick='() => NavigationManager.NavigateTo($"/admin/sites/{site.Id}/edit")'>Edit</button>
                            <button class="btn btn-outline-warning btn-sm py-0 px-1 me-1"
                                    @onclick="() => DeployArtifacts(site)"
                                    disabled="@_deploying">Deploy Artifacts</button>
                            <button class="btn btn-outline-danger btn-sm py-0 px-1"
                                    @onclick="() => DeleteSite(site)">Delete</button>
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    }
</div>

@code {
    private async Task<string> GetCurrentUserAsync()
    {
        var authState = await AuthStateProvider.GetAuthenticationStateAsync();
        return authState.User.FindFirst("Username")?.Value ?? "unknown";
    }

    private List<Site> _sites = new();
    private Dictionary<int, List<DataConnection>> _siteConnections = new();
    private bool _loading = true;
    private string? _errorMessage;

    private bool _deploying;

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

    protected override async Task OnInitializedAsync()
    {
        await LoadDataAsync();
    }

    private async Task LoadDataAsync()
    {
        _loading = true;
        _errorMessage = null;
        try
        {
            _sites = (await SiteRepository.GetAllSitesAsync()).ToList();
            _siteConnections.Clear();
            foreach (var site in _sites)
            {
                var connections = await SiteRepository.GetDataConnectionsBySiteIdAsync(site.Id);
                if (connections.Count > 0)
                {
                    _siteConnections[site.Id] = connections.ToList();
                }
            }
        }
        catch (Exception ex)
        {
            _errorMessage = $"Failed to load sites: {ex.Message}";
        }
        _loading = false;
    }

    private async Task DeleteSite(Site site)
    {
        var confirmed = await _confirmDialog.ShowAsync(
            $"Delete site '{site.Name}' ({site.SiteIdentifier})? This cannot be undone.",
            "Delete Site");

        if (!confirmed) return;

        try
        {
            await SiteRepository.DeleteSiteAsync(site.Id);
            await SiteRepository.SaveChangesAsync();
            CommunicationService.RefreshSiteAddresses();
            _toast.ShowSuccess($"Site '{site.Name}' deleted.");
            await LoadDataAsync();
        }
        catch (Exception ex)
        {
            _toast.ShowError($"Delete failed: {ex.Message}");
        }
    }

    private async Task DeployArtifacts(Site site)
    {
        _deploying = true;
        try
        {
            var user = await GetCurrentUserAsync();
            var result = await ArtifactDeploymentService.RetryForSiteAsync(
                site.Id, site.SiteIdentifier, user);

            if (result.IsSuccess)
                _toast.ShowSuccess($"Artifacts deployed to '{site.Name}'.");
            else
                _toast.ShowError($"Deploy to '{site.Name}' failed: {result.Error}");
        }
        catch (Exception ex)
        {
            _toast.ShowError($"Deploy to '{site.Name}' failed: {ex.Message}");
        }
        finally
        {
            _deploying = false;
        }
    }

    private async Task DeployArtifactsToAllSites()
    {
        _deploying = true;
        try
        {
            var user = await GetCurrentUserAsync();
            var result = await ArtifactDeploymentService.DeployToAllSitesAsync(user);

            if (result.IsSuccess)
            {
                var summary = result.Value!;
                _toast.ShowSuccess(
                    $"Artifacts deployed: {summary.SuccessCount} succeeded, {summary.FailureCount} failed.");
            }
            else
            {
                _toast.ShowError($"Artifact deployment failed: {result.Error}");
            }
        }
        catch (Exception ex)
        {
            _toast.ShowError($"Artifact deployment failed: {ex.Message}");
        }
        finally
        {
            _deploying = false;
        }
    }
}
