using Com.FirmLib.Bll;
using Com.FirmLib.Entity;
using Com.FirmLib.UI.Common.Model;
using FWindSoft.DataFramework;
using Newtonsoft.Json.Linq;
using SAGA.DotNetUtils;
using SAGA.DotNetUtils.Extend;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Com.FirmLib.UI.BllCommon
{
    /// <summary>
    /// 资产管理相关
    /// </summary>
    public static class AssetManager
    {
        public static int PerPageCount { get; set; } = 100;
        #region 提供值函数
        public static Dictionary<string, Func< AssetShowItem, JToken>> ValuesProvider { get; private set; } = new Dictionary<string, Func<AssetShowItem, JToken>>();
        static AssetManager()
        {
            InitValuesProvider();
        }
        private static void InitValuesProvider()
        {
            ValuesProvider.Add(MBIBuiltInParameter.DPInsuerID, si => si.InsuerId);
            ValuesProvider.Add(MBIBuiltInParameter.InsuranceNum, si => si.InsurancePolicyNo);
              ValuesProvider.Add(MBIBuiltInParameter.DPMaintainerID, si => si.MaintainerId);
              ValuesProvider.Add(MBIBuiltInParameter.DPSellerID, si => si.SellerId);
              ValuesProvider.Add(MBIBuiltInParameter.DPManufacturerID, si => si.ManufacturerId);
            ValuesProvider.Add(MBIBuiltInParameter.MaintainDeadline, si => si.MaintainerEndDate);
            ValuesProvider.Add(MBIBuiltInParameter.MaintainPeriod, si => si.MaintainPeriod);

            ValuesProvider.Add(MBIBuiltInParameter.PurchasePrice, si => si.ProcurementPrice);
            ValuesProvider.Add(MBIBuiltInParameter.Warranty, si => si.Warranty);
       

              ValuesProvider.Add(MBIBuiltInParameter.AssetID, si => si.AssetNo);
            ValuesProvider.Add(MBIBuiltInParameter.DPSpecificationID, si => si.TypeId);

            ValuesProvider.Add(MBIBuiltInParameter.EquipLocalName, si => si.LocalName);
            ValuesProvider.Add(MBIBuiltInParameter.EquipLocalID, si => si.LocalCode);
            ValuesProvider.Add(MBIBuiltInParameter.ProductDate, si => si.ProductionDate);
            ValuesProvider.Add(MBIBuiltInParameter.SerialNum, si => si.ManufacturingNo);
        
             ValuesProvider.Add(MBIBuiltInParameter.SupplierContractID, si => si.SellerContractNo);
        }
        public static JToken GetValue(this AssetShowItem item, string parameterId)

        {
            if (!ValuesProvider.TryGetValue(parameterId, out Func<AssetShowItem, JToken> func))
            {
                return null;
            }
            return func(item);
        }
        #endregion
        /// <summary>
        /// 增加参数值信息
        /// </summary>
        /// <param name="jobject"></param>
        /// <param name="parameter"></param>
        /// <param name="item"></param>
        private static void AddAssetValue(AssetShowItem item,JObject jobject, WatchParameter parameter)
        {
            var jtoken = item.GetValue(parameter.Id);
            JObject value = null;

            
            if (parameter.ValidTime)
            {
                //增加生效时间
                value=ParameterUtil.GetMbiInfo(jtoken, parameter.UpdateTime);
            }
            else
            {
                
                    value=ParameterUtil.GetMbiInfo(jtoken);
            }
            JArray jArray = new JArray();
            jArray.Add(value);
            jobject[parameter.Id] = jArray;
        }

        public static JObject CalcAssetValue(AssetShowItem item)
        {
            JObject jobejct=new JObject();
            var parameters = item.CacheParameters;
            foreach (var watchParameter in parameters)
            {
                AddAssetValue(item,jobejct,watchParameter);
            }

            return jobejct;
        }

        public static AssetShowItem ConvertToShowItem(this TdAssetItem assetItem)
        {
            AssetShowItem item = new AssetShowItem();
            item.Id = assetItem.Id;        
            item.FamilyCode = assetItem.FamilyCode;
            if (string.IsNullOrEmpty(item.FamilyCode))
            {
                 item.FamilyCode = assetItem.Category;
            }

            var jobject = assetItem.Infos;
            item.EquipName = jobject.GetValueEx(MBIBuiltInParameter.EquipName).ToString();

            item.InsuerId= jobject.GetValueEx(MBIBuiltInParameter.DPInsuerID).ToString();
            item.MaintainerId= jobject.GetValueEx(MBIBuiltInParameter.DPMaintainerID).ToString();
            item.SellerContractNo= jobject.GetValueEx(MBIBuiltInParameter.SupplierContractID).ToString();
            item.TypeId= jobject.GetValueEx(MBIBuiltInParameter.DPSpecificationID).ToString();
            item.SellerId=jobject.GetValueEx(MBIBuiltInParameter.DPSellerID).ToString();

            item.AssetNo = jobject.GetValueEx(MBIBuiltInParameter.AssetID).ToString();
            item.LocalCode = jobject.GetValueEx(MBIBuiltInParameter.EquipLocalID).ToString();
            item.LocalName = jobject.GetValueEx(MBIBuiltInParameter.EquipLocalName).ToString();
            item.Brand = jobject.GetValueEx(MBIBuiltInParameter.Brand).ToString();
           // item.Product = jobject.GetValueEx(MBIBuiltInParameter.Specification).ToString();
            item.Type = jobject.GetValueEx(MBIBuiltInParameter.Specification).ToString();
            item.ProductionDate = jobject.GetValueEx(MBIBuiltInParameter.ProductDate).ToString();
            item.ManufacturingNo = jobject.GetValueEx(MBIBuiltInParameter.SerialNum).ToString();
            item.MaintainPeriod = jobject.GetValueEx(MBIBuiltInParameter.MaintainPeriod).ToString().ToDouble();
            item.Warranty = jobject.GetValueEx(MBIBuiltInParameter.Warranty).ToDouble();
            item.SellerName = jobject.GetValueEx(MBIBuiltInParameter.Supplier);
            item.ProcurementPrice = jobject.GetValueEx(MBIBuiltInParameter.PurchasePrice).ToDouble();
            return item;
        }

        public static TdAssetItem ConvertToAssetItem(this AssetShowItem showItem)
        {
            TdAssetItem assetItem = new TdAssetItem();
            if (!string.IsNullOrEmpty(showItem.Id))
            {
                assetItem.Id = showItem.Id;
            }
            assetItem.FamilyCode = showItem.FamilyCode;
            assetItem.Infos =CalcAssetValue(showItem);
            //assetItem.Infos.Add(MBIBuiltInParameter.DPSpecificationID, showItem.TypeId);
            //assetItem.Infos.Add(MBIBuiltInParameter.PurchasePrice, showItem.ProcurementPrice);
            //assetItem.Infos.Add(MBIBuiltInParameter.Warranty, showItem.MaintenancePeriod);
            //assetItem.Infos.Add(MBIBuiltInParameter.EquipLocalID, showItem.LocalCode);
            //assetItem.Infos.Add(MBIBuiltInParameter.EquipLocalName, showItem.LocalName);
            //assetItem.Infos.Add(MBIBuiltInParameter.AssetID, showItem.AssetNo);
            //assetItem.Infos.Add(MBIBuiltInParameter.SerialNum, showItem.ManufacturingNo);
            //assetItem.Infos.Add(MBIBuiltInParameter.ProductDate, showItem.ProductionDate);
            return assetItem;

        }
        /// <summary>
        /// 获取分页的资产数据
        /// </summary>
        /// <param name="projectId"></param>
        /// <param name="localName"></param>
        /// <param name="startIndex"></param>
        /// <returns></returns>
        public static SearchResultList<AssetShowItem> GetShowItems(string projectId,string localName,int startIndex)
        {
            SearchResultList<AssetShowItem> items = new SearchResultList<AssetShowItem>();
            ProjectSetting ps = new ProjectSetting(projectId);
            SearchLimit limit = new SearchLimit() { SkipCount = startIndex, GetCount = PerPageCount };
            SearchFilter filter = new SearchFilter();
            filter.AttachObject = new JObject();
            if (!string.IsNullOrEmpty(localName))
            {
                filter.AttachObject.Add(MBIBuiltInParameter.EquipLocalName, localName);
            }
            SearchCriteria criteria = new SearchCriteria();
            criteria.AttachObject = new JObject();
            criteria.AttachObject.Add("id", projectId);
            criteria.AttachObject.Add("family", JArray.FromObject(new List<string>()));
            var originItems = BllFactory<PlatformBll>.Instance.GetAssetItems(ps, limit, filter,criteria);
            items.AddRange(originItems.Select(c =>
            {
                var item=c.ConvertToShowItem();
                item.ProjectId = projectId;
                return item;
            }));
            items.TotalCount = originItems.TotalCount;
            return items;
        }


        public static bool UpdateAssetItems(string projectId, List<AssetShowItem> items)
        {
            if (items == null ||! items.Any())
            {
                return true;
            }
            List<TdAssetItem> assetItems = items.Select(ConvertToAssetItem).ToList();
            ProjectSetting ps = new ProjectSetting(projectId) ;
           return BllFactory<PlatformBll>.Instance.UpdateAssetItems(ps, assetItems);       
        }



        #region 删除资产相关
        public static bool  DeleteSellerAssets(string projectId, List<string> assetIds)
        {
            List<string> parameterIds = new List<string>();
            parameterIds.Add(MBIBuiltInParameter.DPSellerID);
            parameterIds.Add(MBIBuiltInParameter.SupplierContractID);
            return DeleteAssets(projectId, assetIds, parameterIds);
        }
        
        public static bool DeleteInsuerAssets(string projectId, List<string> assetIds)
        {
            List<string> parameterIds=new List<string>();
            parameterIds.Add(MBIBuiltInParameter.DPInsuerID);
            parameterIds.Add(MBIBuiltInParameter.InsuranceNum);
            return DeleteAssets(projectId,assetIds,parameterIds);
        }
        public static bool DeleteAssets(string projectId, List<string> assetIds,List<string> parameterIds)
        {
            List<TdAssetItem> assetItems = new List<TdAssetItem>();
            ProjectSetting ps = new ProjectSetting(projectId);
            foreach (var assetId in assetIds)
            {
                TdAssetItem assetItem = new TdAssetItem();
                assetItem.Id = assetId;
                JObject jo = new JObject();
                foreach (var parameterId in parameterIds)
                {
                    jo[parameterId] = ParameterUtil.CreateEmptyMbiInfo();

                }
                assetItem.Infos = jo;
                assetItems.Add(assetItem);
            }
            return BllFactory<PlatformBll>.Instance.UpdateAssetItems(ps, assetItems);
        }
        #endregion

        /// <summary>
        /// 获取推荐信息
        /// </summary>
        /// <param name="projectId"></param>
        /// <param name="localName"></param>
        /// <param name="startIndex"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        public static SearchResultList<AssetShowItem> GetRecommendShowItems(string projectId, string localName,
            int startIndex,VenderItem item)
        {
            SearchResultList<AssetShowItem> items = new SearchResultList<AssetShowItem>();
            ProjectSetting ps = new ProjectSetting(projectId);
            //SearchLimit limit = new SearchLimit() { SkipCount = startIndex, GetCount = PerPageCount+1 };
            SearchLimit limit = new SearchLimit() { SkipCount = startIndex, GetCount = PerPageCount };
            SearchFilter filter = new SearchFilter();
            filter.AttachObject = new JObject();
            if (!string.IsNullOrEmpty(localName))
            {
                filter.AttachObject.Add(MBIBuiltInParameter.EquipLocalName, localName);
            }
            SearchCriteria criteria = new SearchCriteria();
            criteria.AttachObject = new JObject();
            criteria.AttachObject.Add("venderId", item.Id);
            criteria.AttachObject.Add("venderType", item.Type);
            criteria.AttachObject.Add("venderName", item.Name);
            var originItems = BllFactory<PlatformBll>.Instance.GetRecomendAssetItems(ps, limit, filter, criteria);
            items.AddRange(originItems.Select(c =>
            {
                var tempItem = c.ConvertToShowItem();
                tempItem.ProjectId = projectId;
                return tempItem;
            }));
            items.TotalCount =startIndex+ items.Count;
            if (items.Count>PerPageCount)
            {
                items.RemoveAt(items.Count);
            }
            return items;
        }

        #region 设备相关操作
        //GetEquipmentItems
        /// <summary>
        /// 获取分页的设备数据数据
        /// </summary>
        /// <param name="projectId"></param>
        /// <param name="localName"></param>
        /// <param name="startIndex"></param>
        /// <returns></returns>
        public static SearchResultList<AssetShowItem> GetShowEqItems(string projectId, string localName, int startIndex)
        {
            SearchResultList<AssetShowItem> items = new SearchResultList<AssetShowItem>();
            ProjectSetting ps = new ProjectSetting(projectId) ;
            SearchLimit limit = new SearchLimit() { SkipCount = startIndex, GetCount = PerPageCount };
            SearchFilter filter = new SearchFilter();
            SearchCriteria criteria = new SearchCriteria();
            criteria.AttachObject = new JObject();
            //criteria.AttachObject.Add("id", projectId);
            //criteria.AttachObject.Add("family", JArray.FromObject(new List<string>()));
            criteria.AttachObject.Add("name", localName);
            var originItems = BllFactory<PlatformBll>.Instance.GetEquipmentItems(ps, limit, filter, criteria);
            items.AddRange(originItems.Select(c =>
            {
                var item = c.ConvertToShowItem();
                item.ProjectId = projectId;
                item.FamilyCode = c.Category;
                return item;
            }));
            items.TotalCount = originItems.TotalCount;
            return items;
        }

        /// <summary>
        /// 更新设备信息
        /// </summary>
        /// <param name="projectId"></param>
        /// <param name="items"></param>
        /// <returns></returns>
        public static bool UpdateEqItems(string projectId, List<AssetShowItem> items)
        {
            List<TdAssetItem> assetItems = items.Select(ConvertToAssetItem).ToList();
            ProjectSetting ps = new ProjectSetting(projectId) ;
            return BllFactory<PlatformBll>.Instance.UpdateEquipmentItems(ps, assetItems);
        }
        /// <summary>
        /// 删除维修设备
        /// </summary>
        /// <param name="projectId"></param>
        /// <param name="eqIds"></param>
        /// <returns></returns>
        public static bool DeleteMaintainerEquipments(string projectId, List<string> eqIds)
        {
            #region 参数选定
            List<string> parameterIds = new List<string>();
            parameterIds.Add(MBIBuiltInParameter.DPMaintainerID);
            #endregion
            List<TdAssetItem> assetItems = new List<TdAssetItem>();
            ProjectSetting ps = new ProjectSetting(projectId) ;
            foreach (var eqId in eqIds)
            {
                TdAssetItem assetItem = new TdAssetItem();
                assetItem.Id = eqId;
                JObject jo = new JObject();
                foreach (var parameterId in parameterIds)
                {
                    jo[parameterId] = ParameterUtil.CreateEmptyMbiInfo();

                }
                assetItem.Infos = jo;
                assetItems.Add(assetItem);
            }
            return BllFactory<PlatformBll>.Instance.UpdateEquipmentItems(ps, assetItems);
        }
        #endregion
    }
}
