using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using FactorySystemCommon;
using FactorySystemModel.EnumModel;
using FactorySystemModel.SqlSugarModel;
using Newtonsoft.Json;
using SqlSugar;

namespace FactorySystemBll
{
    public class PackageBll
    {
        /// <summary>
        /// 获取包材信息
        /// </summary>
        public object GetPackageInfo(int teamId)
        {
            SqlSugarClient db = AppSettingsHelper.GetSqlSugar();
            TFS_FTeamwork teamwork = db.Queryable<TFS_FTeamwork>().Where(s => s.FID == teamId).First();
            TFS_PackageMain main;
            if (teamwork.FPackID > 0) main = db.Queryable<TFS_PackageMain>().Where(s => s.FID == teamwork.FPackID).First();
            else main = db.Queryable<TFS_PackageMain>().Where(string.Format("FID=(select FPackID from TFS_FTeamwork where FID={0})", teamId)).First();
            if (main != null)
            {
                List<TFS_PackageChild> childs = db.Queryable<TFS_PackageChild>().Where(s => s.FPackageID == teamwork.FPackID && s.FDeleted != 1).ToList();
                return new
                {
                    Main = main,
                    FCode = teamwork.FPackCode,
                    List = childs.Count == 0 ? new List<TFS_PackageChild>() : childs
                };
            }
            return new { FCode = teamwork.FPackCode };
        }

