namespace DragonISO.App.Services;

// /topology/* route handlers â€” read + apply / restore the machine NDI
// access-manager config so the operator can flip transcoder topology
// without leaving the web UI.
//
//   GET  /topology          â†’ GetTopology
//   POST /topology/apply    â†’ ApplyTopologyAsync
//   POST /topology/restore  â†’ RestoreTopologyAsync
public sealed partial class ControlSurfaceServer
{
    /// <summary>
    /// Report the current NDI machine topology. "mode" is "hidden" when
    /// local senders are confined to the private group (raw Teams sources
    /// invisible to the rest of the LAN), "public" otherwise. Reads the
    /// machine NDI config file directly â€” no caching, so the result
    /// reflects whatever state the file is in right now (including
    /// manual edits).
    /// </summary>
    private object GetTopology()
    {
        try
        {
            var (mode, sends, recvs) = NdiAccessManagerConfig.ReadCurrent();
            return new
            {
                mode,
                senders = sends,
                receivers = recvs,
                configPath = NdiAccessManagerConfig.ConfigPath,
            };
        }
        catch (Exception ex)
        {
            return new { ok = false, error = ex.Message };
        }
    }

    /// <summary>
    /// Apply the transcoder topology: machine senders â†’ <c>Dragon-ISO-input</c>,
    /// receivers â†’ <c>public + Dragon-ISO-input</c>; engine groups updated to
    /// match (discover from Dragon-ISO-input, broadcast on public). Operator
    /// MUST restart Teams afterward for it to read the new NDI config.
    /// </summary>
    private async Task<object> ApplyTopologyAsync()
    {
        var result = NdiAccessManagerConfig.ApplyTranscoderTopology();
        if (!result.Success)
        {
            return new { ok = false, error = result.ErrorMessage, configPath = result.ConfigPath };
        }
        // Mirror what the WPF settings VM does so the engine groups +
        // machine config stay in lockstep.
        var ourGroups = new DragonISO.Engine.Domain.NdiGroupSettings(
            DiscoveryGroups: NdiAccessManagerConfig.TranscoderInputGroup,
            OutputGroups: "public");
        await _controller.SetGroupSettingsAsync(ourGroups, CancellationToken.None);
        return new
        {
            ok = true,
            mode = "hidden",
            backupPath = result.BackupPath,
            note = "Restart Microsoft Teams for the new NDI config to take effect there.",
        };
    }

    /// <summary>
    /// Restore the machine NDI defaults: senders + receivers both on
    /// <c>public</c>. Engine groups go back to null/defaults too. Operator
    /// must restart Teams for it to broadcast on public again.
    /// </summary>
    private async Task<object> RestoreTopologyAsync()
    {
        var result = NdiAccessManagerConfig.RestoreDefaults();
        if (!result.Success)
        {
            return new { ok = false, error = result.ErrorMessage, configPath = result.ConfigPath };
        }
        var ourGroups = new DragonISO.Engine.Domain.NdiGroupSettings(
            DiscoveryGroups: null,
            OutputGroups: null);
        await _controller.SetGroupSettingsAsync(ourGroups, CancellationToken.None);
        return new
        {
            ok = true,
            mode = "public",
            backupPath = result.BackupPath,
            note = "Restart Microsoft Teams for the new NDI config to take effect there.",
        };
    }
}
