using System;
using System.Collections.Generic;

namespace QRRapidoApp.Models.Ads
{
    /// <summary>
    /// Represents the content for a single affiliate advertisement.
    /// </summary>
    public class AffiliateAdContent
    {
        public string Title { get; set; } = string.Empty;
        public string? Description { get; set; }
        public string ProductUrl { get; set; } = string.Empty;
        public string? ImageUrl { get; set; }
        public string? CtaText { get; set; }
        public string? BadgeText { get; set; }
        public string? PriceText { get; set; }
        public string? Category { get; set; }

        public bool IsEmpty()
        {
            return string.IsNullOrWhiteSpace(ProductUrl);
        }

        public AffiliateAdContent Clone()
        {
            return new AffiliateAdContent
            {
                Title = Title,
                Description = Description,
                ProductUrl = ProductUrl,
                ImageUrl = ImageUrl,
                CtaText = CtaText,
                BadgeText = BadgeText,
                PriceText = PriceText,
                Category = Category
            };
        }
    }

    /// <summary>
    /// Configuration for an ad slot, supporting AdSense or affiliate content.
    /// </summary>
    public class AdSlotConfiguration
    {
        /// <summary>
        /// Provider type for the slot. Supported values: "AdSense", "Affiliate".
        /// Defaults to "AdSense" to preserve current behaviour.
        /// </summary>
        public string Provider { get; set; } = "AdSense";

        /// <summary>
        /// Optional custom AdSense slot ID override.
        /// </summary>
        public string? AdSenseSlotId { get; set; }

        /// <summary>
        /// Affiliate content that will be rendered when <see cref="Provider"/> is "Affiliate".
        /// </summary>
        public AffiliateAdContent? Affiliate { get; set; }

        public AdSlotConfiguration Clone()
        {
            return new AdSlotConfiguration
            {
                Provider = Provider,
                AdSenseSlotId = AdSenseSlotId,
                Affiliate = Affiliate?.Clone()
            };
        }
    }

    /// <summary>
    /// Root options object bound from configuration for ad slots.
    /// </summary>
    public class AdsConfigurationOptions
    {
        private IDictionary<string, AdSlotConfiguration> _slots = new Dictionary<string, AdSlotConfiguration>(StringComparer.OrdinalIgnoreCase);
        private IDictionary<string, IDictionary<string, AdSlotConfiguration>> _locales = new Dictionary<string, IDictionary<string, AdSlotConfiguration>>(StringComparer.OrdinalIgnoreCase);

        public IDictionary<string, AdSlotConfiguration> Slots
        {
            get => _slots;
            set => _slots = CreateSlotDictionary(value);
        }

        public IDictionary<string, IDictionary<string, AdSlotConfiguration>> Locales
        {
            get => _locales;
            set
            {
                _locales = new Dictionary<string, IDictionary<string, AdSlotConfiguration>>(StringComparer.OrdinalIgnoreCase);
                if (value == null)
                {
                    return;
                }

                foreach (var locale in value)
                {
                    _locales[locale.Key] = CreateSlotDictionary(locale.Value);
                }
            }
        }

        public AdSlotConfiguration GetSlot(string slotKey, string? cultureName = null)
        {
            if (string.IsNullOrWhiteSpace(slotKey))
            {
                slotKey = "header";
            }

            var localeSlot = TryGetLocaleSlot(slotKey, cultureName);
            if (localeSlot != null)
            {
                return localeSlot.Clone();
            }

            if (_slots.TryGetValue(slotKey, out var config))
            {
                return config.Clone();
            }

            // Default to AdSense when not configured
            return new AdSlotConfiguration();
        }

        private AdSlotConfiguration? TryGetLocaleSlot(string slotKey, string? cultureName)
        {
            if (string.IsNullOrWhiteSpace(cultureName) || _locales.Count == 0)
            {
                return null;
            }

            if (_locales.TryGetValue(cultureName, out var localeSlots) && localeSlots.TryGetValue(slotKey, out var slot))
            {
                return slot;
            }

            var neutralCulture = cultureName.Split('-')[0];
            if (!string.Equals(neutralCulture, cultureName, StringComparison.OrdinalIgnoreCase)
                && _locales.TryGetValue(neutralCulture, out var neutralSlots)
                && neutralSlots.TryGetValue(slotKey, out var neutralSlot))
            {
                return neutralSlot;
            }

            return null;
        }

        private static IDictionary<string, AdSlotConfiguration> CreateSlotDictionary(IDictionary<string, AdSlotConfiguration>? source)
        {
            var dictionary = new Dictionary<string, AdSlotConfiguration>(StringComparer.OrdinalIgnoreCase);
            if (source == null)
            {
                return dictionary;
            }

            foreach (var kvp in source)
            {
                if (kvp.Value != null)
                {
                    dictionary[kvp.Key] = kvp.Value;
                }
            }

            return dictionary;
        }
    }

    /// <summary>
    /// View model used by the affiliate ad partial.
    /// </summary>
    public class AffiliateAdViewModel
    {
        public string SlotKey { get; set; } = "header";
        public string ContainerCssClass { get; set; } = string.Empty;
        public AffiliateAdContent Content { get; set; } = new AffiliateAdContent();
    }
}
