using AutoTurnOver.Models.ApiDto;
using AutoTurnOver.Utility;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Net;
using System.Text;
using System.Linq;
using AutoTurnOver.Models;
using AutoTurnOver.DB;
using System.Text.RegularExpressions;
using AutoTurnOver.Models.Base;
using System.Threading.Tasks;

namespace AutoTurnOver.Services
{
    public class ApiServices
    {
        /// <summary>
        /// 获取一二级的百伦分类数据
        /// </summary>
        /// <returns></returns>
        public static List<CategoryDto> GetCategoryAll()
        {
            List<CategoryDto> clsit = new List<CategoryDto>();
            clsit.AddRange(GetCategoryList(1));
            clsit.AddRange(GetCategoryList(2));
            return clsit;
        }

        public static List<CategoryDto> GetCategoryList(int level = 1)
        {
            if (level == 0)
            {
                List<CategoryDto> datas = new List<CategoryDto>();
                var tempLevel = 1;
                while (true)
                {
                    var tempDatas = GetCategoryList(tempLevel);
                    if (tempDatas != null && tempDatas.Count >= 1 && level <= 4)
                    {
                        datas.AddRange(tempDatas);
                    }
                    else
                    {
                        return datas;
                    }
                    tempLevel++;

                }
            }
            string appId = "SystemAims";
            string appKey = "YmFpbHVuQWltcw==";
            string url = "http://api.sku.bailuntec.com/api/BailunCateData/GetAllCategoryList";

            List<CategoryDto> result = new List<CategoryDto>();

            ApiEntrance model = new ApiEntrance();
            model.code = appId;
            model.data = level.ToString();

            string sign = Security.md5Encrypt(appKey + model.code + Security.md5Encrypt(model.key + model.data));
            string resultStr = HttpHelper.Request(url + $"?sign={sign}&appId={appId}&level={level}", RequestType.GET);
            ApiResult apiResult = resultStr.ToObj<ApiResult>();
            if (apiResult.result_code == 1)
            {
                result = WebUtility.UrlDecode(apiResult.data).ToObj<List<CategoryDto>>().Where(s => s.C_LEVEL == level).ToList();
            }
            return result;

        }

        /// <summary>
        /// 根据ID查询分类
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static CategoryDto GetCategoryById(int id)
        {
            var all = GetCategoryAll();
            return all.SingleOrDefault(s => s.C_ID == id);
        }

        /// <summary>
        /// 查询相关的子节点
        /// </summary>
        /// <param name="all"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public static List<CategoryDto> GetClientNodesByIds(List<int> ids)
        {
            if (ids == null || ids.Count <= 0)
            {
                return new List<CategoryDto>();
            }
            List<CategoryDto> datas = new List<CategoryDto>();
            var all = GetCategoryList(0);
            foreach (var item in ids)
            {
                datas.AddRange(GetClientNodesById(all, item));
            }
            return datas;
        }

        /// <summary>
        /// 查询相关的子节点
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public static List<CategoryDto> GetClientNodesById(List<CategoryDto> all, int id)
        {

            // 查询所有数据
            if (all == null)
            {
                all = GetCategoryList(0);
            }
            List<CategoryDto> clients = all.Where(s => s.C_ID == id).ToList();
            var cNodes = all.Where(s => s.C_PARENTID == id).ToList();
            if (cNodes != null || cNodes.Count >= 1)
            {
                foreach (var item in cNodes)
                {
                    clients.AddRange(GetClientNodesById(all, item.C_ID));
                }
            }
            return clients;


        }

