using System.Text.Json;
using RolemasterDb.App.Features;

namespace RolemasterDb.App.Components.Shared;

public sealed class CriticalCellEditorModel
{
    public int ResultId { get; set; }
    public string TableSlug { get; set; } = string.Empty;
    public string TableName { get; set; } = string.Empty;
    public string SourceDocument { get; set; } = string.Empty;
    public string RollBand { get; set; } = string.Empty;
    public string? GroupKey { get; set; }
    public string? GroupLabel { get; set; }
    public string ColumnKey { get; set; } = string.Empty;
    public string ColumnLabel { get; set; } = string.Empty;
    public string ColumnRole { get; set; } = string.Empty;
    public string RawCellText { get; set; } = string.Empty;
    public string DescriptionText { get; set; } = string.Empty;
    public string? RawAffixText { get; set; }
    public string ParseStatus { get; set; } = string.Empty;
    public string ParsedJson { get; set; } = "{}";
    public List<string> ValidationMessages { get; set; } = [];
    public List<CriticalEffectEditorModel> Effects { get; set; } = [];
    public List<CriticalBranchEditorModel> Branches { get; set; } = [];

    public static CriticalCellEditorModel FromResponse(CriticalCellEditorResponse response) =>
        new()
        {
            ResultId = response.ResultId,
            TableSlug = response.TableSlug,
            TableName = response.TableName,
            SourceDocument = response.SourceDocument,
            RollBand = response.RollBand,
            GroupKey = response.GroupKey,
            GroupLabel = response.GroupLabel,
            ColumnKey = response.ColumnKey,
            ColumnLabel = response.ColumnLabel,
            ColumnRole = response.ColumnRole,
            RawCellText = response.RawCellText,
            DescriptionText = response.DescriptionText,
            RawAffixText = response.RawAffixText,
            ParseStatus = response.ParseStatus,
            ParsedJson = response.ParsedJson,
            ValidationMessages = response.ValidationMessages.ToList(),
            Effects = response.Effects.Select(CriticalEffectEditorModel.FromItem).ToList(),
            Branches = response.Branches.Select(CriticalBranchEditorModel.FromItem).ToList()
        };

    public CriticalCellUpdateRequest ToRequest() =>
        new(
            RawCellText,
            DescriptionText,
            RawAffixText,
            ResolveParseStatus(Effects, Branches),
            SerializeParsedEffects(Effects),
            Effects.Select(effect => effect.ToItem()).ToList(),
            Branches
                .OrderBy(branch => branch.SortOrder)
                .Select((branch, index) =>
                {
                    branch.SortOrder = index + 1;
                    return branch.ToItem();
                })
                .ToList());

    private static string ResolveParseStatus(
        IReadOnlyList<CriticalEffectEditorModel> effects,
        IReadOnlyList<CriticalBranchEditorModel> branches) =>
        effects.Count > 0 || branches.Any(branch => branch.Effects.Count > 0)
            ? "partial"
            : "raw";

    private static string SerializeParsedEffects(IReadOnlyList<CriticalEffectEditorModel> effects) =>
        effects.Count == 0
            ? "{}"
            : JsonSerializer.Serialize(new { effects = effects.Select(effect => effect.ToItem()).ToList() });
}
