@page "/design/external-systems"
@using ScadaLink.Security
@using ScadaLink.Commons.Entities.ExternalSystems
@using ScadaLink.Commons.Entities.Notifications
@using ScadaLink.Commons.Entities.InboundApi
@using ScadaLink.Commons.Interfaces.Repositories
@attribute [Authorize(Policy = AuthorizationPolicies.RequireDesign)]
@inject IExternalSystemRepository ExternalSystemRepository
@inject INotificationRepository NotificationRepository
@inject IInboundApiRepository InboundApiRepository
@inject NavigationManager NavigationManager

<div class="container-fluid mt-3">
    <h4 class="mb-3">Integration Definitions</h4>

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

    @if (_loading)
    {
        <LoadingSpinner IsLoading="true" />
    }
    else if (_errorMessage != null)
    {
        <div class="alert alert-danger">@_errorMessage</div>
    }
    else
    {
        <ul class="nav nav-tabs mb-3">
            <li class="nav-item">
                <button class="nav-link @(_tab == "extsys" ? "active" : "")" @onclick='() => _tab = "extsys"'>
                    External Systems <span class="badge bg-secondary">@_externalSystems.Count</span>
                </button>
            </li>
            <li class="nav-item">
                <button class="nav-link @(_tab == "dbconn" ? "active" : "")" @onclick='() => _tab = "dbconn"'>
                    Database Connections <span class="badge bg-secondary">@_dbConnections.Count</span>
                </button>
            </li>
            <li class="nav-item">
                <button class="nav-link @(_tab == "notif" ? "active" : "")" @onclick='() => _tab = "notif"'>
                    Notification Lists <span class="badge bg-secondary">@_notificationLists.Count</span>
                </button>
            </li>
            <li class="nav-item">
                <button class="nav-link @(_tab == "inbound" ? "active" : "")" @onclick='() => _tab = "inbound"'>
                    Inbound API Methods <span class="badge bg-secondary">@_apiMethods.Count</span>
                </button>
            </li>
        </ul>

        @if (_tab == "extsys") { @RenderExternalSystems() }
        else if (_tab == "dbconn") { @RenderDbConnections() }
        else if (_tab == "notif") { @RenderNotificationLists() @RenderSmtpConfig() }
        else if (_tab == "inbound") { @RenderInboundApiMethods() @RenderApiKeyMethodAssignments() }
    }
</div>

