using APT.BaseData.Domain.ApiModel.BD;
using APT.BaseData.Domain.ApiModel.Platform;
using APT.BaseData.Domain.Entities;
using APT.BaseData.Domain.Entities.BD;
using APT.BaseData.Domain.Entities.PF;
using APT.BaseData.Domain.Enums;
using APT.BaseData.Domain.IServices.BD;
using APT.ECM.Domain.Entities.EM;
using APT.ECM.Domain.Entities.KR;
using APT.Infrastructure.Api.Redis;
using APT.Infrastructure.Core;
using APT.Infrastructure.Core.Refctor;
using APT.Utility;
using Aspose.Tasks;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using APT.Infrastructure.Api;
namespace APT.BD.WebApi.Controllers.Api
{
    [Route("api/BD/BDServerInfo")]
    public partial class ServerInfoController : AuthorizeApiController<T_BD_SERVER_INFO>
    {
        #region 系统主页

        /// <summary>
        /// 获取系统主页信息接口数据
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [HttpPost, Route("GetCompanyEnergy")]
        public JsonActionResult<CompanyIndexModel> GetCompanyEnergy([FromBody] KeywordFilter filter)
        {
            return SafeExecute<CompanyIndexModel>(() =>
            {
                CompanyIndexModel result = new CompanyIndexModel();
                if (string.IsNullOrEmpty(filter.Parameter2) || string.IsNullOrEmpty(filter.Parameter3))
                    return null;
                var st = DateTime.Parse(filter.Parameter2);
                var et = DateTime.Parse(filter.Parameter3);
                var fieldFilter = new BaseFilter(filter.OrgId);
                fieldFilter.SelectField = new string[] { "CONS_DATA" };
                //能源信息
                //var energyNum = this.GetEntities<T_EM_ENERGY_DOSAGE_DAY>(c => c.TIME >= st && c.TIME <= et, fieldFilter).Sum(d => d.CONS_DATA);

                var types = this.GetEntities<T_BD_ENERGY_TYPE>(x => x.ENABLE_STATUS == (int)FMEnableStatusEnum.启用,
                    new BaseFilter(filter.OrgId), "Nav_UnitEnumItem").OrderBy(x => x.NAME);

                var attrs = this.GetEntities<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点, 
                    new BaseFilter(filter.OrgId), "Nav_VariableAttr");
                var meterApp = new List<Guid>();
                var deductApp = new List<Guid>();
                var serice = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<IBDMeterNodeService>();
                foreach (var type in types)
                {
                    var nodes = serice.GetCalMeterNode(null, type.ID, new BaseFilter(filter.OrgId) { DataRule = filter.DataRule});
                    foreach (var item in nodes)
                    {
                        if (item.Nav_MeterAppliances.Any())
                            meterApp.AddRange(item.Nav_MeterAppliances.Select(x => x.APPLIANCE_ID));
                        if (item.Nav_DeductAppliances.Any())
                            deductApp.AddRange(item.Nav_DeductAppliances.Select(x => x.APPLIANCE_ID));
                    }
                }
                var meterVids = meterApp.Any() ? attrs.Where(x => meterApp.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID) : new List<Guid>();
                var deductVids = deductApp.Any() ? attrs.Where(x => deductApp.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID) : new List<Guid>();
                var report = this.GetEntities<T_EM_ENERGY_DOSAGE_MONTH>(c => c.TIME >= st && c.TIME <= et, new BaseFilter(filter.OrgId));
                var energyNum = report.Where(x=> meterVids.Contains(x.VAR_ID)).Sum(x=>x.CONS_DATA) - report.Where(x => deductVids.Contains(x.VAR_ID)).Sum(x => x.CONS_DATA);

                result.EnergyNum = energyNum.ChangeDoubleToW().ToString("f2");

                //服务信息
                //var data = this.GetEntitiesByRedis<T_BD_SERVER_INFO>(filter.OrgId ?? Guid.Empty).FirstOrDefault(s => s.IP == GetIP());

                //var redisManager = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<RedisManager>();
                if (CsRedisManager.KeyExists(RedisCacheKey.HardWareCpuInfo))
                    result.CPU = CsRedisManager.StringGet<decimal>(RedisCacheKey.HardWareCpuInfo);
                if (CsRedisManager.KeyExists(RedisCacheKey.HardWareRamInfo))
                    result.STORAGE = CsRedisManager.StringGet<decimal>(RedisCacheKey.HardWareRamInfo);
                //result.ConcurrencyNum = WebSocketServiceHelper.ClintInfos.Count;
                if (CsRedisManager.KeyExists(RedisCacheKey.HardWarePVInfo))
                    result.PVNum = CsRedisManager.StringGet<int>(RedisCacheKey.HardWarePVInfo);
                //系统信息
               // var systemData = this.GetEntitiesByRedis<T_BD_SYSTEM_INFO>(filter.OrgId ?? Guid.Empty).FirstOrDefault();
                //result.ConcurrencyNum = systemData?.CONCURRENCY ?? 0;
                //result.PVNum = systemData?.PV ?? 0;

                fieldFilter.SelectField = new string[] { "ID" };
                //报警信息
                var warnNum = this.GetCount<T_KR_ALARM_LOG>(k => k.CREATE_TIME >= st && k.CREATE_TIME <= et, fieldFilter);
                result.WarningNum = warnNum;

                //更新日志
                var param2 = new BasePageFilter(1, 5);
                param2.Sort = "CREATE_TIME";
                param2.Order = DbOrder.DESC;
                param2.OrgId = filter.OrgId;
                param2.SelectField = new string[] { "VERSION_ZH", "VERSION_NO", "CREATE_TIME" , "CONTENT" };
                var versionData = this.GetOrderPageEntities<T_PF_VERSION_MANAGE>(null, param2).Data;
                result.VersionManager = versionData.Select(v => new VersionManager
                {
                    Version = v.VERSION_NO,
                    Content = v.CONTENT,
                    Version_ZH = v.VERSION_ZH,
                    CreateTime = v.CREATE_TIME
                }).ToList();

                //运用流程
                result.UseProcess = new List<UseProcess>();
                fieldFilter.SelectField = new string[] { "ID", "IS_LEAF", "IS_LEAF", "NAME", "PARENT_ID", "Nav_MenuForm.TABLE_NAME", "IS_INIT_REQ" };
                var useProData = this.GetEntities<T_PF_MENU>(null, filter, "Nav_MenuForm").Where(m => m.IS_INIT_SHOW == true
                && ((m.ENABLE_STATUS ?? 0) == Convert.ToInt32(FMEnableStatusEnum.启用)));
                result.UseProcess = useProData.Where(u => !u.IS_LEAF).OrderBy(e => e.NUM).Select(s => new UseProcess
                {
                    PName = s.NAME,
                    UseChildren = useProData.Where(p => p.IS_LEAF && p.PARENT_ID == s.ID
                    && p.Nav_MenuForm != null).OrderBy(c => c.NUM).Select(t => new UseChildren
                    {
                        PName = t.NAME,
                        ApiFormName = t.Nav_MenuForm.TABLE_NAME,
                        FromObj = t.Nav_MenuForm,
                        IsReq = t.IS_INIT_REQ,
                        BgColor = "#f2f2f2"
                    }).ToList()
                }).ToList();

                foreach (var item in result.UseProcess)
                {
                    foreach (var ite in item.UseChildren)
                    {
                        if (string.IsNullOrEmpty(ite.ApiFormName))
                            continue;

                        try
                        {
                            Type type = ReflectHelper.FindTypeInCurrentDomain(ite.ApiFormName);
                            var methodInfo = this.GetType().GetMethod("GetBgEntity", BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static);

                            var count = methodInfo.MakeGenericMethod(new Type[] { type }).Invoke(this, new object[] { filter.OrgId });
                            if (Convert.ToInt32(count) > 0)
                                ite.BgColor = "#bccadf";
                        }
                        catch (Exception)
                        {
                            //throw;
                        }


                    }
                }
                return result;
            });
        }

        #endregion

        #region 方法

        public int GetBgEntity<T>(Guid orgId) where T : MesEntityBase, new()
        {
            BaseFilter filter = new BaseFilter();
            return this.GetCount<T>(c => c.IS_DELETED == false && c.ORG_ID == orgId, filter);
        }

        public static string GetIP()
        {
            ///获取本地的IP地址
            string AddressIP = string.Empty;
            foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
                {
                    AddressIP = _IPAddress.ToString();
                }
            }
            return AddressIP;
        }

        ///// <summary>
        ///// 获取模块数据进行返回显示颜色
        ///// </summary>
        ///// <param name="url"></param>
        ///// <param name="model"></param>
        ///// <returns></returns>
        //public string GetBgColor<T>()
        //{
        //    if (t == null)
        //        return "#facd91";
        //    //获取数据
        //    this.GetEntities<tObj>
        //    if (returnText.Contains("errcode"))
        //        //可能发生错误 
        //        return "#facd91";
        //    if (string.IsNullOrEmpty(returnText))
        //        return "#bccadf";
        //    //Response.Write(returnText); 
        //    return returnText;
        //}

        #endregion
    }
}
