using Kingdee.CDP.WebApi.SDK;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RB_MES_API.Context;
using RB_MES_API.Models;
using RB_MES_API.Models.Cloud;
using System.Data;
using System.Text;

namespace RB_MES_API.Controllers.Cloud
{
    /// <summary>
    /// 实现金蝶云星空的子查询
    /// </summary>
    public class ChiledSelect : IChiledSelect
    {
        private readonly IShareController _shareController;
        private readonly IKDCloudHttpClient _KdhttpClient;
        private readonly IKDSqlHelper _kdsqlhelper;

        public ChiledSelect(IShareController shareController, IKDCloudHttpClient kdhttpClient, IKDSqlHelper kdsqlhelper)
        {
            _shareController = shareController;
            _KdhttpClient = kdhttpClient;
            //_config = config;
            _kdsqlhelper = kdsqlhelper;
        }
        public class ChildQuery
        {
            public string FieldKeys { get; set; }
            public string FormId { get; set; }
            public string FiledString { get; set; }
            public string FOptcode { get; set; }
            public int TopRowCount { get; set; }
            public int StartRow { get; set; }
            public int Limit { get; set; }
            public string SubSystemID { get; set; }
            public string OrderString { get; set; }
            public string Url { get; set; }
            public int FFunctionID { get; set; }
        }
        public async Task<IList<BD_Supplier>> suppliersAsync(int fid)
        {
            List<BD_Supplier> bD_Suppliers = new List<BD_Supplier>();
            List<CloudBillQuery> queryJsons = await _shareController.GetAPIList<CloudBillQuery>();
            var billquery = queryJsons.Where(s => s.FKDBillName.Equals("TB_BS_SUP"));
            if (billquery.Any())
            {
                BillQuery queryJson = (BillQuery)(from a in billquery
                                                  select new BillQuery
                                                  {
                                                      FieldKeys = a.FFieldKeys.Replace("@defaultorgid", LocalStaticRequest.DefaultOrgID.ToString()).Replace("@defaultorgno", LocalStaticRequest.DefaultOrg),
                                                      FormId = a.GetFormID.FDBName,
                                                      FilterString = a.FFiledString.Replace("@defaultorgid", LocalStaticRequest.DefaultOrgID.ToString()).Replace("@defaultorgno", LocalStaticRequest.DefaultOrg),//子查询中这个是固定的
                                                      Limit = a.FLimit,
                                                      OrderString = a.FOrderString,
                                                      StartRow = a.FStartRow,
                                                      SubSystemId = a.FSubSystemID,
                                                      TopRowCount = a.FTopRowCount
                                                  });
                //从云星空查询
                string result = _KdhttpClient.SDKBillQuery(queryJson);
                if (_KdhttpClient.SDKBillQueryStatus(result))
                {
                    try
                    {
                        JArray jArray = (JArray)JsonConvert.DeserializeObject(result.ToString()!)!;
                        if (jArray.Count > 0)
                        {
                            bD_Suppliers = (List<BD_Supplier>)JsonConvert.DeserializeObject(result)!;
                        }
                    }
                    catch (Exception)
                    {
                        _shareController._SqlloggerInvoke(fid, "子查询获得供应商", result, JsonConvert.SerializeObject(queryJson));
                    }
                }
            }
            return bD_Suppliers;
        }

        /// <inheritdoc/>

