using MBN_STOCK_WEBVIEW.Infrastructure;
using MMoneyCoderSharp.Data;

namespace MBN_STOCK_WEBVIEW;

public sealed partial class MainWindow
{
    private LegacyNamedKrxThemeRestoreService? _namedKrxThemeRestoreService;

    private async Task PostNamedKrxThemeRestoreAsync(
        string requestId,
        IReadOnlyList<NamedPlaylistStoredItem> items,
        CancellationToken cancellationToken)
    {
        var candidates = items
            .Select(static item => new LegacyNamedKrxThemeRestoreRow(
                item.ItemIndex,
                item.IsEnabled,
                item.Selection.GroupCode,
                item.Selection.Subject,
                item.Selection.GraphicType,
                item.Selection.Subtype,
                item.Page?.ToString() ?? string.Empty,
                item.Selection.DataCode))
            .Where(LegacyNamedKrxThemeRestoreService.IsCandidate)
            .ToArray();
        if (candidates.Length == 0)
        {
            return;
        }

        try
        {
            var runtime = _databaseRuntime;
            if (runtime is null)
            {
                PostNamedKrxThemeRestoreError(
                    requestId,
                    "DATABASE_UNAVAILABLE",
                    "현재 Oracle DB를 사용할 수 없어 저장된 KRX 테마를 재검증하지 못했습니다.");
                return;
            }

            var service = _namedKrxThemeRestoreService ??=
                new LegacyNamedKrxThemeRestoreService(runtime.Executor);
            var result = await service.ResolveAsync(candidates, cancellationToken);
            cancellationToken.ThrowIfCancellationRequested();
            PostMessage("named-krx-theme-restore-results", new
            {
                requestId,
                result.RetrievedAt,
                totalRowCount = result.Rows.Count,
                rows = result.Rows.Select(ToNamedKrxThemeRestoreWireRow)
            });
        }
        catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
        {
            if (Volatile.Read(ref _playoutCommandInFlight) != 0 &&
                !_lifetimeCancellation.IsCancellationRequested)
            {
                PostNamedKrxThemeRestoreError(
                    requestId,
                    "PLAYOUT_PRIORITY",
                    "송출 명령 우선 처리로 KRX 테마 재검증을 취소했습니다. 자동 재시도하지 않습니다.");
            }

            throw;
        }
        catch (DatabaseOperationException)
        {
            PostNamedKrxThemeRestoreError(
                requestId,
                "DATABASE_UNAVAILABLE",
                "현재 Oracle DB에서 KRX 테마를 재검증하지 못했습니다.");
            _ = PostDatabaseStatusAsync(_lifetimeCancellation.Token);
        }
        catch
        {
            PostNamedKrxThemeRestoreError(
                requestId,
                "RESTORE_FAILED",
                "저장된 KRX 테마 행을 안전한 현재 선택으로 복원하지 못했습니다.");
        }
    }

    private static object ToNamedKrxThemeRestoreWireRow(
        LegacyNamedKrxThemeRestoreOutcome outcome)
    {
        if (outcome.IsResolved)
        {
            var identity = outcome.Identity!;
            return new
            {
                outcome.ItemIndex,
                status = "resolved",
                identity.ActionId,
                identity.BuilderKey,
                identity.CutCode,
                identity.PageSize,
                identity.Sort,
                identity.ThemeTitle,
                identity.StoredThemeCode,
                identity.CurrentThemeCode,
                identity.PreviewItemCount,
                identity.PreviewIsTruncated,
                identity.CodeWasRemapped
            };
        }

        return new
        {
            outcome.ItemIndex,
            status = "failed",
            failure = outcome.Failure switch
            {
                LegacyNamedKrxThemeRestoreFailure.InvalidRow => "INVALID_ROW",
                LegacyNamedKrxThemeRestoreFailure.UnsupportedAction => "UNSUPPORTED_ACTION",
                LegacyNamedKrxThemeRestoreFailure.IdentityNotFound => "IDENTITY_NOT_FOUND",
                LegacyNamedKrxThemeRestoreFailure.IdentityAmbiguous => "IDENTITY_AMBIGUOUS",
                LegacyNamedKrxThemeRestoreFailure.PreviewEmpty => "PREVIEW_EMPTY",
                LegacyNamedKrxThemeRestoreFailure.DatabaseDataInvalid =>
                    "DATABASE_DATA_INVALID",
                _ => "RESTORE_FAILED"
            }
        };
    }

    private void PostNamedKrxThemeRestoreError(
        string requestId,
        string code,
        string message)
    {
        PostMessage("named-krx-theme-restore-error", new
        {
            requestId,
            code,
            message,
            retryable = false
        });
    }
}
