using FactorySystemBll;
using FactorySystemCommon;
using FactorySystemModel.BusinessModel;
using FactorySystemModel.ResponseModel;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Http;

namespace FactorySystemApi.Controllers
{
    /// <summary>
    /// 基础接口
    /// </summary>
    [UserLoginFilter]
    public class BaseController<T> : ApiController
    {
        /// <summary>
        /// 数据处理层
        /// </summary>
        public readonly BaseBll BaseBll = new BaseBll();

        #region 公共接口-开始

        /// <summary>
        /// （通用）获取信息
        /// </summary>
        [HttpPost]
        public virtual ApiResult GetDataModel(Dictionary<string, object> inParam)
        {
            ApiResult apiResult = new ApiResult
            {
                Data = -1
            };
            return ExceptionHelper.TryReturnException(() =>
            {
                inParam.TryGetValue("FID", out object dataId);
                apiResult.Data = BaseBll.GetTempDict<T>(dataId == null ? -1 : int.Parse(dataId.ToString()), inParam.ContainsKey("FKey") ? inParam["FKey"].ToString() : "");
            }, apiResult, Request, inParam);
        }

        /// <summary>
        /// （通用）新增信息
        /// </summary>
        [HttpPost]
        public virtual ApiResult InsertDataModel(Dictionary<string, object> insertData)
        {
            ApiResult apiResult = new ApiResult
            {
                Data = -1
            };
            return ExceptionHelper.TryReturnException(() =>
            {
                //表可新增字段
                if (!string.IsNullOrEmpty(InsertField))
                {
                    insertData = GetDictByField(insertData, InsertField);
                }
                //新增数据
                if (insertData.Count > 1)
                {
                    //设置用户字段
                    ApiAuthInfo user = Request.Properties["token"] as ApiAuthInfo;
                    if (insertData.ContainsKey("FAddUser")) { insertData["FAddUser"] = user.FID; }
                    if (insertData.ContainsKey("FEditUser")) { insertData["FEditUser"] = user.FID; }
                    else { insertData.Add("FEditUser", user.FID); }
                    if (insertData.ContainsKey("FEditDate")) { insertData["FEditDate"] = DateTime.Now; }
                    else { insertData.Add("FEditDate", DateTime.Now); }
                    apiResult.Data = BaseBll.InsertDataModel(insertData, typeof(T).Name);
                }
            }, apiResult, Request, insertData);
        }

