using System.Globalization;
using System.Text.Json;
using MBN_STOCK_WEBVIEW.Infrastructure;
using MMoneyCoderSharp.Data;

namespace MBN_STOCK_WEBVIEW;

public sealed partial class MainWindow
{
    private const string OperatorCatalogQuarantineMessage =
        "A theme/expert database write result could not be confirmed. Restart the app and reconcile the database before another catalog write.";
    private const decimal OperatorCatalogMaximumWebSafeInteger = 9_007_199_254_740_991m;

    private readonly SemaphoreSlim _operatorCatalogWriteGate = new(1, 1);
    private readonly object _operatorCatalogReadLanesGate = new();
    private readonly Dictionary<string, OperatorCatalogReadRequest> _operatorCatalogReadLanes =
        new(StringComparer.Ordinal);
    private IThemeCatalogPersistenceService? _themeCatalogPersistenceService;
    private IExpertCatalogPersistenceService? _expertCatalogPersistenceService;
    private IStockMasterIdentityValidationService? _stockMasterIdentityValidationService;
    private IOperatorCatalogSchemaValidationService? _operatorCatalogSchemaValidationService;
    private CancellationTokenSource? _operatorCatalogWriteCancellation;
    private string? _operatorCatalogInitializationError;
    private string? _operatorCatalogWriteQuarantineMessage;
    private int _operatorCatalogRuntimeState;
    private int _operatorCatalogWriteInFlight;
    private int _operatorCatalogWriteQuarantined;
    private int _operatorCatalogBrowserGeneration;

    /// <summary>
    /// Root integration hook. It is safe to call after InitializeDatabaseRuntime;
    /// request handlers also call it lazily so a missing optional eager call fails
    /// closed rather than dereferencing an uninitialized service.
    /// </summary>
    private void InitializeOperatorCatalogRuntime()
    {
        if (Volatile.Read(ref _operatorCatalogRuntimeState) != 0)
        {
            return;
        }

        var runtime = _databaseRuntime;
        if (runtime is null ||
            Interlocked.CompareExchange(ref _operatorCatalogRuntimeState, 1, 0) != 0)
        {
            return;
        }

        try
        {
            var mutationExecutor = new OperatorCatalogMutationExecutor(
                runtime.ConnectionFactory,
                runtime.Options.Resilience);
            _themeCatalogPersistenceService = new LegacyThemeCatalogPersistenceService(
                runtime.Executor,
                mutationExecutor);
            _expertCatalogPersistenceService = new LegacyExpertCatalogPersistenceService(
                runtime.Executor,
                mutationExecutor);
            _stockMasterIdentityValidationService =
                new LegacyStockMasterIdentityValidationService(runtime.Executor);
            _operatorCatalogSchemaValidationService =
                new LegacyOperatorCatalogSchemaValidationService(runtime.Executor);
        }
        catch
        {
            _themeCatalogPersistenceService = null;
            _expertCatalogPersistenceService = null;
            _stockMasterIdentityValidationService = null;
            _operatorCatalogSchemaValidationService = null;
            _operatorCatalogInitializationError =
                "The theme/expert database boundary could not be initialized.";
            Volatile.Write(ref _operatorCatalogRuntimeState, -1);
        }
    }

    /// <summary>
    /// Root WebMessage switch hook. Return true means the request type belongs to
    /// this boundary, including malformed payloads which receive a correlated
    /// INVALID_REQUEST response here.
    /// </summary>
    private bool TryHandleOperatorCatalogRequest(string? requestType, JsonElement payload)
    {
        switch (requestType)
        {
            case "request-theme-catalog-list":
                _ = HandleThemeCatalogListRequestAsync(payload);
                return true;
            case "request-expert-catalog-list":
                _ = HandleExpertCatalogListRequestAsync(payload);
                return true;
            case "request-operator-catalog-schema":
                _ = HandleOperatorCatalogSchemaRequestAsync(payload);
                return true;
            case "request-theme-catalog-next-code":
                _ = HandleThemeCatalogNextCodeRequestAsync(payload);
                return true;
            case "request-expert-catalog-next-code":
                _ = HandleExpertCatalogNextCodeRequestAsync(payload);
                return true;
            case "create-theme-catalog":
                _ = HandleThemeCatalogCreateRequestAsync(payload);
                return true;
            case "replace-theme-catalog":
                _ = HandleThemeCatalogReplaceRequestAsync(payload);
                return true;
            case "delete-theme-catalog":
                _ = HandleThemeCatalogDeleteRequestAsync(payload);
                return true;
            case "create-expert-catalog":
                _ = HandleExpertCatalogCreateRequestAsync(payload);
                return true;
            case "replace-expert-catalog":
                _ = HandleExpertCatalogReplaceRequestAsync(payload);
                return true;
            case "delete-expert-catalog":
                _ = HandleExpertCatalogDeleteRequestAsync(payload);
                return true;
            default:
                return false;
        }
    }

    private async Task HandleThemeCatalogListRequestAsync(JsonElement payload)
    {
        if (!TryParseThemeCatalogListRequest(
                payload,
                out var requestId,
                out var query,
                out var nxtSession,
                out var maximumResults))
        {
            PostOperatorCatalogInvalidRequest(
                SafeOperatorCatalogRequestId(payload),
                "theme",
                "list");
            return;
        }

        InitializeOperatorCatalogRuntime();
        var service = _themeSelectionService;
        if (service is null)
        {
            PostOperatorCatalogUnavailable(requestId, "theme", "list");
            return;
        }

        await ExecuteOperatorCatalogReadAsync(
            requestId,
            "theme",
            "list",
            async cancellationToken =>
            {
                var result = await service.SearchAsync(
                    query,
                    nxtSession,
                    maximumResults,
                    cancellationToken);
                cancellationToken.ThrowIfCancellationRequested();
                return new OperatorCatalogBridgeReply(
                    "theme-catalog-list-results",
                    new
                    {
                        requestId,
                        query = result.Query,
                        nxtSession = ToWireValue(result.NxtSession),
                        result.RetrievedAt,
                        totalRowCount = result.Items.Count,
                        truncated = result.IsTruncated,
                        canMutate = CanMutateThemeCatalog(),
                        writeQuarantined = IsOperatorCatalogWriteQuarantined(),
                        results = result.Items.Select(item => new
                        {
                            market = ToWireValue(item.Identity.Market),
                            session = ToWireValue(item.Identity.Session),
                            themeCode = item.Identity.ThemeCode,
                            themeTitle = item.Identity.ThemeTitle,
                            source = ToWireValue(item.Source)
                        }).ToArray()
                    });
            });
    }

