using DeskRedis.Exceptions;
using DeskRedis.Model;
using DeskRedis.Util;
using ServiceStack.Redis;
using System;
using System.Linq;
using System.Windows;

namespace DeskRedis
{
    /// <summary>
    /// WinAddKey.xaml 的交互逻辑
    /// </summary>
    public partial class WinAddKey : Window
    {
        #region 私有变量
        private readonly NodeInfo nodeInfo;
        #endregion


        #region 事件委托
        /// <summary>
        /// 当添加新项成功时发生。
        /// </summary>
        public event Action<string> OnAdded;
        public event Action<string> OnError;
        #endregion


        #region 构造方法
        public WinAddKey(NodeInfo nodeInfo)
        {
            InitializeComponent();

            string[] types = Enum.GetNames(typeof(RedisKeyType))
                                 .Where(p => !"none".Equals(p.ToLower()))
                                 .ToArray();
            foreach (string item in types)
            {
                this.cbbType.Items.Add(item);
            }
            this.cbbType.SelectedIndex = 0;

            this.nodeInfo = nodeInfo;
        }
        #endregion


        #region 私有方法
        #endregion


        #region 本地事件
        /// <summary>
        /// 当鼠标点击“保存”按钮时发生。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnSave_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                AssertUtil.FormDataValidate("请输入键名", () => { return string.IsNullOrEmpty(this.tbKey.Text.Trim()); });
                AssertUtil.FormDataValidate("请选择类型", () =>
                {
                    return this.cbbType.SelectedItem == null || string.IsNullOrEmpty(this.cbbType.SelectedItem.ToString());
                });
                AssertUtil.FormDataValidate("请输入值", () => { return string.IsNullOrEmpty(this.tbValue.Text.Trim()); });
                string key = this.tbKey.Text.Trim();
                string type = this.cbbType.SelectionBoxItem.ToString();
                Enum.TryParse(type, out RedisKeyType redisKeyType);
                string value = this.tbValue.Text.Trim();

                switch (redisKeyType)
                {
                    case RedisKeyType.String:
                        {
                            GlobalBusiness.RedisCaches[nodeInfo.ConfigId]
                                          .Add<string>(key, value, nodeInfo.DbIndex);
                        }
                        break;
                    case RedisKeyType.List:
                        {
                            GlobalBusiness.RedisCaches[nodeInfo.ConfigId]
                                          .AddList(key, value, nodeInfo.DbIndex);
                        }
                        break;
                    case RedisKeyType.Set:
                        {
                            GlobalBusiness.RedisCaches[nodeInfo.ConfigId]
                                          .AddSet(key, value, nodeInfo.DbIndex);
                        }
                        break;
                    case RedisKeyType.SortedSet:
                        {
                            string strScore = this.tbScore.Text.Trim();
                            AssertUtil.FormDataValidate("请输入排序号!", () => { return string.IsNullOrEmpty(strScore); });
                            if (!double.TryParse(strScore, out double score))
                            {
                                throw new IllegalFormDataException("排序号不合法!");
                            }
                            GlobalBusiness.RedisCaches[nodeInfo.ConfigId]
                                          .AddSortedSet(key, value, score, nodeInfo.DbIndex);
                        }
                        break;
                    case RedisKeyType.Hash:
                        {
                            string hashKey = this.tbHashKey.Text.Trim();
                            AssertUtil.FormDataValidate("请输入HashKey!", () => { return string.IsNullOrEmpty(hashKey); });
                            GlobalBusiness.RedisCaches[nodeInfo.ConfigId]
                                          .AddHash(key, hashKey, value, nodeInfo.DbIndex);
                        }
                        break;
                    default:
                        break;
                }
                this.OnAdded?.Invoke(key);
                MessageBox.Show("添加成功");
                this.Close();
            }
            catch (IllegalFormDataException ex)
            {
                MessageBox.Show(ex.Message);
            }
            catch (RedisException ex)
            {
                MessageBox.Show(ex.Message);
            }
            catch (Exception ex)
            {
                this.OnError?.Invoke(ex.Message);
            }
        }

        /// <summary>
        /// 当键类型变化时发生。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CbbType_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            Enum.TryParse(this.cbbType.SelectedItem.ToString(), out RedisKeyType type);
            switch (type)
            {
                case RedisKeyType.String:
                case RedisKeyType.List:
                case RedisKeyType.Set:
                    this.gridScore.Visibility = Visibility.Collapsed;
                    this.gridHashKey.Visibility = Visibility.Collapsed;
                    break;
                case RedisKeyType.SortedSet:
                    this.gridScore.Visibility = Visibility.Visible;
                    this.gridHashKey.Visibility = Visibility.Collapsed;
                    break;
                case RedisKeyType.Hash:
                    this.gridScore.Visibility = Visibility.Collapsed;
                    this.gridHashKey.Visibility = Visibility.Visible;
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 当鼠标点击“取消”按钮时发生。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnCancel_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
        #endregion
    }
}