using CloudBuilder.Core.DependencyInjection.Policy;
using CloudBuilder.Core.DependencyInjection.Request;
using CloudBuilder.Core.Service;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Text;
using System.Threading.Tasks;

namespace CloudBuilder.Core.Policy
{
    public class LocalePolicy : IPolicy
    {
        public const string ZH_CN = "zh-cn";
        public const string EN = "en";

        public LocalePolicy(IContext context, ILocaleMessageManager localeMessageManager)
        {
            this.context = context;
            this.localeMessageManager = localeMessageManager;
        }

        protected object[] values = null;
        private readonly IContext context;
        private readonly ILocaleMessageManager localeMessageManager;

        public string Name { get; set; } = typeof(LocalePolicy).Name;

        public string[] GetValues() { return this.values?.Select(x => x.ToString()).ToArray(); }

        public string[] GetMessages()
        {
            if (values == null || values.Length == 0) return null;

            List<string> messages = new List<string>();
            foreach (string v in values)
            {
                messages.Add(ComposeMessage(Name, v));
            }

            return messages.ToArray();
        }

        public BindOption[] GetBindOptions()
        {
            if (values == null || values.Length == 0) return null;

            List<BindOption> messages = new List<BindOption>();
            foreach (string v in values)
            {
                messages.Add(new BindOption() { BindValue = v, DisplayName = ComposeMessage(v) });
            }

            return messages.ToArray();
        }

        public SelectOption[] GetSelectOptions()
        {
            if (values == null || values.Length == 0) return null;

            List<SelectOption> messages = new List<SelectOption>();
            foreach (string v in values)
            {
                messages.Add(new SelectOption() { BindValue = v, DisplayName = ComposeMessage(v) });
            }

            return messages.ToArray();
        }

        public string ComposeMessage(string msgId, params object[] p)
        {
            if (string.IsNullOrEmpty(msgId)) return null;

            string template = localeMessageManager.ComposeMessage(Name, msgId);

            if (string.IsNullOrEmpty(template)) throw new ValidatedException(string.Format("locale:{0}-{1}", Name, msgId));

            return string.Format(template, p);
        }

        public TableName<string>[] GetDataSource()
        {
            return localeMessageManager.GetDataSource(this.Name);
        }

        public Dictionary<string, object> GetDictionary()
        {
            Dictionary<string, object> keyValues = new Dictionary<string, object>();
            TableName<string>[] tables = localeMessageManager.GetDataSource(this.Name);
            foreach (TableName<string> v in tables)
            {
                keyValues.Add(v.Value, v.DisplayName);
            }

            return keyValues;
        }

        public TableName<string>[] GetDataSource(Action<TableName<string>[]> action)
        {
            TableName<string>[] tables = localeMessageManager.GetDataSource(this.Name);
            if (action != null)
            {
                action(tables);
            }
            return tables;
        }

        public TableName<T>[] GetComposeMessages<T>()
        {
            if (values == null || values.Length == 0) return null;
            TableName<T> tb = null;
            List<TableName<T>> list = new List<TableName<T>>();
            foreach (T v in values)
            {
                tb = new TableName<T>();
                tb.DisplayName = ComposeMessage(v.ToString(), context.GetCulture());
                tb.Value = v;
                list.Add(tb);
            }

            return list.ToArray();
        }

    }
}