    private async Task HandleExpertCatalogListRequestAsync(JsonElement payload)
    {
        if (!TryParseExpertCatalogListRequest(
                payload,
                out var requestId,
                out var query,
                out var maximumResults))
        {
            PostOperatorCatalogInvalidRequest(
                SafeOperatorCatalogRequestId(payload),
                "expert",
                "list");
            return;
        }

        InitializeOperatorCatalogRuntime();
        var service = _expertSelectionService;
        if (service is null)
        {
            PostOperatorCatalogUnavailable(requestId, "expert", "list");
            return;
        }

        await ExecuteOperatorCatalogReadAsync(
            requestId,
            "expert",
            "list",
            async cancellationToken =>
            {
                var result = await service.SearchAsync(
                    query,
                    maximumResults,
                    cancellationToken);
                cancellationToken.ThrowIfCancellationRequested();
                return new OperatorCatalogBridgeReply(
                    "expert-catalog-list-results",
                    new
                    {
                        requestId,
                        query = result.Query,
                        result.RetrievedAt,
                        totalRowCount = result.Items.Count,
                        truncated = result.IsTruncated,
                        canMutate = CanMutateExpertCatalog(),
                        writeQuarantined = IsOperatorCatalogWriteQuarantined(),
                        results = result.Items.Select(item => new
                        {
                            expertCode = item.Identity.ExpertCode,
                            expertName = item.Identity.ExpertName,
                            source = ToWireValue(item.Source)
                        }).ToArray()
                    });
            });
    }

    private async Task HandleOperatorCatalogSchemaRequestAsync(JsonElement payload)
    {
        if (!TryParseOperatorCatalogRequestIdOnly(payload, out var requestId))
        {
            PostOperatorCatalogInvalidRequest(
                SafeOperatorCatalogRequestId(payload),
                "catalog",
                "schemaPreflight");
            return;
        }

        InitializeOperatorCatalogRuntime();
        var service = _operatorCatalogSchemaValidationService;
        if (service is null)
        {
            PostOperatorCatalogUnavailable(
                requestId,
                "catalog",
                "schemaPreflight");
            return;
        }

        await ExecuteOperatorCatalogReadAsync(
            requestId,
            "catalog",
            "schemaPreflight",
            async cancellationToken =>
            {
                var result = await service.ValidateAsync(cancellationToken);
                cancellationToken.ThrowIfCancellationRequested();
                return new OperatorCatalogBridgeReply(
                    "operator-catalog-schema-results",
                    new
                    {
                        requestId,
                        result.ValidatedAt,
                        validatedSources = result.ValidatedSources
                            .Select(ToWireValue)
                            .ToArray(),
                        themeCanMutate = CanMutateThemeCatalog(),
                        expertCanMutate = CanMutateExpertCatalog(),
                        writeQuarantined = IsOperatorCatalogWriteQuarantined()
                    });
            });
    }

    private async Task HandleThemeCatalogNextCodeRequestAsync(JsonElement payload)
    {
        if (!TryParseThemeCatalogNextCodeRequest(
                payload,
                out var requestId,
                out var market))
        {
            PostOperatorCatalogInvalidRequest(
                SafeOperatorCatalogRequestId(payload),
                "theme",
                "nextCode");
            return;
        }

        InitializeOperatorCatalogRuntime();
        var service = _themeCatalogPersistenceService;
        if (service is null)
        {
            PostOperatorCatalogUnavailable(requestId, "theme", "nextCode");
            return;
        }

        await ExecuteOperatorCatalogReadAsync(
            requestId,
            "theme",
            "nextCode",
            async cancellationToken =>
            {
                var code = await service.SuggestNextCodeAsync(market, cancellationToken);
                cancellationToken.ThrowIfCancellationRequested();
                return new OperatorCatalogBridgeReply(
                    "theme-catalog-next-code-results",
                    new
                    {
                        requestId,
                        market = ToWireValue(market),
                        themeCode = code,
                        canMutate = CanMutateThemeCatalog(),
                        writeQuarantined = IsOperatorCatalogWriteQuarantined()
                    });
            });
    }

    private async Task HandleExpertCatalogNextCodeRequestAsync(JsonElement payload)
    {
        if (!TryParseOperatorCatalogRequestIdOnly(payload, out var requestId))
        {
            PostOperatorCatalogInvalidRequest(
                SafeOperatorCatalogRequestId(payload),
                "expert",
                "nextCode");
            return;
        }

        InitializeOperatorCatalogRuntime();
        var service = _expertCatalogPersistenceService;
        if (service is null)
        {
            PostOperatorCatalogUnavailable(requestId, "expert", "nextCode");
            return;
        }

        await ExecuteOperatorCatalogReadAsync(
            requestId,
            "expert",
            "nextCode",
            async cancellationToken =>
            {
                var code = await service.SuggestNextCodeAsync(cancellationToken);
                cancellationToken.ThrowIfCancellationRequested();
                return new OperatorCatalogBridgeReply(
                    "expert-catalog-next-code-results",
                    new
                    {
                        requestId,
                        expertCode = code,
                        canMutate = CanMutateExpertCatalog(),
                        writeQuarantined = IsOperatorCatalogWriteQuarantined()
                    });
            });
    }

    private async Task HandleThemeCatalogCreateRequestAsync(JsonElement payload)
    {
        if (!TryParseThemeCatalogCreateRequest(
                payload,
                out var requestId,
                out var definition))
        {
            PostOperatorCatalogInvalidRequest(
                SafeOperatorCatalogRequestId(payload),
                "theme",
                "create");
            return;
        }

        InitializeOperatorCatalogRuntime();
        var service = _themeCatalogPersistenceService;
        var identityValidation = _stockMasterIdentityValidationService;
        await ExecuteOperatorCatalogWriteAsync(
            requestId,
            "theme",
            "create",
            definition.ThemeCode,
            service?.CanMutate == true && identityValidation is not null,
            async cancellationToken =>
            {
                _ = await identityValidation!.ValidateThemeItemsAsync(
                    definition.Items,
                    cancellationToken);
            },
            cancellationToken => service!.CreateAsync(definition, cancellationToken));
    }

    private async Task HandleThemeCatalogReplaceRequestAsync(JsonElement payload)
    {
        if (!TryParseThemeCatalogReplaceRequest(
                payload,
                out var requestId,
                out var expectedIdentity,
                out var newTitle,
                out var items))
        {
            PostOperatorCatalogInvalidRequest(
                SafeOperatorCatalogRequestId(payload),
                "theme",
                "replace");
            return;
        }

        InitializeOperatorCatalogRuntime();
        var service = _themeCatalogPersistenceService;
        var identityValidation = _stockMasterIdentityValidationService;
        await ExecuteOperatorCatalogWriteAsync(
            requestId,
            "theme",
            "replace",
            expectedIdentity.ThemeCode,
            service?.CanMutate == true && identityValidation is not null,
            async cancellationToken =>
            {
                _ = await identityValidation!.ValidateThemeItemsAsync(
                    items,
                    cancellationToken);
            },
            cancellationToken => service!.ReplaceAsync(
                expectedIdentity,
                newTitle,
                items,
                cancellationToken));
    }

    private async Task HandleThemeCatalogDeleteRequestAsync(JsonElement payload)
    {
        if (!TryParseThemeCatalogDeleteRequest(
                payload,
                out var requestId,
                out var identity))
        {
            PostOperatorCatalogInvalidRequest(
                SafeOperatorCatalogRequestId(payload),
                "theme",
                "delete");
            return;
        }

        InitializeOperatorCatalogRuntime();
        var service = _themeCatalogPersistenceService;
        await ExecuteOperatorCatalogWriteAsync(
            requestId,
            "theme",
            "delete",
            identity.ThemeCode,
            service?.CanMutate == true,
            validationBody: null,
            cancellationToken => service!.DeleteAsync(identity, cancellationToken));
    }

