using System;
using System.Collections.Generic;
using System.Text.Json;
using SessionZero.Data.Sztl;

namespace SessionZero.Data;

public class SzObject
{
    public string Id { get; set; }
    public string Uuid { get; set; }
    public string TemplateId { get; set; }

    public Dictionary<string, SzField> Fields { get; set; } = new();
    public Dictionary<string, SzFieldGroup> FieldGroups { get; set; } = new();

    public virtual object? GetFieldValue(string fieldPath)
    {
        if (string.IsNullOrEmpty(fieldPath)) return null;

        var parts = fieldPath.Split('.');
        if (parts.Length == 1)
        {
            if (Fields.TryGetValue(parts[0], out var field))
                return field.Value;
            return null;
        }

        SzFieldGroup? currentGroup = null;
        for (int i = 0; i < parts.Length - 1; i++)
        {
            var key = parts[i];
            currentGroup = currentGroup == null 
                ? FieldGroups.GetValueOrDefault(key)
                : currentGroup.SubGroups.GetValueOrDefault(key);

            if (currentGroup == null) return null;
        }

        var lastPart = parts[^1];
        if (currentGroup != null)
        {
            if (currentGroup.Fields.TryGetValue(lastPart, out var field))
                return field.Value;
        }

        return Fields.TryGetValue(lastPart, out var topField) ? topField.Value : null;
    }

    public virtual T GetFieldValue<T>(string fieldPath)
    {
        var val = GetFieldValue(fieldPath);
        if (val == null) return default!;
        return (T)Convert.ChangeType(val, typeof(T));
    }

    public virtual string GetFieldValueAsString(string fieldPath)
    {
        var val = GetFieldValue(fieldPath);
        return val?.ToString() ?? string.Empty;
    }

    public virtual void SetFieldValue(string fieldPath, object value)
    {
        if (string.IsNullOrEmpty(fieldPath)) return;

        var parts = fieldPath.Split('.');
        if (parts.Length == 1)
        {
            if (Fields.ContainsKey(parts[0]))
                Fields[parts[0]].Value = value;
            return;
        }

        SzFieldGroup? currentGroup = null;
        for (int i = 0; i < parts.Length - 1; i++)
        {
            var key = parts[i];
            currentGroup = currentGroup == null 
                ? FieldGroups.GetValueOrDefault(key)
                : currentGroup.SubGroups.GetValueOrDefault(key);

            if (currentGroup == null) return;
        }

        var lastPart = parts[^1];
        if (currentGroup != null)
        {
            if (currentGroup.Fields.ContainsKey(lastPart))
                currentGroup.Fields[lastPart].Value = value;
        }
        else if (Fields.ContainsKey(lastPart))
        {
            Fields[lastPart].Value = value;
        }
    }

    public override string ToString()
    {
        return JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = true });
    }
}