using FactorySystemBll;
using FactorySystemCommon;
using FactorySystemModel.BusinessModel;
using FactorySystemModel.ResponseModel;
using FactorySystemModel.SqlSugarModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Web.Http;
using FactorySystemModel.EnumModel;
using System.IO;
using System.Threading.Tasks;

namespace FactorySystemApi.Controllers
{
    /// <summary>
    /// 物料接口
    /// </summary>
    [UserLoginFilter]
    public class MaterialController : BaseController<TFS_Material>
    {
        /// <summary>
        /// 数据处理层
        /// </summary>
        public readonly MaterialBll MaterialBll = new MaterialBll();
        /// <summary>
        /// 初始化
        /// </summary>
        public MaterialController()
        {
            //设置可修改字段
            UpdateField = "FSuccedaneumID,FSuccedaneumInfo,FSuccedaneumType,FSuccedaneumCode,FFuProductsID,FFuProductsInfo,FFuProductsType,FFuProductsCode,FFuProductsCount";
        }

        /// <summary>
        /// （对接）SAP物料同步
        /// </summary>
        [HttpPost]
        public ApiResult DockSapMaterial()
        {
            ApiResult apiResult = new ApiResult
            {
                Data = 0
            };
            int result = 0;
            return ExceptionHelper.TryReturnException(() =>
            {

                List<TFS_Factory> factoryList = FactoryBll.GetFactoryList();
                if (factoryList.Count > 0)
                {
                    ApiAuthInfo user = Request.Properties["token"] as ApiAuthInfo;
                    Sap_Material1.si_mm100_mcs_senderService sapService = new Sap_Material1.si_mm100_mcs_senderService()
                    {
                        Credentials = new System.Net.NetworkCredential()
                        {
                            UserName = AppSettingsHelper.GetAppSettingVal("Sap_UserName"),
                            Password = AppSettingsHelper.GetAppSettingVal("Sap_Password")
                        }
                    };
                    Sap_Material1.dt_mm100_req reqDatas = new Sap_Material1.dt_mm100_req();
                    //委外在前面
                    factoryList = factoryList.OrderBy(s => s.FType).ToList();
                    foreach (TFS_Factory factory in factoryList)
                    {
                        reqDatas.WERKS = factory.FCode;
                        try
                        {
                            Sap_Material1.dt_mm100_res resData = sapService.si_mm100_mcs_sender(reqDatas);
                            ExceptionHelper.AddSystemJournal(Request, reqDatas, resData);
                            List<TFS_Material> materialList = new List<TFS_Material>();
                            if (resData != null && resData.DATA != null && resData.DATA.Length > 0)
                            {
                                foreach (var item in resData.DATA)
                                {
                                    string name = string.IsNullOrEmpty(item.EXTWG) ? item.MAKTX : item.EXTWG;
                                    materialList.Add(new TFS_Material()
                                    {
                                        FFactoryID = factory.FID,
                                        FFactoryCode = factory.FCode,
                                        FName = string.IsNullOrEmpty(name) ? "" : item.MAKTX,
                                        FCode = string.IsNullOrEmpty(item.MATNR) ? "" : item.MATNR,
                                        FTestCode = string.IsNullOrEmpty(item.BISMT) ? "" : item.BISMT,
                                        FBaseUnit = string.IsNullOrEmpty(item.MEINS) ? "" : item.MEINS,
                                        FMaterialGroup = string.IsNullOrEmpty(item.MATKL) ? "" : item.MATKL,
                                        FAddDate = DateTime.Now,
                                        FEditUser = user.FID,
                                        FType = string.IsNullOrEmpty(item.ZCATEG) ? "" : item.ZCATEG,//产品分类
                                        FMaterialType = string.IsNullOrEmpty(item.MTART) ? "" : item.MTART,//物料类型
                                    });
                                }
                            }
                            if (materialList.Count > 0) result += MaterialBll.DockSapMaterial(materialList, user.FID);
                        }
                        catch (Exception ex)
                        {
                            ExceptionHelper.AddSystemJournal(Request, reqDatas, ex.Message);
                        }
                    }
                    apiResult.Data = result;
                }
            }, apiResult, Request, null);
        }

