using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FObjBase;

using System.Reflection;
using Misc;
using System.ComponentModel;
using System.Net;
using System.Xml;
using FLY.Modbus;
using FLY.Weight2.Server.Model;
using FLY.Weight2.OBJ_INTERFACE;
using FLY.Weight2.IService;
using FLY.Weight2.Common;
using FLY.OBJComponents.Client;
using FLY.OBJComponents.IService;
using System.Collections.ObjectModel;

using System.IO;

namespace FLY.Weight2.Client
{
    public class WeightSystemServiceClient: FObjServiceClient, IWeightSystemService, IPropertyOpt
    {

        #region IWeightSystemService 接口

        public ObservableCollection<WeighterC> Items { get; } = new ObservableCollection<WeighterC>();

        public WeighterAccessory Accessory { get; } = new WeighterAccessory();

        /// <summary>
        /// PLC代理系统
        /// </summary>
        public IPLCProxySystemService PLCos { get; set; }

        /// <summary>
        /// 层数
        /// </summary>
        public int ItemsCnt { get; set; } = 3;

        #endregion

        string[] NumberNames;
        SyncPropServiceClient syncPropServiceClient;


        public event Action ResetItemsEvent;
        /// <summary>
        /// TODO
        /// </summary>
        /// <param name="serviceId"></param>
        public WeightSystemServiceClient(UInt32 serviceId) : base(serviceId) {
            Init();
        }
        public WeightSystemServiceClient(UInt32 serviceId, string connName) : base(serviceId) {
            ConnName = connName;
            filePath = connName + "." + filePath;
            Init();
            

            FObjServiceClientManager.Instance.Connect_to_Another_OBJSys(connName, this);
        }

        string GetNumber(int index) {
            string number;

            if (NumberNames != null
                && index < NumberNames.Count()
                && !string.IsNullOrEmpty(NumberNames[index]))
            {
                number = NumberNames[index];
            }
            else
            {
                number = ((char)('A' + index)).ToString();
            }
            return number;
        }
        /// <summary>
        /// 以给定的各层仓数创建,当接收到 BinCnts变化,
        /// 重新修改各层, 删除,或添加
        /// </summary>
        void Init()
        {
            if (!LoadNumberNames())
                SaveNumberNames();
            Load();
            for (int i = 0; i < ItemsCnt; i++)
            {
                string number = GetNumber(i);
                WeighterC w = new WeighterC(number,i);
                Items.Add(w);
            }

            //--------------------------------------------------------------
            //属性同步
            Dictionary<string, INotifyPropertyChanged> objnames = new Dictionary<string, INotifyPropertyChanged>();
            objnames.Add(".", this);
            objnames.Add(nameof(Accessory), Accessory);
            for (int i = 0; i < Items.Count(); i++)
                objnames.Add($"{nameof(Items)}[{i}]", Items[i]);
            
            syncPropServiceClient = new SyncPropServiceClient(mServerID + 1, objnames);

            //--------------------------------------------------------------
            //PLC代理,用于添加更新任务
            Dictionary<string, INotifyPropertyChanged> objnames2 = new Dictionary<string, INotifyPropertyChanged>();
            objnames2.Add(nameof(Accessory), Accessory);
            for (int i = 0; i < Items.Count(); i++)
                objnames2.Add($"{nameof(Items)}[{i}]", Items[i]);

            PLCos = new PLCProxySystemServiceClient(mServerID + 2);




            this.PropertyChanged += WeightSystemClient_PropertyChanged;
        }

        string filePath = "weightSystemClient.json";
        void Save() 
        {
            WeightSystemClientJsonDb jsonDb = new WeightSystemClientJsonDb()
            {
                ItemsCnt = ItemsCnt,
            };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(jsonDb);
            File.WriteAllText(filePath, json);
        }
        void Load() {
            if (!File.Exists(filePath))
                return;
            string json =File.ReadAllText(filePath);
            var p = Newtonsoft.Json.JsonConvert.DeserializeObject< WeightSystemClientJsonDb>(json);
            ItemsCnt = p.ItemsCnt;

        }
        string filePath_number = "weightSystemClientNumberNames.json";
        bool LoadNumberNames() 
        {
            if (!File.Exists(filePath_number))
                return false;
            string json = File.ReadAllText(filePath_number);
            var p = Newtonsoft.Json.JsonConvert.DeserializeObject<NumberNamesJsonDb>(json);
            NumberNames = p.NumberNames;
            return true;
        }
        void SaveNumberNames()
        {
            NumberNamesJsonDb jsonDb = new NumberNamesJsonDb
            {
                NumberNames = NumberNames
            };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(jsonDb);
            File.WriteAllText(filePath_number, json);
        }


        private void WeightSystemClient_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(ItemsCnt))
            {
                ResetItems();
                Save();
            }
        }

        /// <summary>
        /// 重新创建 Items
        /// </summary>
        void ResetItems()
        {

            int last_itemcnt = Items.Count();

            for (int i = 0; i < Items.Count(); i++)
            {
                if (i < ItemsCnt)
                {

                }
                else
                {
                    //多出来的Item 都要删除
                    int remove_cnt = Items.Count() - ItemsCnt;
                    for (i = 0; i < remove_cnt; i++)
                        Items.RemoveAt(Items.Count() - 1);

                    goto _step1;
                }
            }

            for (int i = Items.Count(); i < ItemsCnt; i++)
            {
                //少了,需要添加
                string number = GetNumber(i);
                WeighterC w = new WeighterC(number,i);
                Items.Add(w);
            }

        _step1:
            //处理属性同步
            if (last_itemcnt == Items.Count())//数量相同,不需要处理
                goto _step2;

            if (last_itemcnt < Items.Count())
            {
                //少了需要添加
                for (int i = last_itemcnt; i < Items.Count(); i++)
                {
                    syncPropServiceClient.Add($"{nameof(Items)}[{i}]", Items[i]);
                }
            }
            else
            {
                //多了需要删除
                for (int i = Items.Count(); i < last_itemcnt; i++)
                {
                    syncPropServiceClient.Remove($"{nameof(Items)}[{i}]");
                }
            }

        _step2:
            ResetItemsEvent?.Invoke();
            return;
        }
        public override UInt32[] GetIDs()
        {
            List<UInt32> IDs = new List<uint>
            {
                ID,
                syncPropServiceClient.ID,
            };
            IDs.AddRange(((PLCProxySystemServiceClient)PLCos).GetIDs());
            return IDs.ToArray();
        }
        public override void ConnectNotify(IFConn from)
        {
            base.ConnectNotify(from);
            if (from.IsConnected)
            {

                CurrObjSys.SenseConfigEx(mConn, mServerID, ID,
                    0xffffffff, SENSE_CONFIG.ADD);
            }
        }

        public string[] GetSyncPropNames()
        {
            return new string[]{
                nameof(ItemsCnt)
                };
        }

        public string[] GetNoSyncPropNames()
        {
            return null;
        }

    }

    public class WeightSystemClientJsonDb 
    {
        public int ItemsCnt;
    }
    public class NumberNamesJsonDb
    {
        public string[] NumberNames;
    }
}