        /// <summary>
        /// 推送采购计划
        /// </summary>
        /// <param name="data"></param>
        /// <param name="is_skip_error">是否跳过异常</param>
        /// <returns></returns>
        public static BuyOutputResult PushBuyPlan(mPlanToPurchaseDto data, bool is_skip_error)
        {
            try
            {
                //查询采购建议明细 
                string url = ConfigHelper.GetValue("PushBuyPlan");
                var parStr = ("obj=" + WebUtility.UrlDecode(data.ToJson()));
                Console.WriteLine($" {DateTime.Now} 推送采购单 输入：", parStr);
                string resultStr = HttpHelper.Request(url, RequestType.POST, parStr, timeout: 1000 * 60 * 60 * 24);
                Console.WriteLine($" {DateTime.Now} 推送采购单 输出：" + resultStr);
                var result = resultStr.ToObj<BuyOutputResult>();
                if (result == null)
                {
                    throw new Exception("采购系统异常： 推送失败，采购系统无响应");
                }
                if (!result.IsSuccessed)
                {
                    if (is_skip_error)
                    {
                        // 提取异常sku
                        var skus = ExtractSku(result.Message);
                        if (skus != null && skus.Count >= 1)
                        {
                            // 判断提取出来的sku 是否是我们想推送的sku ,但凡有一个不是我们想推送的，就抛异常
                            if (skus.Any(s => !data.bi_buyplandetail.Any(sku => sku.bd_sku.Equals(s, StringComparison.OrdinalIgnoreCase))))
                            {
                                throw new Exception($"采购系统异常:-------------采购系统抛出来的异常sku {skus.ToJson()} 在源推送sku中未找到-------源异常消息: " + result.Message);
                            }
                            else
                            {
                                // 移除该sku，尝试重新推送
                                data.bi_buyplandetail = data.bi_buyplandetail.Where(s => !skus.Any(sku => sku.Equals(s.bd_sku))).ToList();
                                var re = PushBuyPlan(data, is_skip_error);
                                if (re.fail_skus == null)
                                {
                                    re.fail_skus = new List<string>();
                                }
                                re.fail_skus.AddRange(skus);
                                return re;
                            }
                        }
                        else
                        {
                            throw new Exception("采购系统异常： " + result.Message);
                        }
                    }
                    else
                    {
                        throw new Exception("采购系统异常： " + result.Message);
                    }
                }
                return result;
            }
            catch (Exception ex)
            {
                throw new Exception(" 采购推送操作异常： " + ex.Message);
            }

        }

        /// <summary>
        /// 提取sku
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static List<string> ExtractSku(string message)
        {
            if (!message.Contains("SKU") && !message.Contains("sku"))
            {
                return null;
            }
            else
            {
                Regex skuRegex = new Regex(@"【[\s\S]+】");
                var skus = skuRegex.Matches(message);
                if (skus != null && skus.Count == 1)
                {
                    return skus[0].Value.Replace("【", "").Replace("】", "").Split(',').ToList();
                }
                else if (skus.Count > 1)
                {
                    report.AddError(new dc_task_error_log
                    {
                        date = DateTime.Now,
                        message = "异常中包含多个【】，识别异常",
                        stack_trace = message,
                        task_name = "AutoPushBuySys_ExtractSku"
                    });
                    return null;
                }
                else
                {
                    return null;
                }
            }
        }

        /// <summary>
        /// 账号列表
        /// </summary>
        public static List<AccountDto> AccountList()
        {
            //查询采购建议明细 
            return RedisHelper.Get(RedisConsts.Pams_GetAccountToken, () =>
            {
                string url = ConfigHelper.GetValue("Pams_GetAccountToken");
                string resultStr = HttpHelper.Request(url, RequestType.GET, "", timeout: 1000 * 60 * 60 * 24);
                var result = resultStr.ToObj<PamsResultDto<List<AccountDto>>>();
                if (result == null)
                {
                    throw new Exception("账号系统异常： 未获取到数据");
                }
                if (!result.Success)
                {
                    throw new Exception("账号系统异常： " + result.Message);
                }
                return result.Data;
            });
        }