    private async Task HandleExpertCatalogCreateRequestAsync(JsonElement payload)
    {
        if (!TryParseExpertCatalogCreateRequest(
                payload,
                out var requestId,
                out var definition))
        {
            PostOperatorCatalogInvalidRequest(
                SafeOperatorCatalogRequestId(payload),
                "expert",
                "create");
            return;
        }

        InitializeOperatorCatalogRuntime();
        var service = _expertCatalogPersistenceService;
        var identityValidation = _stockMasterIdentityValidationService;
        await ExecuteOperatorCatalogWriteAsync(
            requestId,
            "expert",
            "create",
            definition.Identity.ExpertCode,
            service?.CanMutate == true && identityValidation is not null,
            async cancellationToken =>
            {
                _ = await identityValidation!.ValidateExpertRecommendationsAsync(
                    definition.Recommendations,
                    cancellationToken);
            },
            cancellationToken => service!.CreateAsync(definition, cancellationToken));
    }

    private async Task HandleExpertCatalogReplaceRequestAsync(JsonElement payload)
    {
        if (!TryParseExpertCatalogReplaceRequest(
                payload,
                out var requestId,
                out var expectedIdentity,
                out var newName,
                out var recommendations))
        {
            PostOperatorCatalogInvalidRequest(
                SafeOperatorCatalogRequestId(payload),
                "expert",
                "replace");
            return;
        }

        InitializeOperatorCatalogRuntime();
        var service = _expertCatalogPersistenceService;
        var identityValidation = _stockMasterIdentityValidationService;
        await ExecuteOperatorCatalogWriteAsync(
            requestId,
            "expert",
            "replace",
            expectedIdentity.ExpertCode,
            service?.CanMutate == true && identityValidation is not null,
            async cancellationToken =>
            {
                _ = await identityValidation!.ValidateExpertRecommendationsAsync(
                    recommendations,
                    cancellationToken);
            },
            cancellationToken => service!.ReplaceAsync(
                expectedIdentity,
                newName,
                recommendations,
                cancellationToken));
    }

    private async Task HandleExpertCatalogDeleteRequestAsync(JsonElement payload)
    {
        if (!TryParseExpertCatalogDeleteRequest(
                payload,
                out var requestId,
                out var identity))
        {
            PostOperatorCatalogInvalidRequest(
                SafeOperatorCatalogRequestId(payload),
                "expert",
                "delete");
            return;
        }

        InitializeOperatorCatalogRuntime();
        var service = _expertCatalogPersistenceService;
        await ExecuteOperatorCatalogWriteAsync(
            requestId,
            "expert",
            "delete",
            identity.ExpertCode,
            service?.CanMutate == true,
            validationBody: null,
            cancellationToken => service!.DeleteAsync(identity, cancellationToken));
    }

    private async Task ExecuteOperatorCatalogReadAsync(
        string requestId,
        string entity,
        string operation,
        Func<CancellationToken, Task<OperatorCatalogBridgeReply>> operationBody)
    {
        var requestCancellation = CancellationTokenSource.CreateLinkedTokenSource(
            _lifetimeCancellation.Token);
        var requestToken = requestCancellation.Token;
        var browserGeneration = Volatile.Read(ref _operatorCatalogBrowserGeneration);
        var request = new OperatorCatalogReadRequest(
            $"{entity}:{operation}",
            requestId,
            entity,
            operation,
            browserGeneration,
            requestCancellation);
        RegisterOperatorCatalogRead(request);
        var databaseActivityEntered = false;

        try
        {
            if (Volatile.Read(ref _playoutCommandInFlight) != 0)
            {
                requestCancellation.Cancel();
                PostOperatorCatalogReadCancellationIfCurrent(
                    request,
                    "PLAYOUT_PRIORITY",
                    "The catalog read was canceled because playout has database priority.");
                return;
            }

            await _databaseActivityGate.WaitAsync(requestToken);
            databaseActivityEntered = true;
            requestToken.ThrowIfCancellationRequested();
            if (Volatile.Read(ref _playoutCommandInFlight) != 0)
            {
                requestCancellation.Cancel();
                PostOperatorCatalogReadCancellationIfCurrent(
                    request,
                    "PLAYOUT_PRIORITY",
                    "The catalog read was canceled because playout has database priority.");
                return;
            }

            if (browserGeneration != Volatile.Read(ref _operatorCatalogBrowserGeneration))
            {
                requestCancellation.Cancel();
                return;
            }

            var reply = await operationBody(requestToken);
            requestToken.ThrowIfCancellationRequested();
            if (browserGeneration != Volatile.Read(ref _operatorCatalogBrowserGeneration) ||
                !TryCompleteOperatorCatalogReadIfCurrent(request))
            {
                return;
            }

            PostMessage(reply.MessageType, reply.Payload);
        }
        catch (OperationCanceledException) when (requestToken.IsCancellationRequested)
        {
            PostOperatorCatalogReadCancellationIfCurrent(
                request,
                "PLAYOUT_PRIORITY",
                "The catalog read was canceled because playout has database priority.");
        }
        catch (DatabaseOperationException) when (requestToken.IsCancellationRequested)
        {
            PostOperatorCatalogReadCancellationIfCurrent(
                request,
                "PLAYOUT_PRIORITY",
                "The catalog read was canceled because playout has database priority.");
        }
        catch (Exception) when (requestToken.IsCancellationRequested)
        {
            PostOperatorCatalogReadCancellationIfCurrent(
                request,
                "PLAYOUT_PRIORITY",
                "The catalog read was canceled because playout has database priority.");
        }
        catch (ArgumentException)
        {
            PostOperatorCatalogReadErrorIfCurrent(
                request,
                "INVALID_REQUEST",
                "The theme/expert catalog request is invalid.",
                retryable: false);
        }
        catch (ThemeSelectionDataException)
        {
            PostOperatorCatalogReadErrorIfCurrent(
                request,
                "INVALID_DATA",
                "Theme catalog data is ambiguous or invalid.",
                retryable: false);
        }
        catch (ExpertSelectionDataException)
        {
            PostOperatorCatalogReadErrorIfCurrent(
                request,
                "INVALID_DATA",
                "Expert catalog data is ambiguous or invalid.",
                retryable: false);
        }
        catch (OperatorCatalogSchemaException)
        {
            PostOperatorCatalogReadErrorIfCurrent(
                request,
                "INVALID_SCHEMA",
                "The theme/expert database schema does not match the migrated contract.",
                retryable: false);
        }
        catch (DatabaseOperationException exception)
        {
            PostOperatorCatalogReadErrorIfCurrent(
                request,
                "DATABASE_ERROR",
                exception.Message,
                retryable: true);
            _ = PostDatabaseStatusAsync(_lifetimeCancellation.Token);
        }
        catch
        {
            PostOperatorCatalogReadErrorIfCurrent(
                request,
                "DATABASE_ERROR",
                "The theme/expert database read failed.",
                retryable: true);
            _ = PostDatabaseStatusAsync(_lifetimeCancellation.Token);
        }
        finally
        {
            if (databaseActivityEntered)
            {
                _databaseActivityGate.Release();
            }

            ReleaseOperatorCatalogRead(request);
            requestCancellation.Dispose();
        }
    }

