using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;
using FLY.Thick.Base.IService;
using Unity;

namespace FLY.Thick.Base.UI
{
    /// <summary>
    /// Window_Password.xaml 的交互逻辑
    /// </summary>
    public partial class WdPassword : FLY.ControlLibrary.WindowBigClose,INotifyPropertyChanged
    {
        PasswordAuthorize passwordAuthorize;
        static PasswordKeep mPwKeep = new PasswordKeep();

        public WdPassword()
        {
            InitializeComponent();
        }
        public void Init(PasswordAuthorize passwordAuthorize, int level, string msg=null) 
        {
            this.passwordAuthorize = passwordAuthorize;
            this.Level = level;
            this.Msg = msg;
        }
        string Msg = null;
        /// <summary>
        /// 密码级别
        /// </summary>
        int Level = 0;

        /// <summary>
        /// 输入密码,查询到的级别
        /// </summary>
        public int PwLv { get; private set; }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="uiName"></param>
        /// <returns></returns>
        public static bool Authorize(string uiName) 
        {
            return Authorize(uiName, out int pwLv);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="uiName"></param>
        /// <returns></returns>
        public static bool Authorize(string uiName, string msg)
        {
            return Authorize(uiName, out int pwLv, msg);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="uiName">界面</param>
        /// <param name="pwLv">当密码正确时,密码的级别</param>
        /// <returns></returns>
        public static bool Authorize(string uiName, out int pwLv, string msg=null)
        {
            pwLv = 0;
            //从容器获取
            var container = Application.Current.Properties["container"] as IUnityContainer;
            if (container == null)
                return true;

            var passwordAuthorize = container.Resolve<PasswordAuthorize>();
            int level = passwordAuthorize.GetLv(uiName);
            if (level <= 0)
                return true;

            WdPassword w = new WdPassword();
            w.Init(passwordAuthorize, level, msg);
            w.Owner = Application.Current.MainWindow;
            bool ret = (bool)w.ShowDialog();
            pwLv = w.PwLv;
            return ret;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="level">要求的级别</param>
        /// <param name="pwLv">当密码正确时,密码的级别</param>
        /// <returns></returns>
        public static bool Authorize(int level, out int pwLv)
        {
            pwLv = 0;
            //从容器获取
            var container = Application.Current.Properties["container"] as IUnityContainer;
            if (container == null)
                return true;

            var passwordAuthorize = container.Resolve<PasswordAuthorize>();
            if (level <= 0)
                return true;

            WdPassword w = new WdPassword();
            w.Init(passwordAuthorize, level);
            w.Owner = Application.Current.MainWindow;
            bool ret = (bool)w.ShowDialog();
            pwLv = w.PwLv;
            return ret;
        }
        private void button_apply_Click(object sender, RoutedEventArgs e)
        {
            if(string.IsNullOrEmpty(passwordbox.Password))
            {
                string tit = (string)Application.Current.TryFindResource("str.WdPassword.OperateFailed");
                string msg = (string)Application.Current.TryFindResource("str.WdPassword.PasswordNull");
                FLY.ControlLibrary.Window_Tip.Show(tit, msg, TimeSpan.FromSeconds(2));
                return;
            }
            

            AUTHORIZE_RESULT r = passwordAuthorize.Authorize(passwordbox.Password, Level, out int pwLv, out string pwDesp);
            PwLv = pwLv;
            switch (r) 
            {
                case AUTHORIZE_RESULT.OK:
                    {
                        mPwKeep.SetPSK(passwordbox.Password);
                        this.DialogResult = true;
                        this.Close();
                        return;
                    }
                case AUTHORIZE_RESULT.ERR_LEVEL:
                    {
                        string tit = (string)Application.Current.TryFindResource("str.WdPassword.OperateFailed");
                        string format = (string)Application.Current.TryFindResource("str.WdPassword.PermissionDenied");
                        string msg = string.Format(format, pwDesp, Level);

                        FLY.ControlLibrary.Window_Tip.Show(tit, msg, TimeSpan.FromSeconds(2));
                        return;
                    }
                case AUTHORIZE_RESULT.ERR_PW:
                    {
                        string tit = (string)Application.Current.TryFindResource("str.WdPassword.OperateFailed");
                        string msg = (string)Application.Current.TryFindResource("str.WdPassword.PasswordWrong");
                        FLY.ControlLibrary.Window_Tip.Show(tit, msg, TimeSpan.FromSeconds(2));
                        return;
                    }
            }
            return;
        }

        private void ButtonOSK_Click(object sender, RoutedEventArgs e)
        {
            TextBox tbPw = new TextBox
            {
                Text = passwordbox.Password,
                Tag = "full password"
            };
            tbPw.TextChanged += (s, _e) =>
            {
                var textbox = s as TextBox;
                passwordbox.Password = textbox.Text;
            };
            FLY.ControlLibrary.UI.OSK.KeyboardBehavior.PopPad(tbPw, this);
        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //从容器获取
            //this.DataContext = this;
            togglebutton_keep5min.DataContext = mPwKeep;

            if (string.IsNullOrEmpty(Msg))
            {
                tbMsg.Visibility = Visibility.Collapsed;
            }
            else {
                tbMsg.Text = Msg;
            }

            if (mPwKeep.GetPSK(out string psk))
            {
                passwordbox.Password = psk;
            }
        }
        #region INotifyPropertyChanged 成员
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }

    /// <summary>
    /// 上一次的密码保持5分钟
    /// </summary>
    public class PasswordKeep:INotifyPropertyChanged
    {

        /// <summary>
        /// 密码保存5分钟
        /// </summary>
        public bool Keep5Min { get; set; } = true;
        
        string PSK;
        /// <summary>
        /// 密码输入时间
        /// </summary>
        DateTime Time = DateTime.MinValue;
        /// <summary>
        /// 复位
        /// </summary>
        public void Reset()
        {
            Time = DateTime.MinValue;
        }
        public bool GetPSK(out string psk) 
        {
            psk = null;
            if (Keep5Min == false)
                return false;

            if ((DateTime.Now - Time) > TimeSpan.FromMinutes(5)) //5分钟内
                return false;
            
            psk = PSK;
            return true;
        }
        public void SetPSK(string psk)
        {
            PSK = psk;
            Time = DateTime.Now;
        }

        #region INotifyPropertyChanged 成员

        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }
}