        public List<T>? GetSourceBillEntry<T>(DataTable datatable, int fromtypeid, ref string reason) where T : class, new()
        {
            reason = "";
            List<T> purchases = new List<T>();
            if (datatable == null || datatable.Rows.Count == 0) { return purchases; }
            List<CloudBillQuery> queryjsons = _shareController.GetAPIList<CloudBillQuery>().Result;
            List<SelectJoinID> selectJoins = _shareController.GetAPIList<SelectJoinID>().Result;
            var cbq = from a in queryjsons.Where(s => s.FFormIDTypeID == fromtypeid)
                      join b in selectJoins on new { A = a.GetFormID.functions.FID, B = a.GetFormID.FDocType } equals new { A = b.FFunctionID, B = b.FDocType }
                      select new ChildQuery
                      {
                          FieldKeys = a.FFieldKeys.Replace("@defaultorgid", LocalStaticRequest.DefaultOrgID.ToString()).Replace("@defaultorgno", LocalStaticRequest.DefaultOrg),
                          FormId = a.GetFormID.FDBName,
                          FiledString = a.FFiledString.Replace("@defaultorgid", LocalStaticRequest.DefaultOrgID.ToString()).Replace("@defaultorgno", LocalStaticRequest.DefaultOrg),
                          FOptcode = b.FOptcode,
                          TopRowCount = a.FTopRowCount,
                          StartRow = a.FStartRow,
                          Limit = a.FLimit,
                          SubSystemID = a.FSubSystemID,
                          OrderString = a.FOrderString,
                          Url = a.GetFormID.functions.FUrl,
                          FFunctionID = a.GetFormID.FFunctionID
                      };
            if (!cbq.Any())
            {
                reason = "子查询配置不正确，检查r_CloudBillQuery和r_SelectJoinID";
                return purchases;
            }
            string optcode = cbq.FirstOrDefault()!.FOptcode;
            if (optcode == null)
            {
                reason = "没有为子查询配置正确的FOptcode";
                return purchases;
            }
            string filedstr = cbq.FirstOrDefault()!.FiledString;
            if (filedstr == null)
            {
                reason = "没有为子查询配置正确的FiledString";
                return purchases;
            }
            if (!LocalStaticRequest.Islogin)
            {
                var kd = _KdhttpClient.LoginErp().Result;
            }
            if (!LocalStaticRequest.Islogin)
            {
                reason = "KdhttpClient登录失败";
                return purchases;
            }
            int fid = cbq.FirstOrDefault()!.FFunctionID;
            string fieldkeys = cbq.FirstOrDefault()!.FieldKeys;
            string cloudfiledstr = GetChildFiledstr(datatable, optcode, filedstr);

            //从云星空查询
            BillQuery queryJson = new BillQuery()
            {
                FieldKeys = cbq.FirstOrDefault()!.FieldKeys,
                FilterString = cloudfiledstr,
                FormId = cbq.FirstOrDefault()!.FormId,
                OrderString = cbq.FirstOrDefault()!.OrderString,
                TopRowCount = cbq.FirstOrDefault()!.TopRowCount,
                StartRow = cbq.FirstOrDefault()!.StartRow,
                Limit = cbq.FirstOrDefault()!.Limit,
                SubSystemId = cbq.FirstOrDefault()!.SubSystemID
            };
            string result = _KdhttpClient.SDKBillQuery(queryJson);
            if (!_KdhttpClient.SDKBillQueryStatus(result))
            {
                reason = "子查询为空...";
            }
            else
            {
                purchases = _shareController.GetNewObjForChild<T>(fieldkeys, result, ref reason);
            }
            return purchases;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="datatable"></param>
        /// <param name="optcode"></param>
        /// <param name="filedstr"></param>
        /// <returns></returns>
        public string GetChildFiledstr(DataTable datatable, string optcode, string filedstr)
        {
            List<string> list = new List<string>();
            string[] strings = optcode.Split('|');
            foreach (DataRow row in datatable.Rows)
            {
                string f = filedstr;
                foreach (string s in strings)
                {
                    string[] strings1 = s.Split('=');
                    string k = strings1[0];
                    if (datatable.Columns.Contains(k))
                    {
                        string? val = row[k].ToString();
                        f = f.Replace(k, val);
                    }
                }
                list.Add(f);
            }
            string cloudfiledstr = string.Format("(({0}))", string.Join(") or (", list.ToArray()));
            return cloudfiledstr;
        }
        /// <inheritdoc/>


        public async Task<string> GetCustomRequestTBAsync(int formtypeid)
        {
            string tbjson = string.Empty;
            List<CloudBillQuery> queryJsons = await _shareController.GetAPIList<CloudBillQuery>();
            var query = queryJsons.Where(s => s.FFormIDTypeID == formtypeid).FirstOrDefault();
            string sql = query.FFieldKeys.Replace("@defaultorgid", LocalStaticRequest.DefaultOrgID.ToString());
            if (string.IsNullOrEmpty(sql)) { return tbjson; }
            string param = query.FFiledString.Replace("@defaultorgid", LocalStaticRequest.DefaultOrgID.ToString()).Replace("@defaultorgno", LocalStaticRequest.DefaultOrg);
            if (!string.IsNullOrEmpty(param))
            {
                string[] strings = param.Split(',');
                foreach (string s in strings)
                {
                    string[] cs = s.Split('=');
                    string key = cs[0];
                    string value = cs[1].Replace("GETDATE", DateTime.Now.ToShortDateString()).Replace("@defaultorgid", LocalStaticRequest.DefaultOrgID.ToString());
                    sql = sql.Replace(key, value);
                }
            }

            string doctype = query.GetFormID.FDocType;
            string costomsql = ApiSettingsHelper.GetConfig("CustomRequestRemoteSql");

            if (costomsql.ToUpper() == "Y")
            {
                string result = await GetCustomReaderAsync(sql, "ExecuteDataSet");
                try
                {
                    if (string.IsNullOrWhiteSpace(result)) { return tbjson; }
                    //先将返回数据格式化
                    JObject jobj = (JObject)JsonConvert.DeserializeObject(result);
                    tbjson = JsonConvert.SerializeObject(jobj["Table"]);
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog(string.Format(doctype + "在自定义SQL查询结果集过程中GetCustomRequestTBAsync发生错误：\r\n{0}", ex.Message));
                }
            }
            else
            {
                string mess = string.Empty;
                DataSet dataSet = _kdsqlhelper.GetDataSet(CommandType.Text, sql, null, ref mess, true);
                if (mess != null || dataSet == null)
                {
                    LogHelper.WriteLog(string.Format(doctype + "在自定义SQL查询结果集过程中GetCustomRequestTBAsync发生错误：\r\n{0}", mess));
                }
                else if (dataSet.Tables.Count != 0)
                {
                    DataTable dataTable = dataSet.Tables[0];
                    tbjson = JsonConvert.SerializeObject(dataTable);
                }
            }
            return tbjson;
        }
        /// <inheritdoc/>

        public async Task<string> GetCustomRequestBillAsync(string sql, string filestr, string ordstr, Dictionary<string, object>? inputdic)
        {
            string tbjson = string.Empty;
            filestr = filestr.Replace("GETDATE", DateTime.Now.ToShortDateString());
            if (!string.IsNullOrWhiteSpace(filestr) && filestr != "") { sql += string.Format(" AND {0}", filestr); }      //前面一定要有WHERE 
            if (!string.IsNullOrWhiteSpace(ordstr) && ordstr != "") { sql += string.Format("\r\n ORDER BY {0}", ordstr); }
            if (inputdic != null)
            {
                foreach (KeyValuePair<string, object> keyValue in inputdic)
                {
                    string key = string.Format("@{0}", keyValue.Key.Replace("@", ""));
                    string value = keyValue.Value.ToString();
                    sql = sql.Replace(key, value);
                }
            }

            string costomsql = ApiSettingsHelper.GetConfig("CustomRequestRemoteSql");
            if (costomsql.ToUpper() == "Y")
            {
                string result = await GetCustomReaderAsync(sql, "ExecuteDataSet");
                try
                {
                    if (!string.IsNullOrWhiteSpace(result) && result != "[]")
                    {
                        //先将返回数据格式化
                        JObject jobj = (JObject)JsonConvert.DeserializeObject(result);
                        if (jobj.Count > 0)
                        {
                            tbjson = JsonConvert.SerializeObject(jobj["Table"]);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog(string.Format("GetCustomRequestBillAsync发生错误：\r\n{0}\r\n{1}", ex.Message, result));
                }
            }
            else
            {
                string mess = string.Empty;
                //实施本地化查询
                DataSet dataSet = _kdsqlhelper.GetDataSet(CommandType.Text, sql, null, ref mess, true);
                if (mess != null || dataSet == null)
                {
                    LogHelper.WriteLog(string.Format("GetCustomRequestBillAsync实施本地化查询发生错误：\r\n{0}", mess));
                }
                else if (dataSet.Tables.Count != 0)
                {
                    DataTable dataTable = dataSet.Tables[0];
                    tbjson = JsonConvert.SerializeObject(dataTable);
                }
            }

            return tbjson;
        }
        public async Task<List<BD_Material>> materialsAsync(List<string> numbers)
        {
            List<BD_Material>? tbjson = new List<BD_Material>();
            StringBuilder sql = new StringBuilder();
            sql.AppendLine("/*dialect*/SELECT M1.FMaterialID,M1.FNumber,M2.FName,M3.FStoreUnitID,M4.FBaseUnitId,CASE M1.FForbidStatus WHEN 'A' THEN 'N' ELSE 'Y' END FForbidStatus");
            sql.AppendLine("	,U1.FNUMBER FUnitNumber,U2.FNUMBER FBaseUnitNumber,F_PKGR_ITEMVERSION");
            sql.AppendLine("FROM T_BD_MATERIAL M1 INNER JOIN T_BD_MATERIAL_L M2 ON M2.FMATERIALID=M1.FMATERIALID");
            sql.AppendLine("	INNER JOIN T_BD_MATERIALSTOCK M3 ON M3.FMATERIALID=M1.FMATERIALID");
            sql.AppendLine("	INNER JOIN T_BD_MATERIALBASE M4 ON M4.FMATERIALID=M1.FMATERIALID");
            sql.AppendLine("	INNER JOIN T_BD_UNIT U1 ON U1.FUNITID=M3.FSTOREUNITID");
            sql.AppendLine("	INNER JOIN T_BD_UNIT U2 ON U2.FUNITID=M4.FBASEUNITID");
            sql.AppendLine("WHERE M1.FDOCUMENTSTATUS='C' AND M1.FUSEORGID=1");
            if (numbers != null)
            {
                string wherestr = string.Format("M1.FNumber in ('{0}')", string.Join("','", numbers.ToArray()));
                sql.AppendLine(" AND " + wherestr);
            }
            string reason = string.Empty;
            string costomsql = ApiSettingsHelper.GetConfig("CustomRequestRemoteSql");
            if (costomsql.ToUpper() == "Y")
            {
                string result = await GetCustomReaderAsync(sql.ToString(), "ExecuteDataSet");
                try
                {
                    if (result == null) { return tbjson; }
                    //先将返回数据格式化
                    JObject jobj = (JObject)JsonConvert.DeserializeObject(result);
                    string tbstr = JsonConvert.SerializeObject(jobj["Table"]);
                    tbjson = _shareController.DataConvertClass<BD_Material>(tbstr, ref reason);
                }
                catch
                {
                    LogHelper.WriteLog(string.Format("Cloud自定义SQL查询结果集过程中GetCustomRequestTableAsync发生错误：\r\n{0}", result));
                }
            }
            else
            {
                string mess = string.Empty;
                string s = sql.ToString();
                //实施本地化查询
                DataSet dataSet = _kdsqlhelper.GetDataSet(CommandType.Text, sql.ToString(), null, ref mess, true);
                if (mess != null || dataSet == null)
                {
                    LogHelper.WriteLog(string.Format("GetCustomRequestBillAsync实施本地化查询发生错误：\r\n{0}", mess));
                }
                else if (dataSet.Tables.Count != 0)
                {
                    DataTable dataTable = dataSet.Tables[0];
                    tbjson = _shareController.GetClassList<BD_Material>(dataTable);
                }
            }
            return tbjson;
        }


        public async Task<string> GetCustomRequestTableAsync(string sql, string filestr, string ordstr, List<Dictionary<string, object>> inputdic)
        {
            string tbjson = string.Empty;
            List<string> wheres = new List<string>();
            filestr = filestr.Replace("GETDATE", DateTime.Now.ToShortDateString());
            if (inputdic != null)
            {
                foreach (Dictionary<string, object> dic in inputdic)
                {
                    string wherestr = filestr;
                    foreach (KeyValuePair<string, object> keyValue in dic)
                    {
                        string key = keyValue.Key;
                        string value = keyValue.Value.ToString();
                        wherestr = wherestr.Replace(key, value);
                    }
                    wheres.Add(wherestr);
                }
            }
            if (wheres.Count != 0) { sql += string.Format(" AND (({0}))", string.Join(") or (", wheres.ToArray())); }      //前面一定要有WHERE 
            if (!string.IsNullOrWhiteSpace(ordstr) && ordstr != "") { sql += string.Format("\r\n ORDER BY {0}", ordstr); }

            string costomsql = ApiSettingsHelper.GetConfig("CustomRequestRemoteSql");
            if (costomsql.ToUpper() == "Y")
            {
                string result = await GetCustomReaderAsync(sql, "ExecuteDataSet");
                try
                {
                    if (result == null) { return tbjson; }
                    //先将返回数据格式化
                    JObject jobj = (JObject)JsonConvert.DeserializeObject(result);
                    tbjson = JsonConvert.SerializeObject(jobj["Table"]);
                }
                catch
                {
                    LogHelper.WriteLog(string.Format("Cloud自定义SQL查询结果集过程中GetCustomRequestTableAsync发生错误：\r\n{0}", result));
                }
            }
            else
            {
                string mess = string.Empty;
                //实施本地化查询
                DataSet dataSet = _kdsqlhelper.GetDataSet(CommandType.Text, sql, null, ref mess, true);
                if (mess != null || dataSet == null)
                {
                    LogHelper.WriteLog(string.Format("GetCustomRequestBillAsync实施本地化查询发生错误：\r\n{0}", mess));
                }
                else if (dataSet.Tables.Count != 0)
                {
                    DataTable dataTable = dataSet.Tables[0];
                    tbjson = JsonConvert.SerializeObject(dataTable);
                }
            }

            return tbjson;
        }
        /// <inheritdoc/>
        public async Task<string> GetCustomReaderAsync(string sql, string servicesstubname)
        {
            string tbjson = string.Empty;
            string apiid = LocalStaticRequest.GetSystemProfile(1, "APIGrouID");
            var csv = await _shareController.GetAPIList<CustomService>();
            var sv = csv.Where(s => s.FApiGroupID == int.Parse(apiid) && s.FActionName == servicesstubname);
            if (!sv.Any()) { return tbjson; }
            CustomService customservice = sv.FirstOrDefault();
            if (customservice == null) { return tbjson; }
            await _KdhttpClient.LoginErp();
            if (!LocalStaticRequest.Islogin) { return tbjson; }
            string apiurl = ApiSettingsHelper.GetConfig("X-KDApi-ServerUrl");
            apiurl += apiurl.Substring(apiurl.Length - 1, 1) == "/" ? "" : "/";         //如果最后一个字符不是"/"就添加上去
            apiurl += customservice.FNamespace + "." + customservice.FClassName + "." + customservice.FActionName + "," + customservice.FAppComponents;
            List<object> Parameters = new List<object>
            {
                sql
            };
            string content = JsonConvert.SerializeObject(Parameters);
            tbjson = _KdhttpClient.AsyncClientRequest(apiurl, content).Result;
            return tbjson;
        }

    }
}