    private async Task ExecuteOperatorCatalogWriteAsync(
        string requestId,
        string entity,
        string operation,
        string identityCode,
        bool canMutate,
        Func<CancellationToken, Task>? validationBody,
        Func<CancellationToken, Task<OperatorCatalogMutationReceipt>> operationBody)
    {
        if (!canMutate)
        {
            PostOperatorCatalogUnavailable(requestId, entity, operation, identityCode);
            return;
        }

        if (IsOperatorCatalogWriteQuarantined())
        {
            PostOperatorCatalogQuarantined(requestId, entity, operation, identityCode);
            return;
        }

        if (!await _operatorCatalogWriteGate.WaitAsync(0))
        {
            PostOperatorCatalogError(
                requestId,
                entity,
                operation,
                identityCode,
                "WRITE_BUSY",
                "Another theme/expert write is already running.",
                retryable: false,
                outcomeUnknown: false);
            return;
        }

        var playoutGateEntered = false;
        var databaseActivityEntered = false;
        var mutationDispatched = false;
        var requestCancellation = CancellationTokenSource.CreateLinkedTokenSource(
            _lifetimeCancellation.Token);
        var requestToken = requestCancellation.Token;
        var browserGeneration = Volatile.Read(ref _operatorCatalogBrowserGeneration);
        Volatile.Write(ref _operatorCatalogWriteCancellation, requestCancellation);

        try
        {
            playoutGateEntered = await _playoutCommandGate.WaitAsync(0, requestToken);
            if (!playoutGateEntered)
            {
                PostOperatorCatalogPlayoutActive(
                    requestId,
                    entity,
                    operation,
                    identityCode);
                return;
            }

            if (!CanStartOperatorCatalogWrite())
            {
                PostOperatorCatalogPlayoutActive(
                    requestId,
                    entity,
                    operation,
                    identityCode);
                return;
            }

            databaseActivityEntered = await _databaseActivityGate.WaitAsync(0, requestToken);
            if (!databaseActivityEntered)
            {
                PostOperatorCatalogError(
                    requestId,
                    entity,
                    operation,
                    identityCode,
                    "DATABASE_BUSY",
                    "The database is busy. Refresh before making a new explicit write request.",
                    retryable: false,
                    outcomeUnknown: false);
                return;
            }

            requestToken.ThrowIfCancellationRequested();
            if (!CanStartOperatorCatalogWrite())
            {
                PostOperatorCatalogPlayoutActive(
                    requestId,
                    entity,
                    operation,
                    identityCode);
                return;
            }

            if (browserGeneration != Volatile.Read(ref _operatorCatalogBrowserGeneration))
            {
                requestCancellation.Cancel();
                return;
            }

            if (validationBody is not null)
            {
                await validationBody(requestToken);
                requestToken.ThrowIfCancellationRequested();
                if (!CanStartOperatorCatalogWrite())
                {
                    PostOperatorCatalogPlayoutActive(
                        requestId,
                        entity,
                        operation,
                        identityCode);
                    return;
                }

                if (browserGeneration != Volatile.Read(ref _operatorCatalogBrowserGeneration) ||
                    !ReferenceEquals(
                        Volatile.Read(ref _operatorCatalogWriteCancellation),
                        requestCancellation))
                {
                    requestCancellation.Cancel();
                    return;
                }
            }

            mutationDispatched = true;
            Interlocked.Exchange(ref _operatorCatalogWriteInFlight, 1);
            var receipt = await operationBody(requestToken);
            if (browserGeneration != Volatile.Read(ref _operatorCatalogBrowserGeneration) ||
                !ReferenceEquals(
                    Volatile.Read(ref _operatorCatalogWriteCancellation),
                    requestCancellation))
            {
                LatchOperatorCatalogWriteQuarantine(OperatorCatalogQuarantineMessage);
                return;
            }

            PostMessage("operator-catalog-mutation-results", new
            {
                requestId,
                entity,
                operation,
                identityCode,
                operationId = receipt.OperationId,
                receipt.CommittedAt,
                writeQuarantined = IsOperatorCatalogWriteQuarantined()
            });
        }
        catch (OperationCanceledException) when (_lifetimeCancellation.IsCancellationRequested)
        {
            if (mutationDispatched)
            {
                LatchOperatorCatalogWriteQuarantine(OperatorCatalogQuarantineMessage);
            }
        }
        catch (OperatorCatalogConflictException)
        {
            PostOperatorCatalogWriteErrorIfCurrent(
                requestId,
                entity,
                operation,
                identityCode,
                "CONFLICT",
                "The catalog changed or a code/name is already in use. Refresh before a new edit.",
                outcomeUnknown: false,
                requestCancellation);
        }
        catch (StockMasterIdentityDataException) when (!mutationDispatched)
        {
            PostOperatorCatalogWriteErrorIfCurrent(
                requestId,
                entity,
                operation,
                identityCode,
                "INVALID_DATA",
                "Every catalog stock must be selected from one current, unambiguous stock-master identity.",
                outcomeUnknown: false,
                requestCancellation);
        }
        catch (DatabaseOperationException) when (!mutationDispatched)
        {
            PostOperatorCatalogWriteErrorIfCurrent(
                requestId,
                entity,
                operation,
                identityCode,
                "DATABASE_ERROR",
                "The stock-master identity verification failed before the database transaction began.",
                outcomeUnknown: false,
                requestCancellation);
            _ = PostDatabaseStatusAsync(_lifetimeCancellation.Token);
        }
        catch (OperatorCatalogMutationException exception)
        {
            if (exception.OutcomeUnknown)
            {
                LatchOperatorCatalogWriteQuarantine(OperatorCatalogQuarantineMessage);
                PostOperatorCatalogWriteErrorIfCurrent(
                    requestId,
                    entity,
                    operation,
                    identityCode,
                    "OUTCOME_UNKNOWN",
                    OperatorCatalogQuarantineMessage,
                    outcomeUnknown: true,
                    requestCancellation);
            }
            else
            {
                PostOperatorCatalogWriteErrorIfCurrent(
                    requestId,
                    entity,
                    operation,
                    identityCode,
                    "WRITE_FAILED",
                    "The database transaction rolled back and was not retried.",
                    outcomeUnknown: false,
                    requestCancellation);
            }
        }
        catch (ArgumentException)
        {
            PostOperatorCatalogWriteErrorIfCurrent(
                requestId,
                entity,
                operation,
                identityCode,
                "INVALID_REQUEST",
                "The theme/expert write request is invalid.",
                outcomeUnknown: false,
                requestCancellation);
        }
        catch (OperationCanceledException)
        {
            if (mutationDispatched)
            {
                LatchOperatorCatalogWriteQuarantine(OperatorCatalogQuarantineMessage);
                PostOperatorCatalogWriteErrorIfCurrent(
                    requestId,
                    entity,
                    operation,
                    identityCode,
                    "OUTCOME_UNKNOWN",
                    OperatorCatalogQuarantineMessage,
                    outcomeUnknown: true,
                    requestCancellation);
            }
            else
            {
                PostOperatorCatalogWriteErrorIfCurrent(
                    requestId,
                    entity,
                    operation,
                    identityCode,
                    "CANCELLED",
                    "The write stopped before a database transaction began.",
                    outcomeUnknown: false,
                    requestCancellation);
            }
        }
        catch
        {
            if (mutationDispatched)
            {
                LatchOperatorCatalogWriteQuarantine(OperatorCatalogQuarantineMessage);
            }

            PostOperatorCatalogWriteErrorIfCurrent(
                requestId,
                entity,
                operation,
                identityCode,
                mutationDispatched ? "OUTCOME_UNKNOWN" : "WRITE_FAILED",
                mutationDispatched
                    ? OperatorCatalogQuarantineMessage
                    : "The write failed before a database transaction began.",
                outcomeUnknown: mutationDispatched,
                requestCancellation);
        }
        finally
        {
            Interlocked.Exchange(ref _operatorCatalogWriteInFlight, 0);
            if (databaseActivityEntered)
            {
                _databaseActivityGate.Release();
            }

            if (playoutGateEntered)
            {
                _playoutCommandGate.Release();
            }

            Interlocked.CompareExchange(
                ref _operatorCatalogWriteCancellation,
                null,
                requestCancellation);
            requestCancellation.Dispose();
            _operatorCatalogWriteGate.Release();
        }
    }