        public static List<AccountDto> AccountList(string name)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(name)) return AccountList();
                return AccountList().Where(s =>
                   (s.OmsAccount ?? "").Contains(name, StringComparison.OrdinalIgnoreCase)
                    ||
                     (s.EmailAccount ?? "").Contains(name, StringComparison.OrdinalIgnoreCase)
                     ||
                      (s.Account ?? "").Contains(name, StringComparison.OrdinalIgnoreCase)
                ).ToList();
            }
            catch (Exception ex)
            {
                report.AddError(new dc_task_error_log
                {
                    date = DateTime.Now,
                    message = ex.Message,
                    stack_trace = ex.StackTrace,
                    task_name = "account_api"
                });
                throw;
            }



        }


        /// <summary>
        /// 查询crm case 数据
        /// </summary>
        public static List<crm_case_order_dto> CrmCaseOrder(List<string> order_no_list)
        {
            if (order_no_list == null || order_no_list.Count <= 0)
            {
                return new List<crm_case_order_dto>();
            }

            string url = ConfigHelper.GetValue("Crm_Case_Order");
            string resultStr = HttpHelper.Request(url, RequestType.POST, "order_no_list=" + string.Join(",", order_no_list), timeout: 1000 * 60 * 60 * 24);
            var result = resultStr.ToObj<crm_api_result_dto<List<crm_case_order_dto>>>();
            if (result == null)
            {
                throw new Exception("crm系统： 获取case 数据失败");
            }
            if (!result.success)
            {
                throw new Exception("crm系统： " + result.message);
            }
            return result.data;
        }

        public static List<crm_message_dto> CrmMessage(List<string> order_no_list)
        {
            if (order_no_list == null || order_no_list.Count <= 0)
            {
                return new List<crm_message_dto>();
            }

            string url = ConfigHelper.GetValue("Crm_Message");
            string resultStr = HttpHelper.Request(url, RequestType.POST, "order_no_list=" + string.Join(",", order_no_list), timeout: 1000 * 60 * 60 * 24);
            var result = resultStr.ToObj<crm_api_result_dto<List<crm_message_dto>>>();
            if (result == null)
            {
                throw new Exception("crm系统： 获取客户来信 数据失败");
            }
            if (!result.success)
            {
                throw new Exception("crm系统： " + result.message);
            }
            return result.data;
        }

        public static List<crm_message_reply_dto> CrmMessageReply(List<string> order_no_list)
        {
            if (order_no_list == null || order_no_list.Count <= 0)
            {
                return new List<crm_message_reply_dto>();
            }

            string url = ConfigHelper.GetValue("Crm_Message_Reply");
            string resultStr = HttpHelper.Request(url, RequestType.POST, "order_no_list=" + string.Join(",", order_no_list), timeout: 1000 * 60 * 60 * 24);
            var result = resultStr.ToObj<crm_api_result_dto<List<crm_message_reply_dto>>>();
            if (result == null)
            {
                throw new Exception("crm系统： 获取出信数据失败");
            }
            if (!result.success)
            {
                throw new Exception("crm系统： " + result.message);
            }
            return result.data;
        }

        public static List<LmsShipLogisticsDto> ShipLogisticsList()
        {
            return ApiUtility.ShipLogisticsList();
        }

        public static List<LmsShipLogisticsDto> ShipLogisticsList(string name)
        {
            try
            {
                var datas = ShipLogisticsList();
                if (!string.IsNullOrWhiteSpace(name))
                {
                    datas = datas.Where(s =>
                  (s.Line_Code ?? "").Contains(name, StringComparison.OrdinalIgnoreCase)
                   ||
                  (s.Line_Name ?? "").Contains(name, StringComparison.OrdinalIgnoreCase)
                ).ToList();
                }

                return datas;
            }
            catch (Exception ex)
            {
                report.AddError(new dc_task_error_log
                {
                    date = DateTime.Now,
                    message = ex.Message,
                    stack_trace = ex.StackTrace,
                    task_name = "ahipLogistics_api"
                });
                throw;
            }



        }
        
        public static List<LmsShipLogisticsDto> ShipLogisticsListHead(string name,string type)
        {
            try
            {
                var datas = ApiUtility.ShipLogisticsListHead();
                if (!string.IsNullOrWhiteSpace(name))
                {
                    datas = datas.Where(s =>
                  (s.Line_Code ?? "").Contains(name, StringComparison.OrdinalIgnoreCase)
                   ||
                  (s.Line_Name ?? "").Contains(name, StringComparison.OrdinalIgnoreCase)
                ).ToList();
                }
                if (!string.IsNullOrWhiteSpace(type))
                {
                    var type_int = 0;
                    if (type == "空运")
                    {
                        type_int = 2;
                    }
                    else if (type == "海运")
                    {
                        type_int = 3;
                    }
                    else if (type == "陆运")
                    {
                        type_int = 1;
                    }

                    datas =  datas.Where(s=>s.TransportType==type_int).ToList();
                }
                return datas;
            }
            catch (Exception ex)
            {
                report.AddError(new dc_task_error_log
                {
                    date = DateTime.Now,
                    message = ex.Message,
                    stack_trace = ex.StackTrace,
                    task_name = "ahipLogistics_api"
                });
                throw;
            }



        }

        /// <summary>
        /// 平台列表
        /// </summary>
        public static List<PlatformDto> PlatformList()
        {
            string url = ConfigHelper.GetValue("Pams_PlatformList");
            string resultStr = HttpHelper.Request(url, RequestType.GET, "", timeout: 1000 * 60 * 60 * 24);
            var result = resultStr.ToObj<PamsResultDto<List<PlatformDto>>>();
            if (result == null)
            {
                throw new Exception("账号系统异常： 未获取到平台数据");
            }
            if (!result.Success)
            {
                throw new Exception("账号系统异常： " + result.Message);
            }
            return result.Data;
        }

        /// <summary>
        /// 查询出信模板
        /// </summary>
        /// <param name="order_no_list"></param>
        /// <returns></returns>
        public static List<crm_message_custom_template_dto> MessageCustomTemplateList()
        {

            string url = ConfigHelper.GetValue("Crm_Message_Custom_Template");
            string resultStr = HttpHelper.Request(url, RequestType.POST, "", timeout: 1000 * 60 * 60 * 24);
            var result = resultStr.ToObj<crm_api_result_dto<List<crm_message_custom_template_dto>>>();
            if (result == null)
            {
                throw new Exception("crm系统： 获取case 数据失败");
            }
            if (!result.success)
            {
                throw new Exception("crm系统： " + result.message);
            }
            return result.data;
        }

        /// <summary>
        /// 出信
        /// </summary>
        public static void SendMessage(ApiSendMessageInputDto data)
        {
            //查询采购建议明细 
            string url = ConfigHelper.GetValue("CRM_SendMessage");
            string resultStr = HttpHelper.Request(url, RequestType.POST, data.ToJson(), timeout: 1000 * 60 * 60 * 24, entype: "application/json");
            var result = resultStr.ToObj<crm_api_result_null_dto>();
            if (result == null)
            {
                throw new Exception("CRM系统异常： 推送失败");
            }
            if (!result.success)
            {
                throw new Exception("crm系统异常： " + result.message);
            }
            return;
        }

        /// <summary>
        /// 缺货推送 (分页推送)
        /// </summary>
        public static List<ShortagePush_Item_RequestDto> ShortagePush(List<dc_auto_shortage_push> datas, string platform)
        {

            var err_datas = new List<ShortagePush_Item_RequestDto>();
            if (datas.Count <= 0) return new List<ShortagePush_Item_RequestDto>();
            int page = 1;
            int rows = 1000;
            int totalPage = (int)Math.Ceiling(datas.Count() * 1.0 / rows);
            while (page <= totalPage)
            {
                var result = ShortagePushApi(new ShortagePush_RequestDto
                {
                    platform = platform,
                    skuType = 1,
                    amisSkuInfos = datas.Skip((page - 1) * rows).Take(rows).Select(s => new ShortagePush_Item_RequestDto
                    {
                        sku = s.bailun_sku,
                        warehouseCode = s.warehouse_code,
                        stocks = s.stocks
                    }).ToList()
                });
                if (!result.isSucceeded && result.objData.Count >= 1)
                {
                    err_datas.AddRange(result.objData);
                }
                page++;
            }


            return err_datas;
        }

        /// <summary>
        /// 缺货推送
        /// </summary>
        private static ShortagePush_ResponseDto ShortagePushApi(ShortagePush_RequestDto data)
        {
            //string url = ConfigHelper.GetValue("PPS_ShortagePush");
            string url = ConfigHelper.GetValue("PPS_ShortagePush2");
            //string resultStr1 = HttpHelper.Request(url2, RequestType.POST, data.ToJson(), timeout: 1000 * 60 * 60 * 24, entype: "application/json");
            string resultStr = HttpHelper.Request(url, RequestType.POST, data.ToJson(), timeout: 1000 * 60 * 60 * 24, entype: "application/json");
            var result = resultStr.ToObj<ShortagePush_ResponseDto>();
            if (result == null)
            {
                throw new Exception("刊登系统异常： 推送失败");
            }
            return result;
        }

        /// <summary>
        /// 回货速改推送 (分页推送)
        /// </summary>
        public static List<ShortagePush_Item_RequestDto> ReturnGoodsPush(List<dc_return_goods_push> original_datas_datas, string platform)
        {
            var datas = original_datas_datas.GroupBy(s => new { s.bailun_sku, s.warehouse_code }).Select(s=>s.FirstOrDefault()).ToList();
            var err_datas = new List<ShortagePush_Item_RequestDto>();
            if (datas.Count <= 0) return new List<ShortagePush_Item_RequestDto>();
            int page = 1;
            int rows = 1000;
            int totalPage = (int)Math.Ceiling(datas.Count * 1.0 / rows);
            while (page <= totalPage)
            {
                var result = ReturnGoodsPushApi(new ShortagePush_RequestDto
                {
                    platform = platform,
                    skuType = 2,
                    amisSkuInfos = datas.Skip((page - 1) * rows).Take(rows).Select(s => new ShortagePush_Item_RequestDto
                    {
                        stocks = s.stocks,
                        sku = s.bailun_sku,
                        warehouseCode = s.warehouse_code
                    }).ToList()
                });
                if (!result.isSucceeded && result.objData.Count >= 1)
                {
                    err_datas.AddRange(result.objData);
                }
                page++;
            }

            return err_datas;
        }

        /// <summary>
        /// 回货速改推送
        /// </summary>
        private static ShortagePush_ResponseDto ReturnGoodsPushApi(ShortagePush_RequestDto data)
        {
            //string url = ConfigHelper.GetValue("PPS_ShortagePush");
            string url = ConfigHelper.GetValue("PPS_ShortagePush2");
            //string resultStr2= HttpHelper.Request(url2, RequestType.POST, data.ToJson(), timeout: 1000 * 60 * 60 * 24, entype: "application/json");
            string resultStr = HttpHelper.Request(url, RequestType.POST, data.ToJson(), timeout: 1000 * 60 * 60 * 24, entype: "application/json");
            var result = resultStr.ToObj<ShortagePush_ResponseDto>();
            if (result == null)
            {
                throw new Exception("刊登系统异常： 推送失败");
            }
            return result;
        }

        public static void QiYeJiQiRenMsPush(QiYeJiQiRenMsDto data)
        {
            string url = ConfigHelper.GetValue("QiYeJiQiRen");
            string resultStr = HttpHelper.Request(url, RequestType.POST, data.ToJson(), timeout: 1000 * 60 * 60 * 24, entype: "application/json");

        }

        /// <summary>
        /// 查看今天是否需要上班
        /// </summary>
        /// <returns></returns>
        public static bool GetSchedulings()
        {
            return true;
            try
            {
                var date_str = DateTime.Now.ToString("yyyy-MM-dd");
                string url = ConfigHelper.GetValue("GetSchedulings");
                string resultStr = HttpHelper.Request(url + $"&btime={date_str}&etime={date_str}", RequestType.GET, timeout: 1000 * 60 * 60 * 24);
                var result = resultStr.ToObj<scheduling_response_dto>();
                if (result == null)
                {
                    throw new Exception("oa系统异常： 获取上班数据失败 ");
                }
                return result.data.Any(s => s.status == 1);
            }
            catch (Exception)
            {
                return true;
            }

        }

        /// <summary>
        /// 获取一二级新百伦分类
        /// </summary>
        /// <returns></returns>
        public static List<bailun_category_new_dto> GetNewCategoryAll()
        {
            return GetNewCategoryList(0);
        }

        /// <summary>
        /// 根据基本查询分类
        /// </summary>
        /// <param name="level"></param>
        /// <returns></returns>
        public static List<bailun_category_new_dto> GetNewCategoryList(int level = 1)
        {

            string url = ConfigHelper.GetValue("SkuSys_CategoryList");
            string resultStr = HttpHelper.Request(url + $"?level={level}", RequestType.GET, timeout: 1000 * 60 * 60 * 24);
            var result = resultStr.ToObj<saas_api_result<List<bailun_category_new_dto>>>();
            if (result == null)
            {
                throw new Exception("skums 系统  新百伦分类接口异常： 未获取到新百伦分类数据");
            }
            if (result.statusCode != 200)
            {
                throw new Exception("wms系统  新百伦分类接口 异常： " + result.message);
            }
            return result.result;
        }

        /// <summary>
        /// 根据ID查询分类
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static bailun_category_new_dto GetNewCategoryById(int id)
        {
            var all = GetNewCategoryAll();
            return all.SingleOrDefault(s => s.id == id);
        }

        /// <summary>
        /// 获取顶层分类
        /// </summary>
        /// <param name="category_id"></param>
        /// <returns></returns>
        public static bailun_category_new_dto GetTopNewCategory(List<bailun_category_new_dto> datas, int category_id)
        {
            if (datas == null) datas = GetNewCategoryAll();
            var c_data = datas.SingleOrDefault(s => s.id == category_id);
            if (c_data == null) throw new Exception($" 分类id {category_id} 不存在 ");
            if (c_data.parentId == 0) return c_data;

            return GetTopNewCategory(datas, c_data.parentId);

        }

        /// <summary>
        /// 查询相关的子节点
        /// </summary>
        /// <param name="all"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public static List<bailun_category_new_dto> GetNewClientNodesByIds(List<int> ids)
        {
            if (ids == null || ids.Count <= 0)
            {
                return new List<bailun_category_new_dto>();
            }
            List<bailun_category_new_dto> datas = new List<bailun_category_new_dto>();
            var all = GetNewCategoryList(0);
            foreach (var item in ids)
            {
                datas.AddRange(GetNewClientNodesById(all, item));
            }
            return datas;
        }

        /// <summary>
        /// 查询相关的子节点
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public static List<bailun_category_new_dto> GetNewClientNodesById(List<bailun_category_new_dto> all, int id)
        {

            // 查询所有数据
            if (all == null)
            {
                all = GetNewCategoryList(0);
            }
            List<bailun_category_new_dto> clients = all.Where(s => s.id == id).ToList();
            var cNodes = all.Where(s => s.parentId == id).ToList();
            if (cNodes != null || cNodes.Count >= 1)
            {
                foreach (var item in cNodes)
                {
                    clients.AddRange(GetNewClientNodesById(all, item.id));
                }
            }
            return clients;


        }

        public static List<platform_type_website_dto> PlatformtypeWebsiteList(string platform_type)
        {

            //查询采购建议明细 
            //var datas = RedisHelper.Get(RedisConsts.platform_type_website, () =>
            //{
            //    return report.GetPlatformWebsite();
            //});
            var datas = report.PlatformtypeWebsiteList(platform_type);
            if (!string.IsNullOrWhiteSpace(platform_type))
            {
                datas = datas.Where(s => platform_type.Equals(s.platform_type, StringComparison.OrdinalIgnoreCase)).ToList();
            }
            return datas;
        }


        /// <summary>
        /// 获取缺货数据
        /// </summary>
        /// <param name="search"></param>
        /// <returns></returns>
        public static Page<dc_quantity_out_stock_dto> GetOutStockPage(dc_quantity_out_stock_search_dto search)
        {
            return api_dao.GetOutStockPage(search);
        }

        /// <summary>
        /// 获取缺货数据
        /// </summary>
        /// <param name="search"></param>
        /// <returns></returns>
        public static async Task<IEnumerable<dc_base_oms_sku_full_dto>> GetOmsSkuFullPage(dc_base_oms_sku_full_search_dto search)
        {
            return await api_dao.GetOmsSkuFullPage(search);
        }


        /// <summary>
        /// 获取缺货数据
        /// </summary>
        /// <param name="search"></param>
        /// <returns></returns>
        public static Page<api_sku_sales_volume_dto> GetSkuSalesVolume(api_sku_sales_volume_search_dto search)
        {
            return api_dao.GetSkuSalesVolume(search);
        }

        public static Page<api_sku_tort_dto> GetSkuTort(api_sku_tort_search_dto search)
        {
            return api_dao.GetSkuTort(search);
        }
    }
}
