using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Misc
{
    public class ParamDictionary
    {

        List<KeyValueCell> cells = new List<KeyValueCell>();

        /// <summary>
        /// 获取值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void SetValue(string key, object value) 
        {
            var cell = cells.Find(c => c.Key == key);
            if (cell == null)
            {
                cell = new KeyValueCell() { Key = key, Value = value };//, Type = value.GetType() };
                cell.IsConverted = true;
                cells.Add(cell);
                ValueChanged?.Invoke(this, new ParamDictionaryValueChangedEventArgs() { Key = key, Value = value });
            }
            else
            {
                cell.IsConverted = true;
                if (cell.Value != value)
                {
                    cell.Value = value;
                    //cell.Type = value.GetType();
                    ValueChanged?.Invoke(this, new ParamDictionaryValueChangedEventArgs() { Key = key, Value = value });
                }
            }
        }

        /// <summary>
        /// 获取值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public T GetValue<T>(string key) 
        {
            return GetValue<T>(key, default(T));
        }


        /// <summary>
        /// 获取值，如果没有返回默认值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public T GetValue<T>(string key, T defaultValue)
        {
            var cell = cells.Find(c => c.Key == key);
            if (cell == null)
            {
                cell = new KeyValueCell() { Key = key, Value = defaultValue };
                cell.IsConverted = true;
                cells.Add(cell);
                return (T)cell.Value;
            }
            else
            {
                if (cell.IsConverted)
                    return (T)cell.Value;
                else
                {
                    cell.ToValue<T>();
                    var type = cell.Value.GetType();

                    return (T)cell.Value;
                }
            }
        }

        private string path;

        public event UiParamDictionaryValueChangedHandler ValueChanged;
        public ParamDictionary(string path = "paramDict.json")
        {
            this.path = path;
            Load();
        }
        public void Load()
        {
            if (!File.Exists(path))
                return;
            try
            {
                string json = File.ReadAllText(path);
                var cells = Newtonsoft.Json.JsonConvert.DeserializeObject<List<KeyValueCell>>(json);
                this.cells = cells;
            }
            catch (Exception e)
            {
                //logger.Error(e, "Load 出错");
            }
        }
        public void Save()
        {
            try
            {
                foreach (var cell in cells)
                    cell.ToToken();

                string json = Newtonsoft.Json.JsonConvert.SerializeObject(cells, Newtonsoft.Json.Formatting.Indented);
                File.WriteAllText(path, json);
            }
            catch (Exception e)
            {
                //logger.Error(e, "Save 出错");
            }
        }
    }
    public delegate void UiParamDictionaryValueChangedHandler(object sender, ParamDictionaryValueChangedEventArgs e);

    public class ParamDictionaryValueChangedEventArgs : EventArgs
    {
        public string Key;
        public object Value;
    }
    
    
    public class KeyValueCell : INotifyPropertyChanged
    {
        public string Key { get; set; }

        [Newtonsoft.Json.JsonIgnore]
        public object Value { get; set; }

        /// <summary>
        /// 已经转换为object 非 JObject 与 JArray
        /// </summary>
        [Newtonsoft.Json.JsonIgnore]
        public bool IsConverted { get; set; }

        [Newtonsoft.Json.JsonProperty("Value")]
        public JToken Token { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

        public override string ToString()
        {
            return $"[{Key}]={Newtonsoft.Json.JsonConvert.SerializeObject(Value)}";
        }

        /// <summary>
        /// Value转为类型T
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public void ToValue<T>() 
        {
            IsConverted = true;
            if (Token == null)
                return;
            Value = Token.ToObject<T>();
        }
        public void ToToken() 
        {
            Token = JToken.FromObject(Value);
        }
    }
}