    private bool CanStartOperatorCatalogWrite()
    {
        if (Volatile.Read(ref _playoutCommandInFlight) != 0 ||
            Volatile.Read(ref _playoutShutdownStarted) != 0 ||
            IsBrowserCorrelationQuarantined() ||
            IsOperatorCatalogWriteQuarantined())
        {
            return false;
        }

        return CanStartOperatorMutation(IsOperatorCatalogWriteQuarantined());
    }

    private void RegisterOperatorCatalogRead(OperatorCatalogReadRequest request)
    {
        OperatorCatalogReadRequest? superseded;
        var shouldPostSuperseded = false;
        lock (_operatorCatalogReadLanesGate)
        {
            _operatorCatalogReadLanes.TryGetValue(request.Lane, out superseded);
            _operatorCatalogReadLanes[request.Lane] = request;
            shouldPostSuperseded = superseded?.TryComplete() == true;
        }

        if (superseded is null)
        {
            return;
        }

        CancelRequest(superseded.Cancellation);
        if (shouldPostSuperseded)
        {
            PostOperatorCatalogError(
                superseded.RequestId,
                superseded.Entity,
                superseded.Operation,
                string.Empty,
                "CANCELLED",
                "The catalog read was canceled because a newer request replaced it.",
                retryable: true,
                outcomeUnknown: false);
        }
    }

    private bool TryCompleteOperatorCatalogReadIfCurrent(OperatorCatalogReadRequest request)
    {
        lock (_operatorCatalogReadLanesGate)
        {
            return request.BrowserGeneration ==
                    Volatile.Read(ref _operatorCatalogBrowserGeneration) &&
                _operatorCatalogReadLanes.TryGetValue(request.Lane, out var current) &&
                ReferenceEquals(current, request) &&
                request.TryComplete();
        }
    }

    private void ReleaseOperatorCatalogRead(OperatorCatalogReadRequest request)
    {
        lock (_operatorCatalogReadLanesGate)
        {
            if (_operatorCatalogReadLanes.TryGetValue(request.Lane, out var current) &&
                ReferenceEquals(current, request))
            {
                _operatorCatalogReadLanes.Remove(request.Lane);
            }
        }
    }

    private OperatorCatalogReadRequest[] SnapshotOperatorCatalogReads(bool clear)
    {
        lock (_operatorCatalogReadLanesGate)
        {
            var requests = _operatorCatalogReadLanes.Values.ToArray();
            if (clear)
            {
                _operatorCatalogReadLanes.Clear();
                foreach (var request in requests)
                {
                    _ = request.TryComplete();
                }
            }

            return requests;
        }
    }

    private void PostOperatorCatalogReadCancellationIfCurrent(
        OperatorCatalogReadRequest request,
        string code,
        string message) =>
        PostOperatorCatalogReadErrorIfCurrent(
            request,
            code,
            message,
            retryable: true);

    private void PostOperatorCatalogReadErrorIfCurrent(
        OperatorCatalogReadRequest request,
        string code,
        string message,
        bool retryable)
    {
        if (_lifetimeCancellation.IsCancellationRequested ||
            !TryCompleteOperatorCatalogReadIfCurrent(request))
        {
            return;
        }

        PostOperatorCatalogError(
            request.RequestId,
            request.Entity,
            request.Operation,
            string.Empty,
            code,
            message,
            retryable,
            outcomeUnknown: false);
    }

    private void PostOperatorCatalogWriteErrorIfCurrent(
        string requestId,
        string entity,
        string operation,
        string identityCode,
        string code,
        string message,
        bool outcomeUnknown,
        CancellationTokenSource requestCancellation)
    {
        if (_lifetimeCancellation.IsCancellationRequested ||
            !ReferenceEquals(
                Volatile.Read(ref _operatorCatalogWriteCancellation),
                requestCancellation))
        {
            return;
        }

        PostOperatorCatalogError(
            requestId,
            entity,
            operation,
            identityCode,
            code,
            message,
            retryable: false,
            outcomeUnknown);
    }

    private void PostOperatorCatalogInvalidRequest(
        string requestId,
        string entity,
        string operation) =>
        PostOperatorCatalogError(
            requestId,
            entity,
            operation,
            string.Empty,
            "INVALID_REQUEST",
            "The theme/expert catalog request is invalid.",
            retryable: false,
            outcomeUnknown: false);

    private void PostOperatorCatalogUnavailable(
        string requestId,
        string entity,
        string operation,
        string identityCode = "") =>
        PostOperatorCatalogError(
            requestId,
            entity,
            operation,
            identityCode,
            "DATABASE_UNAVAILABLE",
            _operatorCatalogInitializationError ??
                _databaseInitializationError ??
                "The theme/expert database boundary is unavailable.",
            retryable: false,
            outcomeUnknown: false);

    private void PostOperatorCatalogPlayoutActive(
        string requestId,
        string entity,
        string operation,
        string identityCode) =>
        PostOperatorCatalogError(
            requestId,
            entity,
            operation,
            identityCode,
            "PLAYOUT_ACTIVE",
            "Theme/expert database writes are allowed only while playout is fully IDLE.",
            retryable: false,
            outcomeUnknown: false);

    private void PostOperatorCatalogQuarantined(
        string requestId,
        string entity,
        string operation,
        string identityCode) =>
        PostOperatorCatalogError(
            requestId,
            entity,
            operation,
            identityCode,
            "OUTCOME_UNKNOWN",
            GetOperatorMutationQuarantineMessage(
                Volatile.Read(ref _operatorCatalogWriteQuarantineMessage) ??
                    OperatorCatalogQuarantineMessage),
            retryable: false,
            outcomeUnknown: true);

