using adas_core.Domain.Enums;
using MongoDB.Bson;

namespace adas_core.Domain.Models.Masters;

/// <summary>
/// Represents a master list, serving as a centralized collection for managing a comprehensive set of items.
/// </summary>
/// <remarks>
/// This class provides a foundational structure for organizing and accessing a primary list of entries.
/// </remarks>
public class MasterList
{
    public ObjectId Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public string Description { get; set; } = string.Empty;
    public string ManualObservationName { get; set; } = "UnknownMasterList";
    public List<string> AutoObservationName { get; set; } = [];
    public MasterListType ListType { get; set; }
    public bool CanAddElement { get; set; }
    public OptionListDetails? OptionListDetails { get; set; }
    public LocaleEnum? DefaultLocale { get; set; }
    public List<OptionList> Options { get; set; } = [];

    public MasterList ReturnMasterListOptionsInLocaleIfExist(LocaleEnum? localeToReturn)
    {
        if (localeToReturn == null) return this;
        var optionsConverted = new List<OptionList>();

        foreach (var opt in Options)
        {
            // 1. Obtener traducción del locale
            string? translatedName = null;

            if (opt.LocaleItems != null)
            {
                var localeProp = opt.LocaleItems
                    .GetType()
                    .GetProperty(localeToReturn.Value.ToString());

                var localeItem = localeProp?.GetValue(opt.LocaleItems) as LocaleItem;
                translatedName = localeItem?.Name;
            }

            // 2. Usar traducción si existe, sino fallback
            var finalName = !string.IsNullOrWhiteSpace(translatedName)
                ? translatedName
                : opt.Name;

            // 3. Crear nueva opción convertida
            var newOpt = new OptionList
            {
                Id = opt.Id,
                Name = finalName,
                OptionType = opt.OptionType,
                Description = opt.Description,
                Color = opt.Color,
                BgColor = opt.BgColor,
                IconDefault = opt.IconDefault,
                IconCategory = opt.IconCategory,
                IconColor = opt.IconColor,
                InitDate = opt.InitDate,
                EndDate = opt.EndDate,
                IsDefault = opt.IsDefault,

                // Mantener todos los LocaleItems originales
                LocaleItems = opt.LocaleItems
            };

            optionsConverted.Add(newOpt);
        }

        // 4. Clonar el master pero con las opciones nuevas
        return new MasterList
        {
            Id = Id,
            Name = Name,
            Description = Description,
            ManualObservationName = ManualObservationName,
            AutoObservationName = new List<string>(AutoObservationName),
            ListType = ListType,
            CanAddElement = CanAddElement,
            OptionListDetails = OptionListDetails,
            DefaultLocale = DefaultLocale,
            Options = optionsConverted
        };
    }
}

/// <summary>
/// Represents a container that holds detailed information about a list of options.
/// </summary>
/// <remarks>
/// This type is intended to encapsulate the metadata or structure associated with an option list, allowing consumers to access its detailed content in a structured manner.
/// </remarks>
public class OptionListDetails
{
    public Element? OptionType { get; set; }
    public Element? Name { get; set; }
    public Element? IconDefault { get; set; }
    public Element? IconCategory { get; set; }
    public Element? IconColor { get; set; }
    public Element? Color { get; set; }
    public Element? BgColor { get; set; }
    public Element? Description { get; set; }
}

/// <summary>
/// Represents a generic element within the system, serving as a foundational type that can be extended or composed to model domain-specific entities or structures.
/// </summary>
public class Element
{
    public string Title { get; set; } = string.Empty;
    public bool IsRequired { get; set; }
    public bool IsList { get; set; } = false;
    public string ListName { get; set; } = string.Empty;
}