using FLY.Integrated.Common;
using FLY.Integrated.IService;
using FLY.Integrated.Server.Model;
using FLY.Modbus;
using FLY.OBJComponents.IService;
using FLY.OBJComponents.Server;
using FObjBase;
using Misc;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FLY.Integrated.Server
{
    [JsonObject(MemberSerialization.OptIn)]
    public class IntegratedSystem : IIntegratedSystemService
    {
        #region IIntegratedSystemService
        /// <summary>
        /// 数据
        /// </summary>
        public IbcData Ibc { get; } = new IbcData();

        /// <summary>
        ///  收卷
        /// </summary>
        public WinderAccessory Accessory { get; } = new WinderAccessory();
        private int ctrlInterval = 5;
        /// <summary>
        /// 控制记录周期,单位s, 最小值为2
        /// </summary>
        [JsonProperty]
        public int CtrlInterval
        {
            get { return ctrlInterval; }
            set
            {
                if (value < 2)
                    value = 2;
                if (ctrlInterval != value)
                {
                    ctrlInterval = value;
                }
            }
        }


        private PLCProxySystem plcos = new PLCProxySystem();
        /// <summary>
        /// PLC代理系统
        /// </summary>
        public IPLCProxySystemService PLCos { get { return plcos; } }

        #endregion

        /// <summary>
        /// 报警系统
        /// </summary>
        WarningSystem warning;
        /// <summary>
        /// 记录到数据库
        /// </summary>
        HistoryDb historyDb;
        /// <summary>
        /// 报警配置
        /// </summary>
        ErrorConf errorConf;

        /// <summary>
        /// 周期保存Ibc数据
        /// </summary>
        PeriodicallySaveData<Db_Width> psdWidth;

        /// <summary>
        /// 周期保存收卷数据
        /// </summary>
        PeriodicallySaveData<Db_WinderInfo> psdWinderInfo;

        public event PropertyChangedEventHandler PropertyChanged;

        public IntegratedSystem()
        {
            Load();


        }
        public void Init(HistoryDb historyDb, WarningSystem warning) 
        {
            this.historyDb = historyDb;
            this.warning = warning;

            //--------------------------------------------------------------------------------
            //step 1 加载PLC寄存器 文件
            plcos.AddConfigFile(
                "plcgroup.json",
                (plcgroup) => new Dictionary<string, INotifyPropertyChanged>
                {
                    { "Ibc", Ibc },
                    { "Accessory", Accessory }
                }
            );

            //--------------------------------------------------------------------------------
            //step 2 报警配置
            errorConf = new ErrorConf(PLCos, this.warning, "综合IBC");
            errorConf.AddErrorAction(Accessory);
            errorConf.AddErrorAction(Ibc);
            errorConf.InitError();


            //--------------------------------------------------------------------------------
            //step 3 历史数据记录

            //添加任务
            PLCos.SetPlan("Ibc", new string[] {
                        "FilmWidth","InletAirFreq","OutletAirFreq","ExCoolFreq"
                    }, 0);

            psdWidth = new PeriodicallySaveData<Db_Width>();
            psdWidth.Init(
                CtrlInterval,
                this.historyDb.AddWidthRange, 
                () =>{
                    if (!PLCos.IsConnectedWithPLC)
                        return null;

                    if (Ibc.InletAirFreq < 2 && Ibc.OutletAirFreq < 2)//没有工作!!!!
                        return null;

                    //记录数据
                    return new Db_Width()
                    {
                        Time = DateTime.Now,
                        FilmWidth = Math.Round(Ibc.FilmWidth, 1),
                        InletAirFreq = Math.Round(Ibc.InletAirFreq, 1),
                        OutletAirFreq = Math.Round(Ibc.OutletAirFreq, 1),
                        ExCoolFreq = Math.Round(Ibc.ExCoolFreq, 1)
                    };
                });

            PLCos.SetPlan("Accessory", new string[] {
                        "TractionVelocity","RotaryFreq","IsRotaryForw","IsRotaryBackw"
                    }, 0);

            psdWinderInfo = new PeriodicallySaveData<Db_WinderInfo>();
            psdWinderInfo.Init(
                10,
                this.historyDb.AddWinderInfos,
                () => {
                    if (!PLCos.IsConnectedWithPLC)
                        return null;

                    if (Accessory.TractionVelocity < 1 )//没有工作!!!!
                        return null;

                    //记录数据
                    return new Db_WinderInfo()
                    {
                        Time = DateTime.Now,
                        TractionVelocity = Math.Round(Accessory.TractionVelocity, 1),
                        RotaryFreq = Math.Round(Accessory.RotaryFreq, 1),
                        IsRotaryBackw = Accessory.IsRotaryBackw,
                        IsRotaryForw = Accessory.IsRotaryForw
                    };
                });

            //--------------------------------------------------------------------------------
            //last step  PLC 更新计划服务初始化
            plcos.Init();
        }

        void Save()
        {
            string json = JsonConvert.SerializeObject(this, Formatting.Indented);
            File.WriteAllText("integrated.json", json);
        }
        void Load()
        {

            if (File.Exists("integrated.json"))
            {
                try
                {
                    string json = File.ReadAllText("integrated.json");
                    JsonConvert.PopulateObject(json, this);
                }
                catch
                {

                }
            }

        }
    }



}