        /// <summary>
        /// （通用）修改信息
        /// </summary>
        [HttpPost]
        public virtual ApiResult UpdateDataModel(Dictionary<string, object> updateModel)
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                ApiAuthInfo user = Request.Properties["token"] as ApiAuthInfo;
                updateModel.Remove("FEditUser");
                updateModel.Remove("FEditDate");
                updateModel.Add("FEditUser", user.FID);
                updateModel.Add("FEditDate", DateTime.Now);
                apiResult.Data = UpdateData(updateModel);
            }, apiResult, Request, updateModel);
        }

        /// <summary>
        /// （通用）删除信息
        /// </summary>
        [HttpPost]
        public ApiResult DeleteDataById(Dictionary<string, object> updateModel)
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                apiResult.Data = BaseBll.DeleteDataById(updateModel, typeof(T).Name);
            }, apiResult, Request, updateModel);
        }

        /// <summary>
        /// （通用）列表分页
        /// </summary>
        [HttpPost]
        public ApiResult GetPageList(Dictionary<string, object> pageParam)
        {
            return GetTPageList<T>(pageParam);
        }

        /// <summary>
        ///（通用）模板上传
        /// </summary>
        [HttpPost]
        public ApiResult UploadTempFile(int FType, int FFuncType)
        {
            ApiResult apiResult = new ApiResult();
            List<string> fileList = new List<string>();
            return ExceptionHelper.TryReturnException(() =>
            {
                var files = HttpContext.Current.Request.Files;
                if (files != null && files.Count > 0)
                {
                    string typeName = "";
                    switch (FType)
                    {
                        case 2://物料
                            typeName = "Material";
                            break;
                        case 1://配方
                        default:
                            typeName = "Formula";
                            break;
                    }

                    ApiAuthInfo authInfo = Request.Properties["token"] as ApiAuthInfo;
                    string[] exts = ".xlsx,.xls".Split(',');
                    string saveBase = string.Format("/Upload/{0}/" + authInfo.FID + "/", typeName);
                    saveBase = System.Web.Hosting.HostingEnvironment.MapPath(saveBase);
                    if (!Directory.Exists(saveBase)) Directory.CreateDirectory(saveBase);

                    for (int i = 0; i < files.Count; i++)
                    {
                        string ext = Path.GetExtension(files[i].FileName).ToLower();
                        if (Array.IndexOf(exts, ext) != -1)
                        {
                            string filePath = saveBase + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "_" + i + ext;
                            files[i].SaveAs(filePath);
                            fileList.Add(filePath);
                        }
                    }
                    ApiAuthInfo user = Request.Properties["token"] as ApiAuthInfo;
                    apiResult.Data = CheckUploadFile(fileList, FFuncType, user.FID);
                }
            }, apiResult, Request, new { FType, FFuncType, FileList = fileList });
        }

        /// <summary>
        /// （临时）创建表
        /// </summary>
        [HttpPost]
        [NoCheckUserLogin]
        [NonAction]
        public ApiResult CreateSqlSugarModel(Dictionary<string, object> updateModel)
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                updateModel.TryGetValue("FAuth", out object apiAuth);
                if (apiAuth == null || apiAuth.ToString() != (DateTime.Now.ToString("yyyyMMdd-") + DateTime.Now.DayOfYear))
                {
                    apiResult.Message = "认证信息错误";
                }
                else
                {
                    updateModel.TryGetValue("FName", out object tableName);
                    BaseBll.CreateSqlSugarModel(tableName == null ? "TFS_" : tableName.ToString());
                }
            }, apiResult, Request, updateModel);
        }

        #endregion 公共接口-结束

        #region 内部方法-开始

        /// <summary>
        /// 可修改字段，非空则只有这些字段是可以修改的
        /// </summary>
        internal string UpdateField = string.Empty;
        /// <summary>
        /// 插入字段，非空则这些字段是必须的，默认值自己数据库设置
        /// </summary>
        internal string InsertField = string.Empty;

        /// <summary>
        /// （通用）修改信息
        /// </summary>
        /// <param name="updateModel">修改数据</param>
        /// <param name="tableName">表名</param>
        /// <param name="canOptField">权限→ null不限制，反之只能改这几个值</param>
        protected int UpdateData(Dictionary<string, object> updateModel, string canOptField = null, string tableName = null)
        {
            //表可修改字段
            if (!string.IsNullOrEmpty(UpdateField))
            {
                updateModel = GetDictByField(updateModel, UpdateField);
            }
            //权限可修改字段
            if (canOptField != null)
            {
                updateModel = GetDictByField(updateModel, canOptField);
            }
            //修改数据
            if (updateModel.ContainsKey("FID") && updateModel.Count > 1)
            {
                return BaseBll.UpdateDataModel(updateModel, string.IsNullOrEmpty(tableName) ? typeof(T).Name : tableName) > 0 ? 1 : 0;
            }
            return 0;
        }

        /// <summary>
        /// 模板文件处理
        /// </summary>
        protected virtual object CheckUploadFile(List<string> fileList, int funcType, int userId)
        {
            return fileList;
        }

        /// <summary>
        /// 筛选字段
        /// </summary>
        protected Dictionary<string, object> GetDictByField(Dictionary<string, object> updateModel, string fieldKey)
        {
            Dictionary<string, object> tempDict = new Dictionary<string, object>();
            if (updateModel.Count > 0)
            {
                string[] fieldKeys = (fieldKey.Trim() + ",FID").Split(',');
                foreach (string fieldName in fieldKeys)
                {
                    if (!string.IsNullOrEmpty(fieldName) && updateModel.TryGetValue(fieldName, out object fieldVal))
                    {
                        tempDict.Add(fieldName, fieldVal);
                    }
                }
            }
            return tempDict;
        }

        /// <summary>
        /// （通用）获取列表分页
        /// </summary>
        protected ApiResult GetTPageList<TT>(Dictionary<string, object> pageParam, string searchKey = null, string orderBy = "FID desc")
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                apiResult.Data = new
                {
                    List = BaseBll.GetPageList<TT>(pageParam, out int totalCount, searchKey, orderBy),
                    Total = totalCount
                };
            }, apiResult, Request, pageParam);
        }

        /// <summary>
        /// 根据名称查找值
        /// </summary>
        protected string GetValueByName(Dictionary<string, object> inParam, string name, string nullVal = "")
        {
            List<string> names = name.Split(',').ToList();
            for (int i = 0; i < names.Count(); i++)
            {
                if (inParam.TryGetValue(names[i], out object result))
                {
                    return result == null ? "" : result.ToString().Trim();
                }
            }
            return nullVal;
        }

        /// <summary>
        /// 根据名称查找值
        /// </summary>
        protected string GetValueByName(DataRow dr, List<string> items, string name, string nullVal = "")
        {
            List<string> names = name.Split(',').ToList();
            for (int i = 0; i < names.Count(); i++)
            {
                if (items.IndexOf(names[i]) != -1)
                {
                    try { return dr[names[i]].ToString().Trim(); }
                    catch (Exception) { }
                }
            }
            return nullVal;
        }

        /// <summary>
        /// 获取MDM代码
        /// </summary>
        public string GetMdmCode(Dictionary<string, object> inParam)
        {
            string logMessage = "";
            string jObject = "";
            try
            {
                JObject jo = new JObject
                {
                    { "systemCode", "mdm" },
                    { "gdCode", "sap_material" },
                    { "masterData",
                        new JArray
                        {
                            new JObject
                                {
                                    { "id", Guid.NewGuid().ToString() },//随机生成值，不可重复
                                    { "sap_flag_system", "香精" },//固定
                                    { "sap_material_basicunit#code",  GetValueByName(inParam, "FWeightUnit") },//必填
                                    { "sap_material_busvol", "" },
                                    { "sap_material_code", "" },
                                    { "sap_material_code_2", "" },
                                    { "sap_material_code_flag", "Y" },//固定
                                    { "sap_material_ex_code", GetValueByName(inParam, "FTestCode") },//试验号，可不填
                                    { "sap_material_fame", "" },
                                    { "sap_material_grossweight", "" },
                                    { "sap_material_grouptype#code",  GetValueByName(inParam, "FMaterialGroup,FGroup")}, //必填
                                    { "sap_material_lable#code", "" },
                                    { "sap_material_models", "" },
                                    { "sap_material_models_text", "" },
                                    { "sap_material_name", GetValueByName(inParam, "FSaleCode,FName")}, //必填
                                    { "sap_material_netweight", "" },
                                    { "sap_material_type#code", GetValueByName(inParam, "FType,FMaterialType") },//固定，必填
                                    { "sap_material_volunit#code", "" },
                                    { "sap_material_weightunit#code", "" }
                                }
                        }
                    }
                };
                jObject = jo.ToString();
                WebRequest webRequest = WebRequest.Create(AppSettingsHelper.GetAppSettingVal("Mdm_Url"));
                HttpWebRequest httpRequest = webRequest as HttpWebRequest;
                httpRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
                httpRequest.ContentType = "application/json";
                httpRequest.Method = "post";
                httpRequest.Headers.Add("mdmtoken", AppSettingsHelper.GetAppSettingVal("Mdm_Token"));
                httpRequest.Headers.Add("tenantid", "tenant");
                Encoding encoding = Encoding.GetEncoding("utf-8");
                byte[] bytesToPost = encoding.GetBytes(jObject);
                httpRequest.ContentLength = bytesToPost.Length;
                Stream requestStream = httpRequest.GetRequestStream();
                requestStream.Write(bytesToPost, 0, bytesToPost.Length);
                requestStream.Close();
                Stream responseStream = httpRequest.GetResponse().GetResponseStream();
                using (StreamReader responseReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8")))
                {
                    logMessage = responseReader.ReadToEnd();
                }
                responseStream.Close();
                ExceptionHelper.AddSystemJournal(Request, new
                {
                    inParam,
                    jObject
                }, logMessage, -1, "GetMdmCode");
            }
            catch (Exception ex)
            {
                ExceptionHelper.AddSystemJournal(Request, new
                {
                    inParam,
                    jObject
                }, new
                {
                    Resule = logMessage,
                    Error = ex.Message
                }, -1, "GetMdmCode");
            }
            try
            {
                if (logMessage.IndexOf("success") != -1)
                {
                    MDMResponseModel resModel = JsonConvert.DeserializeObject<MDMResponseModel>(logMessage);
                    if (resModel.success)
                    {
                        List<MDMDataResponseModel> datas = JsonConvert.DeserializeObject<List<MDMDataResponseModel>>(resModel.data);
                        return datas.Count > 0 ? datas.First().mdm_code : "";
                    }
                }
            }
            catch (Exception) { }
            return "";
        }
        #endregion 内部方法-结束
    }
}