    private void PostOperatorCatalogError(
        string requestId,
        string entity,
        string operation,
        string identityCode,
        string code,
        string message,
        bool retryable,
        bool outcomeUnknown)
    {
        PostMessage("operator-catalog-error", new
        {
            requestId,
            entity,
            operation,
            identityCode,
            code,
            message,
            retryable = retryable && !outcomeUnknown,
            outcomeUnknown,
            writeQuarantined = IsOperatorCatalogWriteQuarantined()
        });
    }

    private bool CanMutateThemeCatalog() =>
        _themeCatalogPersistenceService?.CanMutate == true &&
        _stockMasterIdentityValidationService is not null &&
        !IsOperatorCatalogWriteQuarantined();

    private bool CanMutateExpertCatalog() =>
        _expertCatalogPersistenceService?.CanMutate == true &&
        _stockMasterIdentityValidationService is not null &&
        !IsOperatorCatalogWriteQuarantined();

    private bool IsOperatorCatalogWriteQuarantined() =>
        Volatile.Read(ref _operatorCatalogWriteQuarantined) != 0 ||
        IsOperatorMutationQuarantined();

    private void LatchOperatorCatalogWriteQuarantine(string message)
    {
        LatchOperatorMutationQuarantine(message);
        if (Interlocked.CompareExchange(ref _operatorCatalogWriteQuarantined, 1, 0) == 0)
        {
            Volatile.Write(
                ref _operatorCatalogWriteQuarantineMessage,
                string.IsNullOrWhiteSpace(message)
                    ? OperatorCatalogQuarantineMessage
                    : message);
        }
    }

    /// <summary>
    /// Root browser-navigation/process-failure hook. Losing JavaScript request
    /// correlation while a write is active permanently quarantines writes for
    /// this process and never retries the command.
    /// </summary>
    private void InvalidateOperatorCatalogBrowserRequests()
    {
        Interlocked.Increment(ref _operatorCatalogBrowserGeneration);
        if (Volatile.Read(ref _operatorCatalogWriteInFlight) != 0)
        {
            LatchOperatorCatalogWriteQuarantine(OperatorCatalogQuarantineMessage);
        }

        foreach (var request in SnapshotOperatorCatalogReads(clear: true))
        {
            CancelRequest(request.Cancellation);
        }

        CancelRequest(Interlocked.Exchange(ref _operatorCatalogWriteCancellation, null));
    }

    /// <summary>
    /// Root playout-priority hook. A catalog write owns the playout gate and
    /// therefore cannot reach this point concurrently; only read work is canceled.
    /// </summary>
    private void CancelOperatorCatalogReadsForPlayout()
    {
        foreach (var request in SnapshotOperatorCatalogReads(clear: false))
        {
            CancelRequest(request.Cancellation);
        }
    }

    /// <summary>Root window-close hook.</summary>
    private void ShutdownOperatorCatalogRuntime()
    {
        if (Volatile.Read(ref _operatorCatalogWriteInFlight) != 0)
        {
            LatchOperatorCatalogWriteQuarantine(OperatorCatalogQuarantineMessage);
        }

        foreach (var request in SnapshotOperatorCatalogReads(clear: true))
        {
            CancelRequest(request.Cancellation);
        }

        CancelRequest(Interlocked.Exchange(ref _operatorCatalogWriteCancellation, null));
        _themeCatalogPersistenceService = null;
        _expertCatalogPersistenceService = null;
        _stockMasterIdentityValidationService = null;
        _operatorCatalogSchemaValidationService = null;
    }

    private static bool TryParseThemeCatalogListRequest(
        JsonElement payload,
        out string requestId,
        out string query,
        out ThemeSession nxtSession,
        out int maximumResults)
    {
        requestId = string.Empty;
        query = string.Empty;
        nxtSession = default;
        maximumResults = LegacyThemeSelectionService.DefaultMaximumResults;
        return payload.ValueKind == JsonValueKind.Object &&
            HasOnlyProperties(payload, "requestId", "query", "nxtSession", "maximumResults") &&
            TryGetSafeToken(payload, "requestId", MaximumPlayoutRequestIdLength, out requestId) &&
            TryGetOperatorCatalogQuery(
                payload,
                "query",
                LegacyThemeSelectionService.MaximumQueryLength,
                out query) &&
            TryParseThemeNxtSession(GetString(payload, "nxtSession"), out nxtSession) &&
            TryGetOptionalOperatorCatalogLimit(
                payload,
                LegacyThemeSelectionService.MaximumResults,
                ref maximumResults);
    }

    private static bool TryParseExpertCatalogListRequest(
        JsonElement payload,
        out string requestId,
        out string query,
        out int maximumResults)
    {
        requestId = string.Empty;
        query = string.Empty;
        maximumResults = LegacyExpertSelectionService.DefaultMaximumResults;
        return payload.ValueKind == JsonValueKind.Object &&
            HasOnlyProperties(payload, "requestId", "query", "maximumResults") &&
            TryGetSafeToken(payload, "requestId", MaximumPlayoutRequestIdLength, out requestId) &&
            TryGetOperatorCatalogQuery(
                payload,
                "query",
                LegacyExpertSelectionService.MaximumQueryLength,
                out query) &&
            TryGetOptionalOperatorCatalogLimit(
                payload,
                LegacyExpertSelectionService.MaximumResults,
                ref maximumResults);
    }

    private static bool TryParseOperatorCatalogRequestIdOnly(
        JsonElement payload,
        out string requestId)
    {
        requestId = string.Empty;
        return payload.ValueKind == JsonValueKind.Object &&
            HasOnlyProperties(payload, "requestId") &&
            TryGetSafeToken(payload, "requestId", MaximumPlayoutRequestIdLength, out requestId);
    }

    private static bool TryParseThemeCatalogNextCodeRequest(
        JsonElement payload,
        out string requestId,
        out ThemeMarket market)
    {
        requestId = string.Empty;
        market = default;
        return payload.ValueKind == JsonValueKind.Object &&
            HasOnlyProperties(payload, "requestId", "market") &&
            TryGetSafeToken(payload, "requestId", MaximumPlayoutRequestIdLength, out requestId) &&
            TryParseThemeMarket(GetString(payload, "market"), out market);
    }

    private static bool TryParseThemeCatalogCreateRequest(
        JsonElement payload,
        out string requestId,
        out ThemeCatalogDefinition definition)
    {
        requestId = string.Empty;
        definition = null!;
        if (payload.ValueKind != JsonValueKind.Object ||
            !HasOnlyProperties(payload, "requestId", "draft") ||
            !TryGetSafeToken(payload, "requestId", MaximumPlayoutRequestIdLength, out requestId) ||
            !payload.TryGetProperty("draft", out var draft) ||
            draft.ValueKind != JsonValueKind.Object ||
            !HasOnlyProperties(draft, "market", "themeCode", "themeTitle", "items") ||
            !TryParseThemeMarket(GetString(draft, "market"), out var market) ||
            !TryGetOperatorCatalogCode(draft, "themeCode", 8, out var code) ||
            !TryGetOperatorCatalogText(draft, "themeTitle", 128, out var title) ||
            market == ThemeMarket.Nxt && title.Contains("(NXT)", StringComparison.OrdinalIgnoreCase) ||
            !TryParseThemeCatalogItems(draft, market, out var items))
        {
            return false;
        }

        definition = new ThemeCatalogDefinition(market, code, title, items);
        return true;
    }