        /// <summary>
        /// 对接物料数据（对方写入）
        /// </summary>
        [HttpPost]
        public ApiResult DockingMaterialData(Dictionary<string, object> inParam)
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                if (inParam == null)
                {
                    apiResult.Error("未接收到参数");
                }
                else
                {
                    List<TFS_FieldInfo> fieldList = BaseBll.GetFileInfoList((int)Constant.FieldInfoType.物料模板导入);
                    TFS_Material material = new TFS_Material();
                    List<PropertyInfo> propertys = material.GetType().GetProperties().ToList();
                    foreach (var field in fieldList)
                    {
                        PropertyInfo temp = propertys.Find(s => s.Name == field.FColumnFIeld);
                        if (temp != null) temp.SetValue(material, GetValueByName(inParam, field.FFieldName, field.FDefault));
                    }
                    if (string.IsNullOrEmpty(material.FCode))
                    {
                        apiResult.Error("FCode不能为空");
                    }
                    else if (string.IsNullOrEmpty(material.FName))
                    {
                        apiResult.Error("FName不能为空");
                    }
                    else if (string.IsNullOrEmpty(material.FMaterialGroup))
                    {
                        apiResult.Error("FMaterialGroup不能为空");
                    }
                    else
                    {
                        int userId = -1;
                        if (Request.Properties.ContainsKey("token"))
                        {
                            userId = Request.Properties["token"] is ApiAuthInfo user ? user.FID : userId;
                            List<PropertyInfo> mainProp = typeof(TFS_Material).GetTypeInfo().GetProperties().ToList();
                            apiResult.Data = MaterialBll.DockingRecipeData(new List<TFS_Material>() { material }, mainProp, userId);
                        }
                        else
                        {
                            apiResult.Error("token信息不存在");
                        }
                    }
                }
            }, apiResult, Request, inParam);
        }
        /// <summary>
        /// 根据试验号获取物料
        /// </summary>
        /// <param name="inParam"></param>
        /// <returns></returns>
        [HttpPost]
        public ApiResult GetMaterialListByFTestCode(Dictionary<string, object> inParam)
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                if (inParam == null)
                {
                    apiResult.Error("未接收到参数");
                }
                else
                {
                    if (inParam.ContainsKey("FTestCode")) 
                    {
                        apiResult.Data = MaterialBll.GetMaterialListByFTestCode(inParam["FTestCode"].ToString());
                    }
                }
            }, apiResult, Request, inParam);
        }

        /// <summary>
        /// （对接）MDM获取物料PLM码
        /// </summary>
        [HttpPost]
        public ApiResult DockMDMGetPlmCode(Dictionary<string, object> inParam)
        {

            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                apiResult.Data = GetMdmCode(inParam);
            }, apiResult, Request, inParam);
        }

        /// <summary>
        /// 查询物料
        /// </summary>
        [HttpPost]
        public ApiResult GetMaterialById(Dictionary<string, object> inParam)
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                if (inParam == null || inParam.Count < 0)
                {
                    apiResult.Error("未接收到参数");
                }
                else if (inParam.ContainsKey("ID"))
                {
                    apiResult.Data = MaterialBll.GetMaterialById(int.Parse(inParam["ID"].ToString()));
                }
                else
                {
                    apiResult.Error("缺少查询参数");
                }
            }, apiResult, Request, inParam);
        }

        /// <summary>
        /// 物料查询接口（对方查询）
        /// </summary>
        [HttpPost]
        public ApiResult SearchMaterialData(Dictionary<string, object> inParam)
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                if (inParam == null || inParam.Count < 0)
                {
                    apiResult.Error("未接收到参数");
                }
                else if (inParam.ContainsKey("FType"))
                {
                    apiResult.Data = MaterialBll.SearchMaterialData2(inParam);
                }
                else
                {
                    apiResult.Error("缺少FType参数");
                }
            }, apiResult, Request, inParam);
        }

        /// <summary>
        /// 导出视图
        /// </summary>
        /// <returns></returns>
        public ApiResult DownMateialView(Dictionary<string, object> inParam)
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                if (inParam.ContainsKey("FID"))
                {
                    inParam.TryGetValue("FViewType", out object objType);
                    //string FType = null == objType ? Constant.TeamViewType.物料视图.ToString() : objType.ToString();
                    //string selectSql = "", joinSql = "", whereSql = string.Format("TFS_FTeamwork.FID={0} ", inParam["FTeamID"]);
                    string basePath = AppDomain.CurrentDomain.BaseDirectory.Trim('\\');
                    string savePath = basePath + string.Format("\\File\\Temp\\{0}_{1}\\", inParam["FID"], "View");
                    if (!Directory.Exists(savePath)) Directory.CreateDirectory(savePath);
                    string tempPath = savePath.Replace("\\File\\Temp\\", "\\File\\View\\");
                    if (!Directory.Exists(tempPath)) Directory.CreateDirectory(tempPath);
                    savePath += ".xlsx";

                    bool hasFinish = inParam.ContainsKey("FFinish");
                    if (hasFinish) savePath = savePath.Replace("\\File\\Temp\\", "\\File\\View\\");
                    if (!File.Exists(savePath) || !hasFinish)
                    {
                        MaterialBll.CreateExeclFile(inParam["FName"].ToString() + "_全部视图", savePath, "", "", "", inParam["FID"].ToString(), "");
                    }
                    else
                    {
                        File.Delete(basePath + string.Format("\\File\\Temp\\{0}_{1}\\", inParam["FID"], "全部视图"));
                        MaterialBll.CreateExeclFile(inParam["FName"].ToString() + "_全部视图", savePath, "", "", "", inParam["FID"].ToString(), "");
                    }
                    string url = Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.AbsolutePath, "") + savePath.Replace(basePath, "").Replace("\\", "/").Replace(".xlsx", inParam["FName"].ToString() + "_全部视图" + ".xlsx");
                    apiResult.Data = url;

                }
                else
                {
                    apiResult.Error("视图信息获取失败");
                }
            }, apiResult, Request, inParam);
        }

        /// <summary>
        /// 获取物料分类
        /// </summary>
        /// <param name="inParam"></param>
        /// <returns></returns>
        [HttpPost]
        public ApiResult GetMaterialInfoList()
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                apiResult.Data = MaterialBll.GetMaterialInfoList();
            }, apiResult, Request, null);

        }





        /// <summary>
        /// 导出SAP视图
        /// </summary>
        /// <returns></returns>
        public ApiResult DownSAP(Dictionary<string, object> inParam)
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                if (inParam.ContainsKey("FID"))
                {
                    inParam.TryGetValue("FViewType", out object objType);
                    //string FType = null == objType ? Constant.TeamViewType.物料视图.ToString() : objType.ToString();
                    //string selectSql = "", joinSql = "", whereSql = string.Format("TFS_FTeamwork.FID={0} ", inParam["FTeamID"]);
                    string basePath = AppDomain.CurrentDomain.BaseDirectory.Trim('\\');
                    string savePath = basePath + string.Format("\\File\\Temp\\{0}_{1}\\", inParam["FID"], "SAP");
                    if (!Directory.Exists(savePath)) Directory.CreateDirectory(savePath);
                    string tempPath = savePath.Replace("\\File\\Temp\\", "\\File\\View\\");
                    if (!Directory.Exists(tempPath)) Directory.CreateDirectory(tempPath);
                    savePath += ".xlsx";

                    bool hasFinish = inParam.ContainsKey("FFinish");
                    if (hasFinish) savePath = savePath.Replace("\\File\\Temp\\", "\\File\\View\\");
                    if (!File.Exists(savePath) || !hasFinish)
                    {
                        MaterialBll.CreateExeclFileSAP(inParam["FName"].ToString() + "_SAP视图", savePath, "", "", "", inParam["FID"].ToString(), "");
                    }
                    else
                    {
                        File.Delete(basePath + string.Format("\\File\\Temp\\{0}_{1}\\", inParam["FID"], "SAP视图"));
                        MaterialBll.CreateExeclFileSAP(inParam["FName"].ToString() + "_SAP视图", savePath, "", "", "", inParam["FID"].ToString(), "");
                    }
                    string url = Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.AbsolutePath, "") + savePath.Replace(basePath, "").Replace("\\", "/").Replace(".xlsx", inParam["FName"].ToString() + "_SAP视图" + ".xlsx");
                    apiResult.Data = url;

                }
                else
                {
                    apiResult.Error("物料信息获取失败");
                }
            }, apiResult, Request, inParam);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="inParam"></param>
        /// <returns></returns>
        public ApiResult DownViewAll(Dictionary<string, object> inParam)
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                string str = inParam["FType"].ToString() == "1" ? "全部视图" : "SAP视图";
                inParam.TryGetValue("FViewType", out object objType);
                //string FType = null == objType ? Constant.TeamViewType.物料视图.ToString() : objType.ToString();
                //string selectSql = "", joinSql = "", whereSql = string.Format("TFS_FTeamwork.FID={0} ", inParam["FTeamID"]);
                string basePath = AppDomain.CurrentDomain.BaseDirectory.Trim('\\');
                string savePath = basePath + string.Format("\\File\\Temp\\{0}\\", str);
                if (!Directory.Exists(savePath)) Directory.CreateDirectory(savePath);
                string tempPath = savePath.Replace("\\File\\Temp\\", "\\File\\View\\");
                if (!Directory.Exists(tempPath)) Directory.CreateDirectory(tempPath);
                savePath += ".xlsx";

                bool hasFinish = inParam.ContainsKey("FFinish");
                if (hasFinish) savePath = savePath.Replace("\\File\\Temp\\", "\\File\\View\\");
                if (!File.Exists(savePath) || !hasFinish)
                {
                    MaterialBll.CreateExeclFileALL(inParam["FType"].ToString(), savePath);
                }
                else
                {
                    File.Delete(basePath + string.Format("\\File\\Temp\\{0}\\", "", str));
                    MaterialBll.CreateExeclFileALL(inParam["FType"].ToString(), savePath);
                }

                string url = Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.AbsolutePath, "") + savePath.Replace(basePath, "").Replace("\\", "/").Replace(".xlsx", str + ".xlsx");
                apiResult.Data = url;
            }, apiResult, Request, inParam);
        }

        /// <summary>
        /// 更新替代料 判断任务是否完成
        /// </summary>
        /// <param name="inParam"></param>
        /// <returns></returns>
        [HttpPost]
        public ApiResult UpdateDataModel2(Dictionary<string, object> inParam)
        {
            ApiResult apiResult = new ApiResult();

            //BaseBll.UpdateDataModel(inParam, "TFS_FTeamwork");

            return ExceptionHelper.TryReturnException(() =>
            {
                if (inParam == null || inParam.Count < 0)
                {
                    apiResult.Error("未接收到参数");
                }
                else if (!inParam.ContainsKey("tempId"))
                {
                    apiResult.Error("未找到协同ID");
                }
                else
                {
                    int tempId = int.Parse(inParam["tempId"].ToString());
                    int taskId = int.Parse(inParam["taskId"].ToString());

                    inParam.Remove("tempId");
                    inParam.Remove("taskId");

                    apiResult.Data = BaseBll.UpdateDataModel(inParam, "TFS_Material");

                    TFS_FTeamwork fS_FTeamwork = BaseBll.GetTempModel<TFS_FTeamwork>("FID=" + tempId);
                    //fS_FTeamwork.FMaterialHalfIDs
                    //fMaterialFormulaIDs
                    List<TFS_Material> result = MaterialBll.GetMaterial(fS_FTeamwork.FMaterialFormulaIDs);
                  

                    if (result.Where(m => m.FSuccedaneumID == 0).Count() == 0)
                    {
                        BaseBll.UpdateTeamProcess(tempId, (int)Constant.ProcessType.替代品确认, 2, 2);
                        int count = MaterialBll.ExecSql(BaseBll.GetTaskSql(taskId, 2, tempId, (int)Constant.TaskType.替代料确认));
                    }
                }



            }, apiResult, Request, inParam);
        }


        #region 内部方法

        /// <summary>
        /// 模板上传处理（重构父方法）
        /// </summary>
        protected override object CheckUploadFile(List<string> fileList, int funcType, int userId)
        {
            //替代料导入、副产物导入
            List<TFS_Material> mainList;
            List<PropertyInfo> mainProp;
            if (funcType == 2 || funcType == 3)
            {
                GetFuMaterialFromFile(fileList, funcType, out mainList, out mainProp, out List<TFS_FieldInfo> fieldList);
                if (funcType == 3) return MaterialBll.InsertBatchFuMaterialData(mainList, mainProp, fieldList, userId);
                else return MaterialBll.InsertBatchTiMaterialData(mainList, mainProp, fieldList, userId);
            }
            else if (funcType == 4)
            {
                //物料信息补全导入
                GetMaterialInfoFromFile(fileList, out mainList, out List<TFS_MaterialInfo> infoList, out mainProp, out List<PropertyInfo> childProp, out List<TFS_FieldInfo> fieldList);
                return MaterialBll.InsertBatchInfoMaterialData(mainList, infoList, mainProp, childProp, fieldList, userId);
            }
            else if (funcType <= 1)
            {
                //物料导入
                GetMaterialFromFile(fileList, out mainList, out List<TFS_ViewMaterial> childList, out mainProp, out List<PropertyInfo> childProp);
                return MaterialBll.DockingRecipeData(mainList, mainProp, userId) + MaterialBll.DockingRecipeData(childList, childProp, userId);
            }
            return fileList;
        }

        /// <summary>
        /// 信息补全模板
        /// </summary>
        private void GetMaterialInfoFromFile(List<string> fileList, out List<TFS_Material> mainList, out List<TFS_MaterialInfo> infoList,
            out List<PropertyInfo> mainProp, out List<PropertyInfo> childProp, out List<TFS_FieldInfo> fieldList)
        {
            mainList = new List<TFS_Material>();
            infoList = new List<TFS_MaterialInfo>();
            fieldList = BaseBll.GetFileInfoList((int)Constant.FieldInfoType.物料信息补充模板导入);
            mainProp = typeof(TFS_Material).GetTypeInfo().GetProperties().ToList();
            childProp = typeof(TFS_MaterialInfo).GetTypeInfo().GetProperties().ToList();

            PropertyInfo temp = null;
            foreach (string filePath in fileList)
            {
                DataTable dt = NPOIHelper.ImportExceltoDt(filePath);
                List<string> items = new List<string>();
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    items.Add(dt.Columns[i].ColumnName);
                }
                foreach (DataRow dr in dt.Rows)
                {
                    TFS_Material main = new TFS_Material();
                    TFS_MaterialInfo child = new TFS_MaterialInfo();
                    foreach (var field in fieldList)
                    {
                        string value = GetValueByName(dr, items, field.FFieldName, field.FDefault);
                        if ((temp = mainProp.Find(s => s.Name.Equals(field.FColumnFIeld))) != null) temp.SetValue(main, value);
                        if ((temp = childProp.Find(s => s.Name.Equals(field.FColumnFIeld))) != null) temp.SetValue(child, value);
                    }
                    if (!string.IsNullOrEmpty(main.FCode))
                    {
                        mainList.Add(main);
                        infoList.Add(child);
                    }
                }
            }
        }

        /// <summary>
        /// 根据导入文件生成两个表集合
        /// </summary>
        private void GetMaterialFromFile(List<string> fileList, out List<TFS_Material> mainList, out List<TFS_ViewMaterial> childList, out List<PropertyInfo> mainProp, out List<PropertyInfo> childProp)
        {
            mainList = new List<TFS_Material>();
            childList = new List<TFS_ViewMaterial>();
            List<TFS_FieldInfo> fieldList = BaseBll.GetFileInfoList((int)Constant.FieldInfoType.物料模板导入);
            mainProp = typeof(TFS_Material).GetTypeInfo().GetProperties().ToList();
            childProp = typeof(TFS_ViewMaterial).GetTypeInfo().GetProperties().ToList();
            PropertyInfo temp = null;
            foreach (string filePath in fileList)
            {
                DataTable dt = NPOIHelper.ImportExceltoDt(filePath);
                List<string> items = new List<string>();
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    items.Add(dt.Columns[i].ColumnName);
                }
                foreach (DataRow dr in dt.Rows)
                {
                    //物料表
                    TFS_Material main = new TFS_Material();
                    //视图表
                    TFS_ViewMaterial view = new TFS_ViewMaterial()
                    {
                        FViewType = (int)Constant.ViewType.成品视图
                    };
                    foreach (var field in fieldList)
                    {
                        string value = GetValueByName(dr, items, field.FFieldName, field.FDefault);
                        if ((temp = mainProp.Find(s => s.Name.Equals(field.FColumnFIeld))) != null)
                        {
                            temp.SetValue(main, value);
                        }
                        if ((temp = childProp.Find(s => s.Name.Equals(field.FColumnFIeld))) != null)
                        {
                            temp.SetValue(view, value);
                        }
                    }
                    if (!string.IsNullOrEmpty(main.FCode))
                    {
                        mainList.Add(main);
                        childList.Add(view);
                    }
                }
            }
        }

        /// <summary>
        /// 根据导入文件生成副产物关系表
        /// </summary>
        private void GetFuMaterialFromFile(List<string> fileList, int funcType, out List<TFS_Material> mainList, out List<PropertyInfo> mainProp,
            out List<TFS_FieldInfo> fieldList)
        {
            mainList = new List<TFS_Material>();
            fieldList = BaseBll.GetFileInfoList(funcType == 2 ? (int)Constant.FieldInfoType.替代料模板导入 : (int)Constant.FieldInfoType.副产物模板导入);
            mainProp = typeof(TFS_Material).GetTypeInfo().GetProperties().ToList();
            PropertyInfo temp = null;
            foreach (string filePath in fileList)
            {
                DataTable dt = NPOIHelper.ImportExceltoDt(filePath);
                List<string> items = new List<string>();
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    items.Add(dt.Columns[i].ColumnName);
                }
                foreach (DataRow dr in dt.Rows)
                {
                    TFS_Material main = new TFS_Material();
                    foreach (var field in fieldList)
                    {
                        string value = GetValueByName(dr, items, field.FFieldName, field.FDefault);
                        if ((temp = mainProp.Find(s => s.Name.Equals(field.FColumnFIeld))) != null) temp.SetValue(main, value);
                    }
                    if (!string.IsNullOrEmpty(main.FCode))
                    {
                        if (funcType != 2 && !string.IsNullOrEmpty(main.FFuProductsCode))
                        {
                            mainList.Add(main);
                        }
                        else if (funcType == 2 && !string.IsNullOrEmpty(main.FSuccedaneumCode))
                        {
                            mainList.Add(main);
                        }
                    }
                }
            }
        }

        #endregion
    }
}