using CommunityToolkit.Mvvm.Input;
using FObjBase;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;

namespace FLY.Thick.Base.UI
{
    /// <summary>
    /// PgAddress.xaml 的交互逻辑
    /// </summary>
    public partial class PgAddress : Page
    {
        PgAddressVm viewModel;
        public PgAddress()
        {
            InitializeComponent();
            if (System.ComponentModel.LicenseManager.UsageMode != System.ComponentModel.LicenseUsageMode.Runtime)
                return;

            this.Loaded += UcGridGraph_Loaded;
            this.Unloaded += UcGridGraph_Unloaded;
        }

        private void UcGridGraph_Unloaded(object sender, RoutedEventArgs e)
        {
            viewModel.DisposeBinding();
        }

        private void UcGridGraph_Loaded(object sender, RoutedEventArgs e)
        {
            viewModel.SetBinding();
        }

        [Unity.InjectionMethod]
        public void Init()
        {
            viewModel = new PgAddressVm();
            viewModel.Init();
            this.DataContext = viewModel;
        }
    }
    public class PgAddressVm : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public List<ConnAddr> ConnAddrs { get; }

        public RelayCommand ApplyCmd { get; }

        FObjServiceClientManager serviceClientManager;

        Dictionary<object, List<Misc.BindingOperations.PropertyChangedEventContexts>> bindingConexts = new Dictionary<object, List<Misc.BindingOperations.PropertyChangedEventContexts>>();

        /// <summary>
        /// 数据已经绑定了
        /// </summary>
        bool isBinding;

        public PgAddressVm()
        {
            ApplyCmd = new RelayCommand(Apply);
            ConnAddrs = new List<ConnAddr>();

        }

        public void Init()
        {
            serviceClientManager = FObjServiceClientManager.Instance;


            foreach (var ca in serviceClientManager.ConnAddrs)
            {
                ConnAddrs.Add(new ConnAddr() { ConnName = ca.ConnName, Address = ca.Addr });
            };

            SetBinding();
        }

        /// <summary>
        /// 参数绑定
        /// </summary>
        public void SetBinding()
        {
            if (isBinding)
                return;
            isBinding = true;

            //下面全部event保存在bindingConexts
            Misc.BindingOperations.StartMarkdownEvents(bindingConexts);
            //备份event完毕, 必须关闭记录
            Misc.BindingOperations.StopMarkdownEvents();
        }
        /// <summary>
        /// 解除绑定
        /// </summary>
        public void DisposeBinding()
        {
            if (!isBinding)//已经解除绑定了
                return;
            isBinding = false;

            //释放全部 event
            Misc.BindingOperations.DisposeEventTargetObject(bindingConexts);

        }

        private void Apply()
        {
            if (!WdPassword.Authorize("Address"))
                return;

            Regex regex_hostname = new Regex(@"(\S+)\:(\d+)");
            Regex regex_ip = new Regex(@"(\d+)\.(\d+)\.(\d+)\.(\d+)\:(\d+)");
            //检测地址格式
            foreach (var ca in ConnAddrs)
            {
                //把地址的 ： 替换为 :
                ca.Address = ca.Address.Replace("：", ":");
                Match m_hostname = regex_hostname.Match(ca.Address);
                Match m_ip = regex_ip.Match(ca.Address);

                if (!m_hostname.Success)
                {
                    //格式错误
                    MessageBox.Show(
                        $"{ca.ConnName} 地址格式错误！ 正确为 IP地址:端口号 或 域名:端口号 , 请检查",
                        "格式错误",
                        MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                if (m_ip.Success)
                {
                    //这个IP
                    for (int i = 0; i < 4; i++)
                    {
                        if (!int.TryParse(m_ip.Groups[1 + i].Value, out int num))
                        {
                            //格式错误
                            MessageBox.Show($"{ca.ConnName} 地址格式错误！ 第{i + 1} 位IP段 出错",
                                "格式错误",
                        MessageBoxButton.OK, MessageBoxImage.Error);
                            return;
                        }
                        if (num < 0 || num > 255)
                        {
                            //格式错误
                            MessageBox.Show(
                                $"{ca.ConnName} 地址格式错误！ 第{i + 1}位IP段应该在 0~255 之间",  
                                "格式错误",
                        MessageBoxButton.OK, MessageBoxImage.Error); 
                            return;
                        }
                    }
                }



                {
                    if (!int.TryParse(m_hostname.Groups[2].Value, out int port))
                    {
                        //格式错误
                        MessageBox.Show(
                            $"{ca.ConnName} 地址格式错误！ 端口出错");
                        return;
                    }
                    if (port < 1 || port > 65535)
                    {
                        //格式错误
                        MessageBox.Show(
                            $"{ca.ConnName} 地址格式错误！ 端口应该在 1~65535 之间",
                                "格式错误",
                        MessageBoxButton.OK, MessageBoxImage.Error);
                        return;
                    }
                }

                var ep = Misc.StringConverter.ToIPEndPoint(ca.Address);
                if (ep == null)
                {
                    //不能转为ep
                    MessageBox.Show(
                    $"{ca.ConnName} 不能有效转换IPv4",
                                "地址出错",
                        MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
            }

            int modifyCnt = 0;
            //检查完毕
            foreach (var ca in ConnAddrs)
            {
                var objCa = serviceClientManager.ConnAddrs.Find(_ca => _ca.ConnName == ca.ConnName);
                if (objCa == null)
                    continue;
                if (objCa.Addr != ca.Address)
                {
                    modifyCnt++;
                    //重新连接
                    serviceClientManager.ReConnect(ca.ConnName, ca.Address);
                }
            };

            if (modifyCnt > 0)
            {
                serviceClientManager.Save();

                string tit = (string)Application.Current.TryFindResource("str.PgAddress.AmendSuccessfully");
                FLY.ControlLibrary.Window_Tip.Show(tit, null, TimeSpan.FromSeconds(2));
                return;
            }
            else
            {
                string tit = (string)Application.Current.TryFindResource("str.PgAddress.AmendFailed");
                FLY.ControlLibrary.Window_Tip.Show(tit, null, TimeSpan.FromSeconds(2));
                return;
            }
        }
    }
    public class ConnAddr : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// 连接器名称
        /// </summary>
        public string ConnName { get; set; }

        /// <summary>
        /// 设备地址
        /// </summary>
        public string Address { get; set; }

    }
}