@code {
    private bool _loading = true;
    private string? _errorMessage;
    private string _tab = "extsys";

    // External Systems
    private List<ExternalSystemDefinition> _externalSystems = new();

    // Database Connections
    private List<DatabaseConnectionDefinition> _dbConnections = new();

    // SMTP Configuration
    private List<SmtpConfiguration> _smtpConfigs = new();
    private bool _showSmtpForm;
    private SmtpConfiguration? _editingSmtp;
    private string _smtpHost = "", _smtpFromAddress = "", _smtpAuthType = "OAuth2";
    private int _smtpPort = 587;
    private string? _smtpFormError;

    // API Key list
    private List<ApiKey> _apiKeys = new();

    // Notification Lists
    private List<NotificationList> _notificationLists = new();
    private Dictionary<int, List<NotificationRecipient>> _recipients = new();

    // Inbound API Methods
    private List<ApiMethod> _apiMethods = new();

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

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

    private async Task LoadAllAsync()
    {
        _loading = true;
        try
        {
            _externalSystems = (await ExternalSystemRepository.GetAllExternalSystemsAsync()).ToList();
            _dbConnections = (await ExternalSystemRepository.GetAllDatabaseConnectionsAsync()).ToList();
            _notificationLists = (await NotificationRepository.GetAllNotificationListsAsync()).ToList();

            _recipients.Clear();
            foreach (var list in _notificationLists)
            {
                var recips = await NotificationRepository.GetRecipientsByListIdAsync(list.Id);
                if (recips.Count > 0) _recipients[list.Id] = recips.ToList();
            }

            _apiMethods = (await InboundApiRepository.GetAllApiMethodsAsync()).ToList();
            _smtpConfigs = (await NotificationRepository.GetAllSmtpConfigurationsAsync()).ToList();
            _apiKeys = (await InboundApiRepository.GetAllApiKeysAsync()).ToList();
        }
        catch (Exception ex) { _errorMessage = ex.Message; }
        _loading = false;
    }

    // ==== External Systems ====
    private RenderFragment RenderExternalSystems() => __builder =>
    {
        <div class="d-flex justify-content-between mb-2">
            <h6 class="mb-0">External Systems</h6>
            <button class="btn btn-primary btn-sm" @onclick='() => NavigationManager.NavigateTo("/design/external-systems/create")'>Add</button>
        </div>

        <table class="table table-sm table-striped">
            <thead class="table-dark"><tr><th>Name</th><th>URL</th><th>Auth</th><th>Retries</th><th>Delay</th><th style="width:120px;">Actions</th></tr></thead>
            <tbody>
                @foreach (var es in _externalSystems)
                {
                    <tr>
                        <td>@es.Name</td><td class="small">@es.EndpointUrl</td><td><span class="badge bg-secondary">@es.AuthType</span></td>
                        <td class="small">@es.MaxRetries</td><td class="small">@es.RetryDelay.TotalSeconds s</td>
                        <td>
                            <button class="btn btn-outline-primary btn-sm py-0 px-1 me-1" @onclick='() => NavigationManager.NavigateTo($"/design/external-systems/{es.Id}/edit")'>Edit</button>
                            <button class="btn btn-outline-danger btn-sm py-0 px-1" @onclick="() => DeleteExtSys(es)">Delete</button>
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    };

    private async Task DeleteExtSys(ExternalSystemDefinition es)
    {
        if (!await _confirmDialog.ShowAsync($"Delete '{es.Name}'?", "Delete External System")) return;
        try { await ExternalSystemRepository.DeleteExternalSystemAsync(es.Id); await ExternalSystemRepository.SaveChangesAsync(); _toast.ShowSuccess("Deleted."); await LoadAllAsync(); }
        catch (Exception ex) { _toast.ShowError(ex.Message); }
    }

    // ==== Database Connections ====
    private RenderFragment RenderDbConnections() => __builder =>
    {
        <div class="d-flex justify-content-between mb-2">
            <h6 class="mb-0">Database Connections</h6>
            <button class="btn btn-primary btn-sm" @onclick='() => NavigationManager.NavigateTo("/design/db-connections/create")'>Add</button>
        </div>

        <table class="table table-sm table-striped">
            <thead class="table-dark"><tr><th>Name</th><th>Connection String</th><th>Retries</th><th>Delay</th><th style="width:120px;">Actions</th></tr></thead>
            <tbody>
                @foreach (var dc in _dbConnections)
                {
                    <tr>
                        <td>@dc.Name</td><td class="small text-muted text-truncate" style="max-width:400px;">@dc.ConnectionString</td>
                        <td class="small">@dc.MaxRetries</td><td class="small">@dc.RetryDelay.TotalSeconds s</td>
                        <td>
                            <button class="btn btn-outline-primary btn-sm py-0 px-1 me-1" @onclick='() => NavigationManager.NavigateTo($"/design/db-connections/{dc.Id}/edit")'>Edit</button>
                            <button class="btn btn-outline-danger btn-sm py-0 px-1" @onclick="() => DeleteDbConn(dc)">Delete</button>
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    };

    private async Task DeleteDbConn(DatabaseConnectionDefinition dc)
    {
        if (!await _confirmDialog.ShowAsync($"Delete '{dc.Name}'?", "Delete DB Connection")) return;
        try { await ExternalSystemRepository.DeleteDatabaseConnectionAsync(dc.Id); await ExternalSystemRepository.SaveChangesAsync(); _toast.ShowSuccess("Deleted."); await LoadAllAsync(); }
        catch (Exception ex) { _toast.ShowError(ex.Message); }
    }

    // ==== Notification Lists ====
    private RenderFragment RenderNotificationLists() => __builder =>
    {
        <div class="d-flex justify-content-between mb-2">
            <h6 class="mb-0">Notification Lists</h6>
            <button class="btn btn-primary btn-sm" @onclick='() => NavigationManager.NavigateTo("/design/notification-lists/create")'>Add List</button>
        </div>

        @foreach (var list in _notificationLists)
        {
            <div class="card mb-2">
                <div class="card-header d-flex justify-content-between align-items-center py-2">
                    <strong>@list.Name</strong>
                    <div>
                        <button class="btn btn-outline-primary btn-sm py-0 px-1 me-1" @onclick='() => NavigationManager.NavigateTo($"/design/notification-lists/{list.Id}/edit")'>Edit</button>
                        <button class="btn btn-outline-danger btn-sm py-0 px-1" @onclick="() => DeleteNotifList(list)">Delete</button>
                    </div>
                </div>
                <div class="card-body p-2">
                    @{
                        var recips = _recipients.GetValueOrDefault(list.Id);
                    }
                    @if (recips == null || recips.Count == 0)
                    {
                        <span class="text-muted small">No recipients.</span>
                    }
                    else
                    {
                        @foreach (var r in recips)
                        {
                            <span class="badge bg-light text-dark me-1 mb-1">
                                @r.Name &lt;@r.EmailAddress&gt;
                            </span>
                        }
                    }
                </div>
            </div>
        }
    };

    private async Task DeleteNotifList(NotificationList list)
    {
        if (!await _confirmDialog.ShowAsync($"Delete notification list '{list.Name}'?", "Delete")) return;
        try { await NotificationRepository.DeleteNotificationListAsync(list.Id); await NotificationRepository.SaveChangesAsync(); _toast.ShowSuccess("Deleted."); await LoadAllAsync(); }
        catch (Exception ex) { _toast.ShowError(ex.Message); }
    }

    // ==== Inbound API Methods ====
    private RenderFragment RenderInboundApiMethods() => __builder =>
    {
        <div class="d-flex justify-content-between mb-2">
            <h6 class="mb-0">Inbound API Methods</h6>
            <button class="btn btn-primary btn-sm" @onclick='() => NavigationManager.NavigateTo("/design/api-methods/create")'>Add Method</button>
        </div>

        <table class="table table-sm table-striped">
            <thead class="table-dark"><tr><th>Name</th><th>Timeout</th><th>Script (preview)</th><th style="width:120px;">Actions</th></tr></thead>
            <tbody>
                @foreach (var m in _apiMethods)
                {
                    <tr>
                        <td><code>POST /api/@m.Name</code></td>
                        <td>@m.TimeoutSeconds s</td>
                        <td class="small font-monospace text-truncate" style="max-width:300px;">@m.Script[..Math.Min(60, m.Script.Length)]</td>
                        <td>
                            <button class="btn btn-outline-primary btn-sm py-0 px-1 me-1" @onclick='() => NavigationManager.NavigateTo($"/design/api-methods/{m.Id}/edit")'>Edit</button>
                            <button class="btn btn-outline-danger btn-sm py-0 px-1" @onclick="() => DeleteApiMethod(m)">Delete</button>
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    };

    private async Task DeleteApiMethod(ApiMethod m)
    {
        if (!await _confirmDialog.ShowAsync($"Delete API method '{m.Name}'?", "Delete")) return;
        try { await InboundApiRepository.DeleteApiMethodAsync(m.Id); await InboundApiRepository.SaveChangesAsync(); _toast.ShowSuccess("Deleted."); await LoadAllAsync(); }
        catch (Exception ex) { _toast.ShowError(ex.Message); }
    }

    // ==== SMTP Configuration ====
    private RenderFragment RenderSmtpConfig() => __builder =>
    {
        <hr class="my-3" />
        <div class="d-flex justify-content-between mb-2">
            <h6 class="mb-0">SMTP Configuration</h6>
            @if (_smtpConfigs.Count == 0)
            {
                <button class="btn btn-primary btn-sm" @onclick="ShowSmtpAddForm">Add SMTP Config</button>
            }
        </div>

        @if (_showSmtpForm)
        {
            <div class="card mb-2"><div class="card-body">
                <div class="row g-2 align-items-end">
                    <div class="col-md-3"><label class="form-label small">Host</label><input type="text" class="form-control form-control-sm" @bind="_smtpHost" /></div>
                    <div class="col-md-1"><label class="form-label small">Port</label><input type="number" class="form-control form-control-sm" @bind="_smtpPort" /></div>
                    <div class="col-md-2"><label class="form-label small">Auth Type</label>
                        <select class="form-select form-select-sm" @bind="_smtpAuthType"><option>OAuth2</option><option>Basic</option></select></div>
                    <div class="col-md-3"><label class="form-label small">From Address</label><input type="email" class="form-control form-control-sm" @bind="_smtpFromAddress" /></div>
                    <div class="col-md-3">
                        <button class="btn btn-success btn-sm me-1" @onclick="SaveSmtpConfig">Save</button>
                        <button class="btn btn-outline-secondary btn-sm" @onclick="() => _showSmtpForm = false">Cancel</button></div>
                </div>
                @if (_smtpFormError != null) { <div class="text-danger small mt-1">@_smtpFormError</div> }
            </div></div>
        }

        @foreach (var smtp in _smtpConfigs)
        {
            <div class="card mb-2">
                <div class="card-body py-2">
                    <div class="d-flex justify-content-between align-items-center">
                        <span class="small">
                            <strong>@smtp.Host</strong>:@smtp.Port |
                            Auth: <span class="badge bg-secondary">@smtp.AuthType</span> |
                            From: @smtp.FromAddress
                        </span>
                        <button class="btn btn-outline-primary btn-sm py-0 px-1" @onclick="() => { _editingSmtp = smtp; _smtpHost = smtp.Host; _smtpPort = smtp.Port; _smtpAuthType = smtp.AuthType; _smtpFromAddress = smtp.FromAddress; _showSmtpForm = true; }">Edit</button>
                    </div>
                </div>
            </div>
        }
    };

    private void ShowSmtpAddForm()
    {
        _showSmtpForm = true;
        _editingSmtp = null;
        _smtpHost = string.Empty;
        _smtpPort = 587;
        _smtpAuthType = "OAuth2";
        _smtpFromAddress = string.Empty;
        _smtpFormError = null;
    }

    private async Task SaveSmtpConfig()
    {
        _smtpFormError = null;
        if (string.IsNullOrWhiteSpace(_smtpHost) || string.IsNullOrWhiteSpace(_smtpFromAddress)) { _smtpFormError = "Host and From Address required."; return; }
        try
        {
            if (_editingSmtp != null)
            {
                _editingSmtp.Host = _smtpHost.Trim();
                _editingSmtp.Port = _smtpPort;
                _editingSmtp.AuthType = _smtpAuthType;
                _editingSmtp.FromAddress = _smtpFromAddress.Trim();
                await NotificationRepository.UpdateSmtpConfigurationAsync(_editingSmtp);
            }
            else
            {
                var smtp = new SmtpConfiguration(_smtpHost.Trim(), _smtpAuthType, _smtpFromAddress.Trim()) { Port = _smtpPort };
                await NotificationRepository.AddSmtpConfigurationAsync(smtp);
            }
            await NotificationRepository.SaveChangesAsync();
            _showSmtpForm = false;
            _toast.ShowSuccess("SMTP configuration saved.");
            await LoadAllAsync();
        }
        catch (Exception ex) { _smtpFormError = ex.Message; }
    }

    // ==== API Key → Method Assignments ====
    private RenderFragment RenderApiKeyMethodAssignments() => __builder =>
    {
        <hr class="my-3" />
        <div class="d-flex justify-content-between mb-2">
            <h6 class="mb-0">API Keys</h6>
        </div>

        <table class="table table-sm table-striped">
            <thead class="table-dark"><tr><th>Key Name</th><th>Enabled</th><th style="width:120px;">Actions</th></tr></thead>
            <tbody>
                @foreach (var key in _apiKeys)
                {
                    <tr>
                        <td>@key.Name</td>
                        <td><span class="badge @(key.IsEnabled ? "bg-success" : "bg-secondary")">@(key.IsEnabled ? "Enabled" : "Disabled")</span></td>
                        <td>
                            <button class="btn btn-outline-primary btn-sm py-0 px-1" @onclick="() => ToggleApiKeyEnabled(key)">
                                @(key.IsEnabled ? "Disable" : "Enable")
                            </button>
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    };

    private async Task ToggleApiKeyEnabled(ApiKey key)
    {
        try
        {
            key.IsEnabled = !key.IsEnabled;
            await InboundApiRepository.UpdateApiKeyAsync(key);
            await InboundApiRepository.SaveChangesAsync();
            _toast.ShowSuccess($"API key '{key.Name}' {(key.IsEnabled ? "enabled" : "disabled")}.");
        }
        catch (Exception ex) { _toast.ShowError(ex.Message); }
    }
}