        /// <summary>
        /// 修改包材主信息
        /// </summary>
        public int UpdatePackageData(Dictionary<string, object> inParam)
        {
            int mainId = -1;
            try
            {
                SqlSugarClient db = AppSettingsHelper.GetSqlSugar();
                TFS_PackageMain main = db.Queryable<TFS_PackageMain>().Where(s => s.FCode == inParam["FCode"].ToString()).First();
                if (main == null)
                {
                    main = new TFS_PackageMain();
                    SetFieldVal(typeof(TFS_PackageMain).GetProperties(), main, inParam);
                    main.FID = db.Insertable(main).AS("TFS_PackageMain").IgnoreColumns(true).ExecuteReturnIdentity();
                }
                else
                {
                    SetFieldVal(typeof(TFS_PackageMain).GetProperties(), main, inParam);
                    inParam.Add("FEditDate", DateTime.Now);
                    db.Updateable(main).AS("TFS_PackageMain").Where(s => s.FID == main.FID).ExecuteCommand();
                }

                mainId = main.FID;
                int teamId = int.Parse(inParam["FTeamID"].ToString());
                //2022-10-08 所谓的成品字段值是包材的规格、毛重、净重
                db.Ado.ExecuteCommand(string.Format(@"update a set a.FBaseSpecification=isnull(b.FSpecs,''),
                    a.FBaseGrossWeight=isnull(b.FGrossWeight,''),a.FBaseNetWeight=isnull(b.FNetWeight,'') from 
                    TFS_ViewMaterial a,TFS_PackageMain b where a.FTeamID={0} and b.FID={1} and a.FViewType=1", teamId, mainId));
                db.Updateable<TFS_FTeamwork>(new { FPackID = mainId, FPackCode = main.FCode }).Where(s => s.FID == teamId).ExecuteCommand();
            }
            catch (Exception) { }
            return mainId;
        }

        /**
         * 20230404 需求变更
         * 增加包材新增、修改入口（自包材清单）
         * 此部分功能和协同无关
         * 从包材清单进入时，会带入FOperateType参数，且值为1
         * 当FOperateType == 1，即由包材清单入口进入时调用
         * **/
        public int UpdatePackage(Dictionary<string, object> inParam)
        {
            int mainId = -1;
            try
            {
                SqlSugarClient db = AppSettingsHelper.GetSqlSugar();
                TFS_PackageMain main = db.Queryable<TFS_PackageMain>().Where(s => s.FCode == inParam["FCode"].ToString()).First();
                if (main == null)
                {
                    main = new TFS_PackageMain();
                    SetFieldVal(typeof(TFS_PackageMain).GetProperties(), main, inParam);
                    main.FID = db.Insertable(main).AS("TFS_PackageMain").IgnoreColumns(true).ExecuteReturnIdentity();
                }
                else
                {
                    SetFieldVal(typeof(TFS_PackageMain).GetProperties(), main, inParam);
                    inParam.Add("FEditDate", DateTime.Now);
                    db.Updateable(main).AS("TFS_PackageMain").Where(s => s.FID == main.FID).ExecuteCommand();
                }

                mainId = main.FID;
            }
            catch (Exception) { }
            return mainId;
        }

        /// <summary>
        /// 不补充包材信息
        /// </summary>
        public int NoSupplyPackageChild(Dictionary<string, object> inParam)
        {
            //直接进度完成不让修改
            int teamId = int.Parse(inParam["FTeamID"].ToString());
            string taskSql = BaseBll.GetTaskSql(-1, 2, teamId, (int)Constant.TaskType.补充包材规格, 2);
            SqlSugarClient db = AppSettingsHelper.GetSqlSugar();
            int result = db.Ado.ExecuteCommand(taskSql);
            TeamworkBll.ChangeTeamProcess(teamId, db);
            return result;
        }

        /// <summary>
        /// 包材子项新增
        /// </summary>
        public int InsertChildData(Dictionary<string, object> inParam, List<TFS_PackageChild> childList)
        {
            SqlSugarClient db = AppSettingsHelper.GetSqlSugar();
            db.BeginTran();
            int childId = -1;
            try
            {
                int userId = int.Parse(inParam["FEditUser"].ToString());
                int mainId = int.Parse(inParam["FID"].ToString());
                int teamId = int.Parse(inParam["FTeamID"].ToString());
                {
                    List<TFS_PackageChild> updateList = childList.Where(s => s.FID > 0).ToList();
                    //删除已删除的
                    List<int> updateIds = updateList.Count > 0 ? updateList.Select(s => s.FID).ToList() : new List<int>() { -1 };
                    db.Updateable<TFS_PackageChild>(new { FDeleted = 1, FEditUser = userId, FEditDate = DateTime.Now })
                        .Where(s => !updateIds.Contains(s.FID) && s.FPackageID == mainId && s.FDeleted != 1).ExecuteCommand();
                }
                TFS_FTeamwork teamwork = db.Queryable<TFS_FTeamwork>().Where(s => s.FID == teamId).First();
                bool hasTask = false;//是否创建“新子项包材申请”
                List<int> viewFactory = new List<int>();//视图分工厂
                foreach (TFS_PackageChild child in childList)
                {
                    child.FPackageID = mainId;
                    child.FEditUser = userId;
                    if (child.FID <= 0)
                    {
                        if (child.FMaterialID <= 0) child.FMaterialID = -1;
                        child.FID = db.Insertable(child).IgnoreColumns(true).ExecuteReturnIdentity();
                    }
                    if (child.FMaterialID > 0)
                    {
                        TFS_Material material = null;
                        List<TFS_ViewMaterial> viewList = db.Queryable<TFS_ViewMaterial>().Where(s => s.FMaterialID == child.FMaterialID
                        && s.FDeleted != 1).ToList();
                        bool hasCreate = false;
                        if (viewList.Find(s => s.FFactoryID == teamwork.FCreateFactoryID) == null)
                        {
                            hasCreate = true;
                            if (viewFactory.IndexOf(teamwork.FCreateFactoryID) == -1) viewFactory.Add(teamwork.FCreateFactoryID);
                            if (material == null) db.Queryable<TFS_Material>().Where(s => s.FID == child.FMaterialID).First();
                            TFS_ViewMaterial view = SetViewVal(material, teamwork, userId);
                            view.FFactoryCode = teamwork.FCreateFactoryCode;
                            view.FFactoryID = teamwork.FCreateFactoryID;
                            db.Insertable(view).IgnoreColumns(true).ExecuteCommand();
                        }
                        if (viewList.Find(s => s.FFactoryID == teamwork.FProdFactoryID) == null)
                        {
                            if (viewFactory.IndexOf(teamwork.FProdFactoryID) == -1) viewFactory.Add(teamwork.FProdFactoryID);
                            if (material == null) db.Queryable<TFS_Material>().Where(s => s.FID == child.FMaterialID).First();
                            TFS_ViewMaterial view = SetViewVal(material, teamwork, userId);
                            view.FFactoryCode = teamwork.FProdFactoryCode;
                            view.FFactoryID = teamwork.FProdFactoryID;
                            if (hasCreate) view.FQualityType4 = "05";
                            else view.FQualityType1 = "01";
                            db.Insertable(view).IgnoreColumns(true).ExecuteCommand();
                        }
                    }
                    else
                    {
                        hasTask = true;
                    }
                }
                //删除视图
                db.Deleteable<TFS_ViewMaterial>().Where(s => s.FTeamID == teamId && s.FViewType == (int)Constant.ViewType.包材视图)
                    .Where(string.Format("FMaterialID not in(select FMaterialID from TFS_PackageChild where FPackageID={0} and FDeleted!=1)", mainId))
                    .ExecuteCommand();
                if (hasTask)
                {
                    BaseBll.CreateTaskData(teamId, userId, "10");
                }

                if (viewFactory.Count > 0)
                {
                    BaseBll.CreateTaskData(teamId, userId, "11", string.Join(",", viewFactory));
                }
                db.CommitTran();
            }
            catch (Exception)
            {
                db.RollbackTran();
            }
            return childId;
        }

        /**
         * 20230404 需求变更
         * 增加包材新增、修改入口（自包材清单）
         * 此部分功能和协同无关
         * 从包材清单进入时，会带入FOperateType参数，且值为1
         * 当FOperateType == 1，即由包材清单入口进入时调用
         * **/

        // 根据包规获取包材 20230421
        public TFS_PackageMain GetPackageByFCode(string FCode)
        {
            SqlSugarClient db = AppSettingsHelper.GetSqlSugar();
            return db.Queryable<TFS_PackageMain>().Where(s => s.FCode == FCode).First();
        }

        // 新的包材子项新增
        public void InsertPackageChild(Dictionary<string, object> inParam, List<TFS_PackageChild> childList)
        {            
            try
            {
                SqlSugarClient db = AppSettingsHelper.GetSqlSugar();
                int userId = int.Parse(inParam["FEditUser"].ToString());
                int mainId = int.Parse(inParam["FID"].ToString());

                foreach (TFS_PackageChild child in childList)
                {
                    child.FPackageID = mainId;
                    child.FEditUser = userId;
                    db.Insertable(child).IgnoreColumns(true).ExecuteReturnIdentity();
                }
            }
            catch (Exception ex)
            {

            }
        }

        // 新的包材子项更新（包括逻辑删除）
        public void UpdatePackageChild(Dictionary<string, object> inParam, List<TFS_PackageChild> childList)
        {
            try
            {
                SqlSugarClient db = AppSettingsHelper.GetSqlSugar();
                int userId = int.Parse(inParam["FEditUser"].ToString());
                int mainId = int.Parse(inParam["FID"].ToString());

                foreach (TFS_PackageChild child in childList)
                {
                    child.FEditUser = userId;
                    child.FEditDate = DateTime.Now;
                }

                db.Updateable<TFS_PackageChild>(childList).ExecuteCommand();

                //db.Updateable<TFS_PackageChild>(new { 
                    
                //    FEditUser = userId,
                //    FEditDate = DateTime.Now
                //}).Where(s => s.FPackageID == mainId && s.FDeleted != 1).ExecuteCommand();
            }
            catch (Exception ex)
            {

            }
        }

        /// <summary>
        /// 导入包材
        /// </summary>
        public object InsertBatchPackageData(List<TFS_PackageMain> mainList, List<TFS_PackageChild> childList, int userId)
        {
            int result = 0;
            SqlSugarClient db = AppSettingsHelper.GetSqlSugar();

            List<TFS_PackageMain> mainList2 = new List<TFS_PackageMain>();
            List<TFS_PackageChild> childList2 = new List<TFS_PackageChild>();

            for (int i = 0; i < mainList.Count; i++)
            {
                TFS_PackageMain item = mainList[i];
                TFS_PackageMain main = db.Queryable<TFS_PackageMain>().Where(s => s.FCode == item.FCode).First();
                if (main == null)
                {
                    main = item;
                    main.FEditUser = userId;
                    main.FFactoryID = -1;
                    main.FID = db.Insertable(main).IgnoreColumns(true).ExecuteReturnIdentity();
                }
                else if (mainList2.Find(s => s.FID == main.FID) == null)
                {
                    main.FFactoryCode = string.IsNullOrEmpty(item.FFactoryCode) ? main.FFactoryCode : item.FFactoryCode;
                    main.FCode = string.IsNullOrEmpty(item.FCode) ? main.FCode : item.FCode;
                    main.FBomUnit = string.IsNullOrEmpty(item.FBomUnit) ? main.FBomUnit : item.FBomUnit;
                    main.FRemark = string.IsNullOrEmpty(item.FRemark) ? main.FRemark : item.FRemark;
                    main.FSpecs = string.IsNullOrEmpty(item.FSpecs) ? main.FSpecs : item.FSpecs;
                    main.FNetWeight = GetWeight2(string.IsNullOrEmpty(item.FNetWeight) ? main.FNetWeight : item.FNetWeight);
                    main.FGrossWeight = GetWeight2(string.IsNullOrEmpty(item.FGrossWeight) ? main.FGrossWeight : item.FGrossWeight);
                    main.FSize = string.IsNullOrEmpty(item.FSize) ? main.FSize : item.FSize;
                    main.FVolume = string.IsNullOrEmpty(item.FVolume) ? main.FVolume : item.FVolume;
                    db.Updateable(main).ExecuteCommand();
                }
                TFS_PackageChild item2 = childList[i];
                TFS_PackageChild child = db.Queryable<TFS_PackageChild>().Where(s => s.FCode == item2.FCode && s.FPackageID == main.FID).First();

                TFS_Material material = db.Queryable<TFS_Material>().Where(s => s.FCode == item2.FCode).First();
                if (child == null)
                {
                    child = item2;
                    child.FPackageID = main.FID;
                    child.FMaterialID = material != null ? material.FID : -1;
                    child.FEditUser = userId;
                    child.FID = db.Insertable(child).IgnoreColumns(true).ExecuteReturnIdentity();
                }
                else
                {
                    child.FPackageID = main.FID;
                    child.FMaterialID = material != null ? material.FID : -1;
                    child.FName = !string.IsNullOrEmpty(item2.FName) ? item2.FName : child.FName;
                    child.FCode = !string.IsNullOrEmpty(item2.FCode) ? item2.FCode : child.FCode;
                    child.FCount = !string.IsNullOrEmpty(item2.FCount) ? item2.FCount : child.FCount;
                    child.FUnit = !string.IsNullOrEmpty(item2.FUnit) ? item2.FUnit : child.FUnit;
                    child.FGroup = !string.IsNullOrEmpty(item2.FGroup) ? item2.FGroup : child.FGroup;
                    child.FOutSize = !string.IsNullOrEmpty(item2.FOutSize) ? item2.FOutSize : child.FOutSize;
                    child.FWeight = !string.IsNullOrEmpty(item2.FWeight) ? item2.FWeight : child.FWeight;
                    db.Updateable(child).ExecuteCommand();
                }
                mainList2.Add(main);
                childList2.Add(child);
                result += 1;
            }
            ExceptionHelper.AddSystemJournal(null, new { mainList, childList }, new { mainList2, childList2 }, userId, "InsertBatchPackageData");
            return result;
        }

        private string GetWeight2(string weight)
        {
            if (string.IsNullOrEmpty(weight)) return "";
            try
            {
                if (decimal.TryParse(weight, out decimal dWeight))
                {
                    return Math.Round(dWeight, 2, MidpointRounding.AwayFromZero).ToString("f2");
                }
            }
            catch (Exception) { }
            return weight;
        }
        /// <summary>
        /// 包材新增完成
        /// </summary>
        public void TaskCompleted(Dictionary<string, object> inParam)
        {
            int taskId = int.Parse(inParam["FTaskID"].ToString()); ;
            int teamId = int.Parse(inParam["FTeamID"].ToString());
            string taskSql = BaseBll.GetTaskSql(taskId, 2, teamId, (int)Constant.TaskType.新包材新增);
            SqlSugarClient db = AppSettingsHelper.GetSqlSugar();
            db.Ado.ExecuteCommand(taskSql);
            TeamworkBll.ChangeTeamProcess(teamId, db);
        }

        /// <summary>
        /// 对接子项代码
        /// </summary>
        public object DockChildCode(Dictionary<string, object> inParam, List<TFS_PackageChild> childs, int userId)
        {
            SqlSugarClient db = AppSettingsHelper.GetSqlSugar();
            db.BeginTran();
            int result = 0;
            try
            {
                int teamId = int.Parse(inParam["FTeamID"].ToString());
                TFS_FTeamwork teamwork = db.Queryable<TFS_FTeamwork>().Where(s => s.FID == teamId).First();
                foreach (var item in childs)
                {
                    TFS_Material material = new TFS_Material()
                    {
                        FName = item.FName,
                        FType = "40",
                        FTestCode = "",
                        FFactoryID = teamwork.FCreateFactoryID,
                        FFactoryCode = teamwork.FCreateFactoryCode,
                        FMaterialGroup = item.FGroup,
                        FBaseUnit = item.FUnit,
                        FCode = item.FCode
                    };
                    material.FID = db.Insertable(material).IgnoreColumns(true).ExecuteReturnIdentity();
                    item.FAddDate = null;
                    item.FMaterialID = material.FID;
                    item.FCode = material.FCode;
                    item.FEditUser = userId;
                    item.FEditDate = DateTime.Now;
                    if (item.FID > 0) result += db.Updateable(item).IgnoreColumns(true).ExecuteCommand() + 1;
                    else result += db.Insertable(item).IgnoreColumns(true).ExecuteCommand() + 1;

                    TFS_ViewMaterial view = SetViewVal(material, teamwork, userId);
                    view.FBaseMaterialGroup = string.IsNullOrEmpty(material.FMaterialGroup) ? item.FGroup : "";
                    view.FFactoryCode = teamwork.FCreateFactoryCode;
                    view.FFactoryID = teamwork.FCreateFactoryID;
                    view.FBaseBasicMeter = material.FBaseUnit;
                    result += db.Insertable(view).IgnoreColumns(true).ExecuteCommand();
                    if (teamwork.FCreateFactoryID != teamwork.FProdFactoryID)
                    {
                        view.FFactoryCode = teamwork.FProdFactoryCode;
                        view.FFactoryID = teamwork.FProdFactoryID;
                        result += db.Insertable(view).IgnoreColumns(true).ExecuteCommand();
                    }
                }
                string taskSql = BaseBll.GetTaskSql(-1, 2, teamId, (int)Constant.TaskType.新子项包材申请, 2,
                    string.Format("(select count(1) from TFS_PackageChild where FPackageID={0} and FDeleted!=1 and FMaterialID<1)=0",
                    inParam["FID"].ToString()));
                if (!string.IsNullOrEmpty(taskSql))
                {
                    db.Ado.ExecuteCommand(taskSql);
                    TeamworkBll.ChangeTeamProcess(teamId, db);
                }
                string factory = teamwork.FCreateFactoryID.ToString();
                if (teamwork.FCreateFactoryID != teamwork.FProdFactoryID) factory += "," + teamwork.FProdFactoryID;
                //BaseBll.CreateTaskData(teamId, userId, "11", factory, true, db);
                db.CommitTran();
            }
            catch (Exception)
            {
                db.RollbackTran();
            }
            return result;
        }

        /// <summary>
        /// 设置视图值
        /// </summary>
        private TFS_ViewMaterial SetViewVal(TFS_Material material, TFS_FTeamwork teamwork, int userId)
        {
            TFS_ViewMaterial view = new TFS_ViewMaterial()
            {
                FMaterialID = material.FID,
                FTeamID = teamwork.FID,
                FViewType = (int)Constant.ViewType.包材视图,
                FLevel = 1,
                FEditUser = userId,
                FAddDate = DateTime.Now,
                FBaseMaterialCode = string.IsNullOrEmpty(material.FPlmCode) ? material.FCode : material.FPlmCode,
                FBaseTestCode = material.FTestCode,
                FBaseMaterialDesc = material.FName
            };
            return view;
        }

        /// <summary>
        /// 类属性赋值
        /// </summary>
        private void SetFieldVal(PropertyInfo[] props, object dataObj, Dictionary<string, object> inParam)
        {
            foreach (PropertyInfo prop in props)
            {
                if (inParam.ContainsKey(prop.Name))
                {
                    object value = inParam[prop.Name];
                    if (prop.PropertyType.Name == "Decimal")
                    {
                        prop.SetValue(dataObj, ((decimal)value).ToString("#0.00"));
                    }
                    else if (prop.PropertyType.Name == "Int32" || prop.PropertyType.Name == "Int64")
                    {
                        prop.SetValue(dataObj, int.Parse(value.ToString()));
                    }
                    else
                    {
                        prop.SetValue(dataObj, value);
                    }
                }
            }
        }
    }
}