    private static bool TryParseThemeCatalogReplaceRequest(
        JsonElement payload,
        out string requestId,
        out ThemeSelectionIdentity expectedIdentity,
        out string newTitle,
        out IReadOnlyList<ThemeCatalogItem> items)
    {
        requestId = string.Empty;
        expectedIdentity = null!;
        newTitle = string.Empty;
        items = Array.Empty<ThemeCatalogItem>();
        if (payload.ValueKind != JsonValueKind.Object ||
            !HasOnlyProperties(payload, "requestId", "expectedIdentity", "newTitle", "items") ||
            !TryGetSafeToken(payload, "requestId", MaximumPlayoutRequestIdLength, out requestId) ||
            !payload.TryGetProperty("expectedIdentity", out var identityElement) ||
            !TryParseThemeCatalogIdentity(identityElement, out expectedIdentity) ||
            !TryGetOperatorCatalogText(payload, "newTitle", 128, out newTitle) ||
            expectedIdentity.Market == ThemeMarket.Nxt &&
                newTitle.Contains("(NXT)", StringComparison.OrdinalIgnoreCase) ||
            !TryParseThemeCatalogItems(payload, expectedIdentity.Market, out items))
        {
            return false;
        }

        return true;
    }

    private static bool TryParseThemeCatalogDeleteRequest(
        JsonElement payload,
        out string requestId,
        out ThemeSelectionIdentity identity)
    {
        requestId = string.Empty;
        identity = null!;
        return payload.ValueKind == JsonValueKind.Object &&
            HasOnlyProperties(payload, "requestId", "identity") &&
            TryGetSafeToken(payload, "requestId", MaximumPlayoutRequestIdLength, out requestId) &&
            payload.TryGetProperty("identity", out var identityElement) &&
            TryParseThemeCatalogIdentity(identityElement, out identity);
    }

    private static bool TryParseThemeCatalogIdentity(
        JsonElement element,
        out ThemeSelectionIdentity identity)
    {
        identity = null!;
        if (element.ValueKind != JsonValueKind.Object ||
            !HasOnlyProperties(element, "market", "session", "themeCode", "themeTitle") ||
            !TryParseThemeMarket(GetString(element, "market"), out var market) ||
            !TryParseThemeSession(GetString(element, "session"), out var session) ||
            market == ThemeMarket.Krx && session != ThemeSession.NotApplicable ||
            market == ThemeMarket.Nxt &&
                session is not (ThemeSession.PreMarket or ThemeSession.AfterMarket) ||
            !TryGetExistingThemeCatalogCode(element, "themeCode", out var code) ||
            !TryGetOperatorCatalogText(element, "themeTitle", 128, out var title) ||
            market == ThemeMarket.Nxt && title.Contains("(NXT)", StringComparison.OrdinalIgnoreCase))
        {
            return false;
        }

        identity = new ThemeSelectionIdentity(market, session, code, title);
        return true;
    }

    private static bool TryParseThemeCatalogItems(
        JsonElement parent,
        ThemeMarket market,
        out IReadOnlyList<ThemeCatalogItem> items)
    {
        items = Array.Empty<ThemeCatalogItem>();
        if (!parent.TryGetProperty("items", out var array) ||
            array.ValueKind != JsonValueKind.Array ||
            array.GetArrayLength() > LegacyThemeCatalogPersistenceService.MaximumItems)
        {
            return false;
        }

        var parsed = new List<ThemeCatalogItem>(array.GetArrayLength());
        var codes = new HashSet<string>(StringComparer.Ordinal);
        var names = new HashSet<string>(StringComparer.Ordinal);
        var expectedIndex = 0;
        foreach (var element in array.EnumerateArray())
        {
            if (element.ValueKind != JsonValueKind.Object ||
                !HasOnlyProperties(element, "inputIndex", "itemCode", "itemName") ||
                !element.TryGetProperty("inputIndex", out var indexElement) ||
                indexElement.ValueKind != JsonValueKind.Number ||
                !indexElement.TryGetInt32(out var inputIndex) ||
                inputIndex != expectedIndex ||
                !TryGetOperatorCatalogText(element, "itemCode", 13, out var itemCode) ||
                !IsThemeItemCodeForMarket(itemCode, market) ||
                !TryGetOperatorCatalogText(element, "itemName", 200, out var itemName) ||
                !codes.Add(itemCode) ||
                !names.Add(itemName))
            {
                return false;
            }

            parsed.Add(new ThemeCatalogItem(inputIndex, itemCode, itemName));
            expectedIndex++;
        }

        items = parsed.AsReadOnly();
        return true;
    }

    private static bool TryParseExpertCatalogCreateRequest(
        JsonElement payload,
        out string requestId,
        out ExpertCatalogDefinition definition)
    {
        requestId = string.Empty;
        definition = null!;
        if (payload.ValueKind != JsonValueKind.Object ||
            !HasOnlyProperties(payload, "requestId", "draft") ||
            !TryGetSafeToken(payload, "requestId", MaximumPlayoutRequestIdLength, out requestId) ||
            !payload.TryGetProperty("draft", out var draft) ||
            draft.ValueKind != JsonValueKind.Object ||
            !HasOnlyProperties(draft, "expertCode", "expertName", "recommendations") ||
            !TryGetOperatorCatalogCode(draft, "expertCode", 4, out var code) ||
            !TryGetOperatorCatalogText(draft, "expertName", 128, out var name) ||
            !TryParseExpertCatalogRecommendations(draft, out var recommendations))
        {
            return false;
        }

        definition = new ExpertCatalogDefinition(
            new ExpertSelectionIdentity(code, name),
            recommendations);
        return true;
    }

    private static bool TryParseExpertCatalogReplaceRequest(
        JsonElement payload,
        out string requestId,
        out ExpertSelectionIdentity expectedIdentity,
        out string newName,
        out IReadOnlyList<ExpertCatalogRecommendation> recommendations)
    {
        requestId = string.Empty;
        expectedIdentity = null!;
        newName = string.Empty;
        recommendations = Array.Empty<ExpertCatalogRecommendation>();
        if (payload.ValueKind != JsonValueKind.Object ||
            !HasOnlyProperties(
                payload,
                "requestId",
                "expectedIdentity",
                "newName",
                "recommendations") ||
            !TryGetSafeToken(payload, "requestId", MaximumPlayoutRequestIdLength, out requestId) ||
            !payload.TryGetProperty("expectedIdentity", out var identityElement) ||
            !TryParseExpertCatalogIdentity(identityElement, out expectedIdentity) ||
            !TryGetOperatorCatalogText(payload, "newName", 128, out newName) ||
            !TryParseExpertCatalogRecommendations(payload, out recommendations))
        {
            return false;
        }

        return true;
    }

