using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Billing.Languages
{
    internal class Resource
    {
        public static string TitleDateFormat => Text(nameof(TitleDateFormat));

        static readonly Dictionary<string, LanguageResource> dict = new();

        public static string Text(string name, params object[] args)
        {
            string current = App.CurrentCulture.PlatformString;
            if (!dict.TryGetValue(current, out LanguageResource lang))
            {
                lang = new LanguageResource(App.CurrentCulture);
                dict.Add(current, lang);
            }
            if (args == null || args.Length == 0)
            {
                return lang[name];
            }
            return string.Format(lang[name], args);
        }

        private class LanguageResource
        {
            private readonly Dictionary<string, string> strings;

            public string this[string key]
            {
                get
                {
                    if (strings != null && strings.TryGetValue(key, out string val))
                    {
                        return val;
                    }
                    return key;
                }
            }

            public LanguageResource(PlatformCulture lang)
            {
                try
                {
                    var ns = lang.GetNamespace();
                    var langId = $"{ns}.Languages.{lang.Language}.xml";
                    var langCodeId = $"{ns}.Languages.{lang.LanguageCode}.xml";
                    var assembly = typeof(LanguageResource).Assembly;
                    var name = assembly.GetManifestResourceNames().FirstOrDefault(n =>
                        string.Equals(n, langId, StringComparison.OrdinalIgnoreCase) ||
                        string.Equals(n, langCodeId, StringComparison.OrdinalIgnoreCase));
                    if (name == null)
                    {
                        name = $"{ns}.Languages.zh-CN.xml";
                    }
                    var xml = new XmlDocument();
                    using (var stream = assembly.GetManifestResourceStream(name))
                    {
                        xml.Load(stream);
                    }
                    strings = new Dictionary<string, string>();
                    foreach (XmlElement ele in xml.DocumentElement)
                    {
                        strings[ele.Name] = ele.InnerText;
                    }
                }
                catch (Exception ex)
                {
                    Helper.Error("language.ctor", $"failed to load json resource: {lang}, {ex.Message}");
                }
            }
        }
    }

    [ContentProperty(nameof(Text))]
    public class TextExtension : IMarkupExtension
    {
        public string Text { get; set; }

        public object ProvideValue(IServiceProvider serviceProvider)
        {
            if (Text == null)
            {
                return string.Empty;
            }
            return Resource.Text(Text);
        }
    }
}