    private static bool TryParseExpertCatalogDeleteRequest(
        JsonElement payload,
        out string requestId,
        out ExpertSelectionIdentity identity)
    {
        requestId = string.Empty;
        identity = null!;
        return payload.ValueKind == JsonValueKind.Object &&
            HasOnlyProperties(payload, "requestId", "identity") &&
            TryGetSafeToken(payload, "requestId", MaximumPlayoutRequestIdLength, out requestId) &&
            payload.TryGetProperty("identity", out var identityElement) &&
            TryParseExpertCatalogIdentity(identityElement, out identity);
    }

    private static bool TryParseExpertCatalogIdentity(
        JsonElement element,
        out ExpertSelectionIdentity identity)
    {
        identity = null!;
        if (element.ValueKind != JsonValueKind.Object ||
            !HasOnlyProperties(element, "expertCode", "expertName") ||
            !TryGetOperatorCatalogCode(element, "expertCode", 4, out var code) ||
            !TryGetOperatorCatalogText(element, "expertName", 128, out var name))
        {
            return false;
        }

        identity = new ExpertSelectionIdentity(code, name);
        return true;
    }

    private static bool TryParseExpertCatalogRecommendations(
        JsonElement parent,
        out IReadOnlyList<ExpertCatalogRecommendation> recommendations)
    {
        recommendations = Array.Empty<ExpertCatalogRecommendation>();
        if (!parent.TryGetProperty("recommendations", out var array) ||
            array.ValueKind != JsonValueKind.Array ||
            array.GetArrayLength() > LegacyExpertCatalogPersistenceService.MaximumRecommendations)
        {
            return false;
        }

        var parsed = new List<ExpertCatalogRecommendation>(array.GetArrayLength());
        var codes = new HashSet<string>(StringComparer.Ordinal);
        var names = new HashSet<string>(StringComparer.Ordinal);
        var expectedIndex = 0;
        foreach (var element in array.EnumerateArray())
        {
            if (element.ValueKind != JsonValueKind.Object ||
                !HasOnlyProperties(
                    element,
                    "playIndex",
                    "stockCode",
                    "stockName",
                    "buyAmount") ||
                !element.TryGetProperty("playIndex", out var indexElement) ||
                indexElement.ValueKind != JsonValueKind.Number ||
                !indexElement.TryGetInt32(out var playIndex) ||
                playIndex != expectedIndex ||
                !TryGetOperatorCatalogText(element, "stockCode", 32, out var stockCode) ||
                !stockCode.All(char.IsAsciiLetterOrDigit) ||
                !TryGetOperatorCatalogText(element, "stockName", 200, out var stockName) ||
                !element.TryGetProperty("buyAmount", out var amountElement) ||
                amountElement.ValueKind != JsonValueKind.Number ||
                !amountElement.TryGetInt64(out var amount) ||
                amount <= 0 ||
                amount > OperatorCatalogMaximumWebSafeInteger ||
                !codes.Add(stockCode) ||
                !names.Add(stockName))
            {
                return false;
            }

            parsed.Add(new ExpertCatalogRecommendation(
                playIndex,
                stockCode,
                stockName,
                amount));
            expectedIndex++;
        }

        recommendations = parsed.AsReadOnly();
        return true;
    }

    private static bool TryGetOptionalOperatorCatalogLimit(
        JsonElement payload,
        int maximum,
        ref int value)
    {
        if (!payload.TryGetProperty("maximumResults", out var element))
        {
            return true;
        }

        return element.ValueKind == JsonValueKind.Number &&
            element.TryGetInt32(out value) &&
            value is >= 1 && value <= maximum;
    }

    private static bool TryGetOperatorCatalogQuery(
        JsonElement payload,
        string propertyName,
        int maximumLength,
        out string value)
    {
        value = GetString(payload, propertyName) ?? string.Empty;
        return payload.TryGetProperty(propertyName, out var element) &&
            element.ValueKind == JsonValueKind.String &&
            value.Length <= maximumLength &&
            string.Equals(value, value.Trim(), StringComparison.Ordinal) &&
            IsSafeOperatorCatalogText(value);
    }

    private static bool TryGetOperatorCatalogCode(
        JsonElement payload,
        string propertyName,
        int length,
        out string value)
    {
        value = GetString(payload, propertyName) ?? string.Empty;
        return value.Length == length && value.All(char.IsAsciiDigit);
    }

    private static bool TryGetExistingThemeCatalogCode(
        JsonElement payload,
        string propertyName,
        out string value)
    {
        value = GetString(payload, propertyName) ?? string.Empty;
        return value.Length is >= 3 and <= 8 && value.All(char.IsAsciiDigit);
    }

    private static bool TryGetOperatorCatalogText(
        JsonElement payload,
        string propertyName,
        int maximumLength,
        out string value)
    {
        value = GetString(payload, propertyName) ?? string.Empty;
        return payload.TryGetProperty(propertyName, out var element) &&
            element.ValueKind == JsonValueKind.String &&
            value.Length is > 0 && value.Length <= maximumLength &&
            string.Equals(value, value.Trim(), StringComparison.Ordinal) &&
            IsSafeOperatorCatalogText(value);
    }

    private static bool IsSafeOperatorCatalogText(string value)
    {
        foreach (var character in value)
        {
            var category = CharUnicodeInfo.GetUnicodeCategory(character);
            if (char.IsControl(character) ||
                char.IsSurrogate(character) ||
                character == '\uFFFD' ||
                category is UnicodeCategory.Format or
                    UnicodeCategory.LineSeparator or
                    UnicodeCategory.ParagraphSeparator)
            {
                return false;
            }
        }

        return true;
    }

    private static bool IsThemeItemCodeForMarket(string itemCode, ThemeMarket market)
    {
        if (itemCode.Length is < 2 or > 13 ||
            !itemCode.AsSpan(1).ToArray().All(char.IsAsciiLetterOrDigit))
        {
            return false;
        }

        return market switch
        {
            ThemeMarket.Krx => itemCode[0] is 'P' or 'D',
            ThemeMarket.Nxt => itemCode[0] is 'X' or 'T',
            _ => false
        };
    }

    private static string SafeOperatorCatalogRequestId(JsonElement payload)
    {
        return payload.ValueKind == JsonValueKind.Object &&
            TryGetSafeToken(
                payload,
                "requestId",
                MaximumPlayoutRequestIdLength,
                out var requestId)
            ? requestId
            : string.Empty;
    }

    private readonly record struct OperatorCatalogBridgeReply(string MessageType, object Payload);

    private sealed class OperatorCatalogReadRequest
    {
        private int _terminalState;

        public OperatorCatalogReadRequest(
            string lane,
            string requestId,
            string entity,
            string operation,
            int browserGeneration,
            CancellationTokenSource cancellation)
        {
            Lane = lane;
            RequestId = requestId;
            Entity = entity;
            Operation = operation;
            BrowserGeneration = browserGeneration;
            Cancellation = cancellation;
        }

        public string Lane { get; }

        public string RequestId { get; }

        public string Entity { get; }

        public string Operation { get; }

        public int BrowserGeneration { get; }

        public CancellationTokenSource Cancellation { get; }

        public bool TryComplete() => Interlocked.CompareExchange(ref _terminalState, 1, 0) == 0;
    }
}
