using COSXML.Network;
using dodohold.core;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR.Protocol;
using System.Diagnostics;
using System.Net;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Threading.Channels;
using TencentCloud.Cwp.V20180228.Models;
using YunhuiKit;


namespace molilian.core
{
    public partial class UnionParseCore
    {
        private static readonly HashSet<string> BusyLimitedRiskStrategies = new(StringComparer.OrdinalIgnoreCase)
        {
            "tbpush",
            "icon"
        };

        private static readonly int BusyLimitedWindowSeconds = GetIntEnv("TbPushIconThrottleWindowSeconds", 5);
        private static readonly int BusyLimitedMaxRequests = GetIntEnv("TbPushIconThrottleMaxRequests", 100);

        /// <summary>
        /// 联盟转链统一入口
        /// </summary>
        public static async Task<ActionResult> UnionParseAsync(UnionParseRequest request)
        {

            switch (request.Channel)
            {
                case "tbpush":
                case "brwsimilar":
                case "icon":
                    request.RiskStrategy = request.Channel;
                    request.LaunchScene = 0;
                    request.Channel = "tb";
                    break;
            }

            switch (request.RiskStrategy)
            {
                case "tbpush":
                case "brwsimilar":
                case "icon":
                    if (request.LaunchScene == -1) request.LaunchScene = 0;
                    break;
            }

            request.Content = request.Content.Trim();

            var busyRejectResult = TryRejectBusyLimitedRequest(request);
            if (busyRejectResult != null)
            {
                return busyRejectResult;
            }

            if (request.SpecialText == 1)
            {
                return await SpecialTextParseAsync(request);
            }

            switch (request.Type)
            {
                case "dp":
                    return request.Channel switch
                    {
                        "jd" => await DeeplinkJdParseAsync(request),
                        "pdd" => await DeeplinkPddParseAsync(request),
                        "tb" => await DeeplinkTaobaoParseAsync(request),
                    };
                //case "ym":
                //    return request.Channel switch
                //    {
                //        "tb" => await DeeplinkTaobaoParseAsync(request),
                //        //"tb" => await DeepleaperParseAsync(request),
                //    };
                case "goods":
                    return request.Channel switch
                    {
                        "jd" => await GoodsJdParseAsync(request),
                        "pdd" => await GoodsPddParseAsync(request),
                    };
            }

            var config = TkConfigCore.Get();

            if (ZlongForwardChannels.IsEnabled($"{config.webook_forward_zlong}", request.Channel)
                && !string.IsNullOrEmpty(request.Oaid))
            {
                _ = ZlongForwardCore.ForwardAsync(request.Channel, request.Oaid);
            }

            return request.Channel switch
            {
                //"wemeet" => await WemeetParseAsync(request),
                //"bdpan" => await PanParseAsync(request),
                "jd" => await JdParseAsync(request),
                "ks" => await KsParseAsync(request),
                "dy" => await DyParseAsync(request),
                "pdd" => await PddParseAsync(request),
                "tb" => await TaobaoParseAsync(request),
                _ => await DeeplinkParseCore.ParseAsync(request),
            };
        }

        //return await DeeplinkParseCore.ParseAsync(content, channel, ip, oaid);

        public static async Task<APIResult> WemeetParseAsync(string content, string ip, string oaid)
        {
            var result = ToolParsePlus.GetFormattedObject(TkChannelEnum.wemeet, content, ip, oaid);
            content = content.UrlDecode();
            result.rawContent = content;
            try
            {
                result = await ToolParsePlus.WemeetParseAsync(content, result);
            }
            catch (Exception ex)
            {
                _ = new LoggerLibrary("unionParse", "wemeet_error")
                    .Info(ip, oaid)
                    .Info(content)
                    .Info(ex.Message, ex.StackTrace)
                    .SaveAsync();
                NotifyCore.Notify(new NifyMessage
                {
                    message = $"【转链异常Wemeet】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
                    priority = NifyMessagePriority.high,
                    tags = ["red_circle"]
                });
                result.success = false;
                result.message = "内部错误";
                result.reason = "转链接口异常";
            }
            _ = TkLogCore.ParseLogAsync(result);
            return new APIResult(new
            {
                result.success,
                result.message,
                channel = result?.channel.ToString(),
                result.shortLinkurl,
                result.deeplink_url,
                result.itemName,
            }, result.success ? APIResultCodeEnum.OK : APIResultCodeEnum.NotAcceptable);
        }

        public static async Task<ActionResult> PanParseAsync(string content, string ip, string oaid)
        {

            string pattern = ".*(https://snsyun\\.baidu\\.com/sl/[A-Za-z0-9?=]+).*";
            var regex = new Regex(pattern);
            var match = regex.Match(content);
            if (match.Success)
            {
                var request = new UnionParseRequest
                {
                    Content = content,
                    Channel = "bdpan",
                    Ip = ip,
                    Oaid = oaid
                };
                return await DeeplinkParseCore.ParseAsync(request);
            }


            var result = ToolParsePlus.GetFormattedObject(TkChannelEnum.bdpan, content, ip, oaid);
            content = content.UrlDecode();
            result.rawContent = content;
            try
            {
                ToolParsePlus.PanParse(content, ref result);
            }
            catch (Exception ex)
            {
                _ = new LoggerLibrary("unionParse", "pan_error")
                    .Info(ip, oaid)
                    .Info(content)
                    .Info(ex.Message, ex.StackTrace)
                    .SaveAsync();
                NotifyCore.Notify(new NifyMessage
                {
                    message = $"【转链异常Pan】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
                    priority = NifyMessagePriority.high,
                    tags = ["red_circle"]
                });
                result.success = false;
                result.message = "内部错误";
                result.reason = "转链接口异常";
            }
            _ = TkLogCore.ParseLogAsync(result);
            return new APIResult(new
            {
                result.success,
                result.message,
                channel = result?.channel.ToString(),
                result.shortLinkurl,
                result.deeplink_url,
                result.itemName,
            }, !string.IsNullOrEmpty(result.deeplink_url) ? APIResultCodeEnum.OK : APIResultCodeEnum.NotAcceptable);
        }

        private static bool ValidateDeeplinkIfRequired(bool success, string deeplink_url)
        {
            //根据 deeplink 是否为空返回 success 值
            //return !string.IsNullOrEmpty(deeplink_url);

            //暂时不判断
            return success;
        }

        private static APIResult TaobaoParseOutput(TkDataDTO result, Dictionary<string, long> swData, object info, APIResultCodeEnum code = APIResultCodeEnum.OK)
        {
            if (result.elapsedTime > 2000)
            {
                LoggerLibrary log = new("debug", "stopwatch");
                foreach ((var key, var value) in swData)
                {
                    log.Info($"{key}\t{value}");
                }
                log.SaveAsync();
            }
            return new APIResult(info, code);
        }

        private static ActionResult? TryRejectBusyLimitedRequest(UnionParseRequest request)
        {
            if (!"pdd".Equals(request.Channel, StringComparison.OrdinalIgnoreCase))
            {
                return null;
            }

            if (!BusyLimitedRiskStrategies.Contains(request.RiskStrategy))
            {
                return null;
            }

            var window = TimeSpan.FromSeconds(BusyLimitedWindowSeconds);
            var bucketKey = $"pdd_{request.RiskStrategy.ToLowerInvariant()}";
            if (SpecialBusinessRateLimiter.TryAcquire(bucketKey, BusyLimitedMaxRequests, window))
            {
                return null;
            }

            var result = PddUnionPlus.GetFormattedObject(request);
            result.link_type = LinkTypeEnum.unknown;
            result.channel_type = ChannelTypeEnum.pdd;
            result.rawContent = request.Content;
            result.success = false;
            result.message = "放弃转链";
            result.reason = "系统繁忙";
            result.subCode = (int)TkSubCodeEnum.TrafficCtrl;
            result.deeplink_url = string.IsNullOrEmpty(result.shortLinkurl) ? string.Empty : PddUnionPlus.GetDeeplink(result.shortLinkurl);
            _ = TkLogCore.ParseLogAsync(result);
            return PddParseOutput(result);
        }

        private static int GetIntEnv(string key, int defaultValue)
        {
            var raw = Environment.GetEnvironmentVariable(key);
            return int.TryParse(raw, out var value) && value > 0 ? value : defaultValue;
        }


        public static async Task<APIResult> DeepleaperParseAsync(UnionParseRequest request)
        {
            //content = content.UrlDecode();
            var result = AlimamaPlus.GetFormattedObject(request);
            result.shortLinkurl = string.Empty;
            result.deeplink_url = string.Empty;

            result.riskStrategy = request.RiskStrategy;
            result.launchScene = request.LaunchScene;
            result.rawContent = request.Content;

            Dictionary<string, long> swData = new();
            swData.Add("StartNew", 0);
            Stopwatch stopwatch = Stopwatch.StartNew();

            try
            {
                TkPoolDTO? account = await TkPoolCore.GetOneAsync(TkPoolCore.TkAction.parse, true, string.Empty, -1, "ym", string.Empty);
                if (account == null)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "没有匹配账号";
                    result.subCode = TkSubCodeEnum.Other;
                    result.itemName = "点击打开淘宝APP";

                    _ = TkLogCore.ParseLogAsync(result);
                    return TaobaoParseOutput(result, swData, new
                    {
                        success = ValidateDeeplinkIfRequired(result.success, result.deeplink_url),
                        result.commercial,
                        result.with_middle_page,
                        result.message,
                        result.content,
                        sub_message = result.reason,
                        home_page = "tbopen://m.taobao.com/tbopen/index.html".Equals(result.deeplink_url),
                        result.couponAmount,
                        result.taoToken,
                        result.shortLinkurl,
                        result.deeplink_url,
                    });
                }


                string reason = string.Empty;

                result.accountId = account.id;
                result.accountName = account.name;


                int timeout = 5000;
#if DEBUG
                timeout = 5000;
#endif
                using var cts = new CancellationTokenSource();
                cts.CancelAfter(timeout);

                DeepleaperPlus deepleaperPlus = new(account.nodeName);

                var requestTask = Task.Run(async () => result = await deepleaperPlus.UnionParseAsync(result), cts.Token);
                var delayTask = Task.Delay(timeout, cts.Token);
                var completedTask = await Task.WhenAny(requestTask, delayTask);
                if (completedTask == requestTask)
                {
                    result = await requestTask;
                }
                else
                {
                    //============================== 放弃转链-请求超时 ==============================
                    cts.Cancel();
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "请求超时";
                    result.subCode = TkSubCodeEnum.Other;
                    result.itemName = "点击打开淘宝APP";
                }
            }
            catch (Exception ex)
            {
                //============================== 放弃转链-请求超时 ==============================
                if (ex.Message.Contains("was canceled"))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "请求超时";
                    result.subCode = TkSubCodeEnum.Other;
                    result.itemName = "点击打开淘宝APP";
                }
                else
                {
                    //============================== 转链接口异常 ==============================
                    _ = new LoggerLibrary("unionParse", "tb_error")
                        .Info(request.Ip, request.Oaid)
                        .Info(request.Content)
                        .Info(ex.Message, ex.StackTrace)
                        .SaveAsync();

                    NotifyCore.Notify(new NifyMessage
                    {
                        message = $"【转链异常TB】\n{request.Content}\n\n{ex.Message}\n{ex.StackTrace}",
                        priority = NifyMessagePriority.high,
                        tags = ["red_circle"]
                    });
                    result.success = false;
                    result.subCode = TkSubCodeEnum.Other;
                    result.message = "转链接口异常";
                    result.itemName = "点击打开淘宝APP";
                }
            }

            var now = DateTime.Now;
            var ts = now - result.create_time;
            result.elapsedTime = (int)ts.TotalMilliseconds;


            _ = TkLogCore.ParseLogAsync(result);

            return TaobaoParseOutput(result, swData, new
            {
                success = ValidateDeeplinkIfRequired(result.success, result.deeplink_url),
                result.commercial,
                exposeTracks = TracksCore.BuildPath(TrackType.Expose, result),
                clickTracks = TracksCore.BuildPath(TrackType.Click, result),
                result.with_middle_page,
                result.message,
                sub_message = result.reason,
                home_page = "tbopen://m.taobao.com/tbopen/index.html".Equals(result.deeplink_url),
                link_type = result.link_type.ToString(),
                channel = result?.channel.ToString(),
                result.channel_type,
                result.itemId,
                result.itemName,
                result.pic,
                result.zkFinalPrice,
                result.reservePrice,
                result.promotionPrice,
                result.couponAmount,
                result.couponEffectiveStartTime,
                result?.couponEffectiveEndTime,
                result.shortLinkurl,
                result.deeplink_url,
                result.riskStrategy,
                result.launchScene,
                result.content,
                result.taoToken,
            });
        }


        public static async Task<APIResult> TaobaoParseAsync(UnionParseRequest request)
        {
            bool other_aff = false;
            AlimamaPlus alimama = null;
            //content = content.UrlDecode();
            var result = AlimamaPlus.GetFormattedObject(request);

            result.riskStrategy = request.RiskStrategy;
            result.launchScene = request.LaunchScene;
            result.rawContent = request.Content;

            Dictionary<string, long> swData = new();
            swData.Add("StartNew", 0);
            Stopwatch stopwatch = Stopwatch.StartNew();

            try
            {
                string content = result.content[..Math.Min(1000, result.content.Length)];

                string reason = string.Empty;

                var config = TkConfigCore.Get();
                var arr = config.tk_whitelist_regular.Split('\n')
                    .Where(line => !string.IsNullOrWhiteSpace(line))
                    .ToList();

                var arr2 = config.tk_blacklist_regular.Split('\n')
                    .Where(line => !string.IsNullOrWhiteSpace(line))
                    .ToList();


                var arr3 = config.multi_token_regular.Split('\n')
                    .Where(line => !string.IsNullOrWhiteSpace(line))
                    .ToList();


                bool is_tao_url = !string.IsNullOrEmpty(result.shortLinkurl);
                bool is_tao_token = AlimamaPlus.MatchRegexes(content, arr);
                bool is_other = AlimamaPlus.MatchOtherInfo(content, arr2);


                var overrideContent = await OverrideRuleCore.ProcessAsync(request);
                if (overrideContent != null)
                {
                    result.success = true;
                    result.deeplink_url = overrideContent.output_text;

                    _ = TkLogCore.ParseLogAsync(result);
                    return TaobaoParseOutput(result, swData, new
                    {
                        success = ValidateDeeplinkIfRequired(result.success, result.deeplink_url),
                        result.commercial,
                        exposeTracks = TracksCore.BuildPath(TrackType.Expose, result),
                        clickTracks = TracksCore.BuildPath(TrackType.Click, result),
                        result.with_middle_page,
                        result.message,
                        sub_message = result.reason,
                        home_page = "tbopen://m.taobao.com/tbopen/index.html".Equals(result.deeplink_url),
                        result.content,
                        result.itemName,
                        other_aff,
                        result.deeplink_url,
                    });
                }


                //============================== 放弃转链-初步筛选1 ==============================
                if (!is_tao_url && !is_tao_token || is_other)
                {
                    //没有链接都放弃
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "初步筛选1";
                    result.subCode = TkSubCodeEnum.Prelim1;
                    result.itemName = "";
                    result.deeplink_url = string.Empty;
                    _ = TkLogCore.ParseLogAsync(result);

                    return TaobaoParseOutput(result, swData, new
                    {
                        success = ValidateDeeplinkIfRequired(result.success, result.deeplink_url),
                        result.commercial,
                        result.with_middle_page,
                        result.message,
                        sub_message = result.reason,
                        home_page = "tbopen://m.taobao.com/tbopen/index.html".Equals(result.deeplink_url),
                        result.content,
                        result.itemName,
                        other_aff,
                        result.deeplink_url,
                    });
                }


                bool is_multi_token = AlimamaPlus.MatchMultiToken(content, arr3);
                //============================== 放弃转链-初步筛选1.5 ==============================
                if (is_multi_token)
                {
                    //没有链接都放弃
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "初步筛选1.5";
                    result.subCode = TkSubCodeEnum.Prelim1_5;
                    result.itemName = "";
                    result.deeplink_url = string.Empty;
                    _ = TkLogCore.ParseLogAsync(result);

                    return TaobaoParseOutput(result, swData, new
                    {
                        success = ValidateDeeplinkIfRequired(result.success, result.deeplink_url),
                        result.commercial,
                        result.with_middle_page,
                        result.message,
                        sub_message = result.reason,
                        home_page = "tbopen://m.taobao.com/tbopen/index.html".Equals(result.deeplink_url),
                        result.content,
                        result.itemName,
                        other_aff,
                        result.deeplink_url,
                    });
                }

                //============================== 放弃转链-初步筛选2 ==============================
                bool is_aff_link = false;
                if (!string.IsNullOrEmpty(result.shortLinkurl)) is_aff_link = AlimamaPlus.IsAffLink(result.shortLinkurl);
                if (!is_tao_url && is_tao_token)
                {
                    //淘宝口令
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "初步筛选2";
                    result.subCode = TkSubCodeEnum.Prelim2;
                    result.itemName = "点击打开淘宝APP";
                    _ = TkLogCore.ParseLogAsync(result);


                    //20241229 特例
                    //if ("bj".Equals(EndPointCore.CurrentEndPoint))
                    //{
                    //    string ruleKey = $"tmp_rules2:tb:{DateTime.Now:yyyyMMdd}";
                    //    var count = RedisHelper.Get<int>(ruleKey);
                    //    var now = DateTime.Now;
                    //    if (now > new DateTime(2024, 12, 19) && now <= new DateTime(2024, 12, 22) && now.Hour >= 7 && count < 1000)
                    //    {
                    //        result.deeplink_url = "tbopen://m.taobao.com/tbopen/index.html?source=auto&action=ali.open.nav&module=h5&bootImage=0&afc_route=1&bc_fl_src=growth_dhh_2200803434968_100-1930985-1595034112&dpa_Inid=159503411212096&dpa_material_id=530637422585&dpa_material_type=1&dpa_source_code=12096&force_no_smb=true&h5Url=https%3A%2F%2Fs.m.taobao.com%2Fh5%3Ffrom%3Dcustoms%26g_channelSrp%3Ddhhdpa_1232552832%26dpa_material_type%3D1%26ut_sk%3Dsearch%26spm%3Da2141.mb819t211c7%26sLaunch%3D0%26sKeep%3D1%26sModuleName%3Dsearch%26spm_back_up%3Da2141.mb819t211c7%26bc_fl_src%3Dgrowth_dhh_2200803434968_100-1930985-1595034112%26dpa_Inid%3D159503411212096%26dpa_material_id%3D530637422585%26dpa_material_type%3D1%26dpa_source_code%3D12096%26force_no_smb%3Dtrue%26itemIds%3D530637422585%26slk_actid%3D100000000207%26spm%3D2014.ugdhh.2200803434968.100-1930985-1595034112%26wh_biz%3Dtm&itemIds=530637422585&slk_actid=100000000207&spm=2014.ugdhh.2200803434968.100-1930985-1595034112&wh_biz=tm";
                    //        RedisHelper.IncrBy(ruleKey);
                    //        RedisHelper.Expire(ruleKey, 86400 * 1);
                    //    }
                    //}

                    other_aff = true;
                    return TaobaoParseOutput(result, swData, new
                    {
                        success = ValidateDeeplinkIfRequired(result.success, result.deeplink_url),
                        result.commercial,
                        result.with_middle_page,
                        result.message,
                        sub_message = result.reason,
                        home_page = "tbopen://m.taobao.com/tbopen/index.html".Equals(result.deeplink_url),
                        result.content,
                        result.itemName,
                        other_aff,
                        result.deeplink_url,
                    });

                }
                if ((!is_tao_url && is_tao_token) || is_aff_link)
                {
                    //没有短链接都放弃
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "初步筛选2";
                    result.subCode = TkSubCodeEnum.Prelim2;
                    result.itemName = "点击打开淘宝APP";

                    _ = TkLogCore.ParseLogAsync(result);

                    //20241229 特例
                    //if ("bj".Equals(EndPointCore.CurrentEndPoint))
                    //{
                    //    string ruleKey = $"tmp_rules2:tb:{DateTime.Now:yyyyMMdd}";
                    //    var count = RedisHelper.Get<int>(ruleKey);
                    //    var now = DateTime.Now;
                    //    if (now > new DateTime(2024, 12, 19) && now <= new DateTime(2024, 12, 22) && now.Hour >= 7 && count < 1000)
                    //    {
                    //        result.deeplink_url = "tbopen://m.taobao.com/tbopen/index.html?source=auto&action=ali.open.nav&module=h5&bootImage=0&afc_route=1&bc_fl_src=growth_dhh_2200803434968_100-1930985-1595034112&dpa_Inid=159503411212096&dpa_material_id=530637422585&dpa_material_type=1&dpa_source_code=12096&force_no_smb=true&h5Url=https%3A%2F%2Fs.m.taobao.com%2Fh5%3Ffrom%3Dcustoms%26g_channelSrp%3Ddhhdpa_1232552832%26dpa_material_type%3D1%26ut_sk%3Dsearch%26spm%3Da2141.mb819t211c7%26sLaunch%3D0%26sKeep%3D1%26sModuleName%3Dsearch%26spm_back_up%3Da2141.mb819t211c7%26bc_fl_src%3Dgrowth_dhh_2200803434968_100-1930985-1595034112%26dpa_Inid%3D159503411212096%26dpa_material_id%3D530637422585%26dpa_material_type%3D1%26dpa_source_code%3D12096%26force_no_smb%3Dtrue%26itemIds%3D530637422585%26slk_actid%3D100000000207%26spm%3D2014.ugdhh.2200803434968.100-1930985-1595034112%26wh_biz%3Dtm&itemIds=530637422585&slk_actid=100000000207&spm=2014.ugdhh.2200803434968.100-1930985-1595034112&wh_biz=tm";
                    //        RedisHelper.IncrBy(ruleKey);
                    //        RedisHelper.Expire(ruleKey, 86400 * 1);
                    //    }
                    //}

                    other_aff = true;
                    return TaobaoParseOutput(result, swData, new
                    {
                        success = ValidateDeeplinkIfRequired(result.success, result.deeplink_url),
                        result.commercial,
                        result.with_middle_page,
                        result.message,
                        sub_message = result.reason,
                        home_page = "tbopen://m.taobao.com/tbopen/index.html".Equals(result.deeplink_url),
                        result.content,
                        result.itemName,
                        other_aff,
                        result.deeplink_url,
                    });
                }



                //那就初步筛选3   有tb.cn 并且有   or  手淘发现
                string pattern = @"^(?!【淘宝】).*https?:\/\/m\.tb\.cn.*(?:手淘发现|手淘搜索)";
                bool isMatch = Regex.IsMatch(content, pattern);
                if (isMatch)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "初步筛选3";
                    result.subCode = TkSubCodeEnum.Prelim3;
                    result.itemName = "点击打开淘宝APP";

                    _ = TkLogCore.ParseLogAsync(result);

                    return TaobaoParseOutput(result, swData, new
                    {
                        success = ValidateDeeplinkIfRequired(result.success, result.deeplink_url),
                        result.commercial,
                        result.with_middle_page,
                        result.message,
                        sub_message = result.reason,
                        home_page = "tbopen://m.taobao.com/tbopen/index.html".Equals(result.deeplink_url),
                        result.content,
                        result.itemName,
                        other_aff,
                        result.deeplink_url,
                    });

                }
                //============================== 放弃转链-地区过滤 ==============================

                bool is_ignore2 = AlimamaPlus.ShouldIgnoreRequest(request, out reason);

                if (is_ignore2)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.itemName = "点击打开淘宝APP";
                    result.reason = reason;
                    result.subCode = TkSubCodeEnum.TrafficCtrl;

                    _ = TkLogCore.ParseLogAsync(result);
                    return TaobaoParseOutput(result, swData, new
                    {
                        success = ValidateDeeplinkIfRequired(result.success, result.deeplink_url),
                        result.commercial,
                        result.with_middle_page,
                        result.message,
                        sub_message = result.reason,
                        home_page = "tbopen://m.taobao.com/tbopen/index.html".Equals(result.deeplink_url),
                        result.content,
                        result.itemName,
                        other_aff,
                        result.deeplink_url,
                    });
                }

                (bool isTaobaoUrl, string url) = AlimamaPlus.IsTaobaoUrl(content);

                //============================== 放弃转链-没有匹配账号 ==============================
#if DEBUG
                //request.AccountId = 133;
#endif

                TkPoolDTO? account = request.AccountId > 0 ?
                    await TkPoolCore.GetOneAsync(request.AccountId) :
                    await TkPoolCore.GetOneAsync(TkPoolCore.TkAction.parse, isTaobaoUrl, request.RiskStrategy, request.LaunchScene, request.Type);
                if (account == null)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "没有匹配账号";
                    result.subCode = TkSubCodeEnum.Other;
                    result.itemName = "点击打开淘宝APP";

                    _ = TkLogCore.ParseLogAsync(result);
                    return TaobaoParseOutput(result, swData, new
                    {
                        success = ValidateDeeplinkIfRequired(result.success, result.deeplink_url),
                        result.commercial,
                        result.with_middle_page,
                        result.message,
                        result.content,
                        sub_message = result.reason,
                        home_page = "tbopen://m.taobao.com/tbopen/index.html".Equals(result.deeplink_url),
                        result.couponAmount,
                        result.taoToken,
                        result.shortLinkurl,
                        other_aff,
                        result.deeplink_url,
                    });
                }
                result.accountId = account.id;
                result.accountName = account.company;


                alimama = new AlimamaPlus(account);


                int timeout = alimama._config.rt_max;
#if DEBUG
                timeout = 10000;
#endif
                using var cts = new CancellationTokenSource();
                cts.CancelAfter(timeout);

                var requestTask = Task.Run(() => alimama.UnionParseAsync(request, content, result, isTaobaoUrl, cts.Token, swData), cts.Token);
                var delayTask = Task.Delay(timeout, cts.Token);
                var completedTask = await Task.WhenAny(requestTask, delayTask);
                if (completedTask == requestTask)
                {
                    result = await requestTask;
                }
                else
                {
                    //============================== 放弃转链-请求超时 ==============================
                    cts.Cancel();
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "请求超时";
                    result.subCode = TkSubCodeEnum.Other;
                    result.itemName = "点击打开淘宝APP";
                }

                result.accountName = account.company;
                //result = await alimama.UnionParse2Async(content, result);
            }
            catch (Exception ex)
            {
                //============================== 放弃转链-请求超时 ==============================
                if (ex.Message.Contains("was canceled"))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "请求超时";
                    result.subCode = TkSubCodeEnum.Other;
                    result.itemName = "点击打开淘宝APP";
                }
                else
                {
                    //============================== 转链接口异常 ==============================
                    _ = new LoggerLibrary("unionParse", "tb_error")
                        .Info(request.Ip, request.Oaid)
                        .Info(request.Content)
                        .Info(ex.Message, ex.StackTrace)
                        .SaveAsync();

                    NotifyCore.Notify(new NifyMessage
                    {
                        message = $"【转链异常TB】\n{request.Content}\n\n{ex.Message}\n{ex.StackTrace}",
                        priority = NifyMessagePriority.high,
                        tags = ["red_circle"]
                    });
                    result.success = false;
                    result.subCode = TkSubCodeEnum.Other;
                    result.message = "转链接口异常";
                    result.itemName = "点击打开淘宝APP";
                }
            }
            _ = TkLogCore.ParseLogAsync(result, alimama);

            switch (result.reason)
            {
                case "其他推广链接":
                //case "排除淘口令":
                case "纯口令 没链接":
                    other_aff = true;
                    break;
            }

            if ("brwsimilar".Equals(request.RiskStrategy))
            {
                bool clearGoodsFields = !result.success;
                return TaobaoParseOutput(result, swData, new
                {
                    success = ValidateDeeplinkIfRequired(result.success, result.deeplink_url),
                    result.commercial,
                    exposeTracks = TracksCore.BuildBrwSimilarPath(TrackType.Expose, result),
                    clickTracks = TracksCore.BuildBrwSimilarPath(TrackType.Click, result),
                    result.with_middle_page,
                    result.message,
                    sub_message = result.reason,
                    home_page = "tbopen://m.taobao.com/tbopen/index.html".Equals(result.deeplink_url),
                    link_type = result.link_type.ToString(),
                    channel = result?.channel.ToString(),
                    result.channel_type,
                    shopTitle = clearGoodsFields ? string.Empty : result.shopTitle,
                    itemId = clearGoodsFields ? string.Empty : result.itemId,
                    itemName = clearGoodsFields ? string.Empty : result.itemName,
                    pic = clearGoodsFields ? string.Empty : result.pic,
                    price = clearGoodsFields ? string.Empty : (object)result.reservePrice,
                    zkFinalPrice = clearGoodsFields ? string.Empty : (object)result.zkFinalPrice,
                    promotionPrice = clearGoodsFields ? string.Empty : (object)result.promotionPrice,
                    couponAmount = clearGoodsFields ? string.Empty : (object)result.couponAmount,
                    couponEffectiveStartTime = clearGoodsFields ? string.Empty : result.couponEffectiveStartTime,
                    couponEffectiveEndTime = clearGoodsFields ? string.Empty : result.couponEffectiveEndTime,
                    result.shortLinkurl,
                    result.deeplink_url,
                    result.riskStrategy,
                    result.launchScene,
                    result.content,
                    result.taoToken,
                    other_aff,
                    promotionImg = clearGoodsFields ? string.Empty : (object)result.PromotionImg
                });
            }
            return TaobaoParseOutput(result, swData, new
            {
                success = ValidateDeeplinkIfRequired(result.success, result.deeplink_url),
                result.commercial,
                exposeTracks = TracksCore.BuildPath(TrackType.Expose, result),
                clickTracks = TracksCore.BuildPath(TrackType.Click, result),
                result.with_middle_page,
                result.message,
                sub_message = result.reason,
                home_page = "tbopen://m.taobao.com/tbopen/index.html".Equals(result.deeplink_url),
                link_type = result.link_type.ToString(),
                channel = result?.channel.ToString(),
                result.channel_type,
                result.shopTitle,
                result.itemId,
                result.itemName,
                result.pic,
                result.zkFinalPrice,
                price = result.reservePrice,
                result.promotionPrice,
                result.couponAmount,
                result.couponEffectiveStartTime,
                result?.couponEffectiveEndTime,
                result.shortLinkurl,
                result.deeplink_url,
                result.riskStrategy,
                result.launchScene,
                result.content,
                result.taoToken,
                other_aff,
            });

        }


        private static APIResult JdParseOutput(JdDataDTO result, APIResultCodeEnum code = APIResultCodeEnum.OK)
        {
            return new APIResult(new
            {
                success = ValidateDeeplinkIfRequired(result.success, result.deeplink_url),
                //result.success,
                result.message,
                result.commercial,
                exposeTracks = TracksCore.BuildPath(TrackType.Expose, result),
                clickTracks = TracksCore.BuildPath(TrackType.Click, result),
                link_type = result.link_type.ToString(),
                channel = result?.channel.ToString(),
                result.channel_type,
                sub_message = result.reason,
                home_page = "openapp.jdmobile://".Equals(result.deeplink_url),
                result.itemId,
                result.itemName,
                result.shortLinkurl,
                result.deeplink_url,
                result.riskStrategy,
                result.launchScene,
            }, code);
        }

        public static async Task<APIResult> GoodsJdParseAsync(UnionParseRequest request, CancellationToken cancellationToken = default)
        {
            var config = TkConfigCore.Get();
            var result = JdUnionPlus.GetFormattedObject(request);

            result.rawContent = request.Content;
            result.riskStrategy = request.RiskStrategy;
            result.launchScene = request.LaunchScene;
            bool IfExceptional = false;
            bool is_hide = false;
            string content = request.Content;
            try
            {

                string goods_pattern = @"(?:sku=|sku%3D|sku%253D)(\d+)";
                Match match = Regex.Match(content, goods_pattern);
                if (match.Success)
                {
                    string goods_id = match.Groups[1].Value; // 返回匹配的 URL
                    if (string.IsNullOrEmpty(goods_id))
                    {
                        result.success = false;
                        result.deeplink_url = string.Empty;
                        result.message = "放弃转链";
                        result.reason = "无效商品ID";
                        _ = TkLogCore.ParseLogAsync(result, is_hide);
                        return JdParseOutput(result);
                    }
                    content = $"https://item.jd.com/{goods_id}.html";
                    result.shortLinkurl = content;
                }
                else
                {
                    result.success = false;
                    result.deeplink_url = string.Empty;
                    result.message = "放弃转链";
                    result.reason = "无效商品ID";
                    _ = TkLogCore.ParseLogAsync(result, is_hide);
                    return JdParseOutput(result);
                }

                if (!string.IsNullOrEmpty(config.jd_blacklist_regular))
                {
                    var blacklist = config.jd_blacklist_regular.Split('\n')
                        .Where(line => !string.IsNullOrWhiteSpace(line))
                        .ToList();
                    bool anyMatch = false;
                    foreach (string pattern in blacklist)
                    {
                        if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
                    }
                    if (anyMatch)
                    {
                        result.success = false;
                        result.deeplink_url = string.IsNullOrEmpty(result.shortLinkurl) ? string.Empty : JdUnionPlus.GetDeeplink(result.shortLinkurl, request.ClickId);
                        result.message = "放弃转链";
                        result.reason = "规则排除";
                        _ = TkLogCore.ParseLogAsync(result, is_hide);
                        return JdParseOutput(result);
                    }
                }
                string out_url = null;
                string itemId = null;

                //============================== 放弃转链-地区过滤 ==============================
                if (!TestParseCore.InWhitelist(result.ip, result.oaid) && request.AccountId == 0 && JdUnionPlus.ShouldIgnoreRequest(config, request, out string reason))
                {
                    result.link_type = JdUnionPlus.GetLinkType(result.shortLinkurl, out out_url, out itemId);

                    result.deeplink_url = result.link_type switch
                    {
                        LinkTypeEnum.other_aff or
                        LinkTypeEnum.live or
                        LinkTypeEnum.video or
                        LinkTypeEnum.profile or
                        LinkTypeEnum.goods => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
                        _ => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
                    };

                    //if (result.link_type == LinkTypeEnum.other_aff)
                    //{
                    //    //20241204 特例
                    //    if ("bj".Equals(EndPointCore.CurrentEndPoint))
                    //    {
                    //        string ruleKey = $"tmp_rules1:jd:{DateTime.Now:yyyyMMdd}";
                    //        var count = RedisHelper.Get<int>(ruleKey);
                    //        if (DateTime.Now < DateTime.Parse("2024-12-07") && count < 500)
                    //        {
                    //            result.deeplink_url = "openapp.jdmobile://virtual?params=%7B%22des%22%3A%22union%22%2C%22category%22%3A%22jump%22%2C%22url%22%3A%22https%3A%2F%2Fu.jd.com%2FugInesd%3Fe%3DCPS-11417-__ZLDEVICE__-CPS-wkfG72%22%7D&backurl=__back_url__";
                    //            RedisHelper.IncrBy(ruleKey);
                    //            RedisHelper.Expire(ruleKey, 86400 * 1);
                    //        }

                    //    }
                    //}
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = reason;
                    _ = TkLogCore.ParseLogAsync(result, is_hide);
                    return JdParseOutput(result);
                }

                result.link_type = JdUnionPlus.GetLinkType(result.shortLinkurl, out out_url, out itemId);

                bool is_numeric = result.shortLinkurl.Contains(itemId);

                var account = request.AccountId > 0 ?
                    await JdPoolCore.GetOneAsync(request.AccountId, JdPoolCore.JdAction.parse) :
                    await JdPoolCore.GetOneAsync(JdPoolCore.JdAction.parse, is_numeric, request);
                if (account == null)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "没有匹配账号";
                    result.deeplink_url = result.link_type switch
                    {
                        LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
                        _ => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
                    };

                    _ = TkLogCore.ParseLogAsync(result, is_hide);
                    return JdParseOutput(result);
                }
                result.accountId = account.id;
                result.accountName = account.name;
                is_hide = account.is_hide;

                var plus = new JdUnionPlus(account);
                result.proxy_name = plus._proxyName;
                result.proxy_node = plus._proxy?.Address?.Host;

                result = await plus.JdParseAsync(content, request, result, cancellationToken);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("was canceled"))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "请求超时";
                }
                else
                {
                    IfExceptional = true;
                    _ = new LoggerLibrary("unionParse", "jd_error")
                        .Info(request.Ip, request.Oaid)
                        .Info(content)
                        .Info(ex.Message, ex.StackTrace)
                        .SaveAsync();
                    NotifyCore.Notify(new NifyMessage
                    {
                        message = $"【转链异常JD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
                        priority = NifyMessagePriority.high,
                        tags = ["red_circle"]
                    });
                    result.success = false;
                    result.message = "内部错误";
                    result.reason = "转链接口异常";
                }
                result.deeplink_url = result.link_type switch
                {
                    LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
                    _ => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
                };
            }
            if (!result.success)
            {
                result.deeplink_url = string.IsNullOrEmpty(result.shortLinkurl) ? string.Empty : JdUnionPlus.GetDeeplink(result.shortLinkurl, request.ClickId);

            }
            _ = TkLogCore.ParseLogAsync(result, is_hide);
            return JdParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);

        }

        public static async Task<APIResult> JdParseAsync(UnionParseRequest request, CancellationToken cancellationToken = default)
        {
            var config = TkConfigCore.Get();
            var result = JdUnionPlus.GetFormattedObject(request);

            result.rawContent = request.Content;
            result.riskStrategy = request.RiskStrategy;
            result.launchScene = request.LaunchScene;
            bool IfExceptional = false;
            bool is_hide = false;
            string content = request.Content;
            content = content.UrlDecode();
            try
            {
                var overrideContent = await OverrideRuleCore.ProcessAsync(request);
                if (overrideContent != null)
                {
                    result.success = true;
                    result.message = "OK";
                    result.commercial = true;
                    result.deeplink_url = overrideContent.output_text;

                    _ = TkLogCore.ParseLogAsync(result, is_hide);
                    return JdParseOutput(result);
                }

                if (!string.IsNullOrEmpty(config.jd_blacklist_regular))
                {
                    var blacklist = config.jd_blacklist_regular.Split('\n')
                        .Where(line => !string.IsNullOrWhiteSpace(line))
                        .ToList();
                    bool anyMatch = false;
                    foreach (string pattern in blacklist)
                    {
                        if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
                    }
                    if (anyMatch)
                    {
                        result.success = false;
                        result.deeplink_url = string.Empty;
                        result.message = "放弃转链";
                        result.reason = "规则排除";
                        _ = TkLogCore.ParseLogAsync(result, is_hide);
                        return JdParseOutput(result);
                    }
                }
                string out_url = null;
                string itemId = null;

                //============================== 放弃转链-地区过滤 ==============================
                if (!TestParseCore.InWhitelist(result.ip, result.oaid) && request.AccountId == 0 && JdUnionPlus.ShouldIgnoreRequest(config, request, out string reason))
                {
                    result.link_type = JdUnionPlus.GetLinkType(result.shortLinkurl, out out_url, out itemId);

                    result.deeplink_url = result.link_type switch
                    {
                        LinkTypeEnum.other_aff or
                        LinkTypeEnum.live or
                        LinkTypeEnum.video or
                        LinkTypeEnum.profile or
                        LinkTypeEnum.goods => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
                        _ => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
                    };

                    //if (result.link_type == LinkTypeEnum.other_aff)
                    //{
                    //    //20241204 特例
                    //    if ("bj".Equals(EndPointCore.CurrentEndPoint))
                    //    {
                    //        string ruleKey = $"tmp_rules1:jd:{DateTime.Now:yyyyMMdd}";
                    //        var count = RedisHelper.Get<int>(ruleKey);
                    //        if (DateTime.Now < DateTime.Parse("2024-12-07") && count < 500)
                    //        {
                    //            result.deeplink_url = "openapp.jdmobile://virtual?params=%7B%22des%22%3A%22union%22%2C%22category%22%3A%22jump%22%2C%22url%22%3A%22https%3A%2F%2Fu.jd.com%2FugInesd%3Fe%3DCPS-11417-__ZLDEVICE__-CPS-wkfG72%22%7D&backurl=__back_url__";
                    //            RedisHelper.IncrBy(ruleKey);
                    //            RedisHelper.Expire(ruleKey, 86400 * 1);
                    //        }

                    //    }
                    //}
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = reason;
                    _ = TkLogCore.ParseLogAsync(result, is_hide);
                    return JdParseOutput(result);
                }

                //                bool is_ignore2 = JdUnionPlus.FlowControlIgnoreRequest(config, out reason);
                //#if DEBUG
                //                is_ignore2 = false;
                //#endif
                //                if (accountid == 0 && is_ignore2)
                //                {
                //                    result.success = false;
                //                    result.message = "放弃转链";
                //                    result.reason = reason;
                //                    _ = TkLogCore.ParseLogAsync(result);
                //                    return JdParseOutput(result);
                //                }

                result.shortLinkurl = JdUnionPlus.GetLink(content);
                result.content = result.shortLinkurl;
                result.link_type = JdUnionPlus.GetLinkType(result.shortLinkurl, out out_url, out itemId);

                bool is_numeric = result.shortLinkurl.Contains(itemId);

                var account = request.AccountId > 0 ?
                    await JdPoolCore.GetOneAsync(request.AccountId, JdPoolCore.JdAction.parse) :
                    await JdPoolCore.GetOneAsync(JdPoolCore.JdAction.parse, is_numeric, request);
                if (account == null)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "没有匹配账号";
                    result.deeplink_url = result.link_type switch
                    {
                        LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
                        _ => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
                    };

                    _ = TkLogCore.ParseLogAsync(result, is_hide);
                    return JdParseOutput(result);
                }
                result.accountId = account.id;
                result.accountName = account.name;
                is_hide = account.is_hide;

                var plus = new JdUnionPlus(account);
                result.proxy_name = plus._proxyName;
                result.proxy_node = plus._proxy?.Address?.Host;

                result = await plus.JdParseAsync(content, request, result, cancellationToken);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("was canceled"))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "请求超时";
                }
                else
                {
                    IfExceptional = true;
                    _ = new LoggerLibrary("unionParse", "jd_error")
                        .Info(request.Ip, request.Oaid)
                        .Info(content)
                        .Info(ex.Message, ex.StackTrace)
                        .SaveAsync();
                    NotifyCore.Notify(new NifyMessage
                    {
                        message = $"【转链异常JD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
                        priority = NifyMessagePriority.high,
                        tags = ["red_circle"]
                    });
                    result.success = false;
                    result.message = "内部错误";
                    result.reason = "转链接口异常";
                }
                result.deeplink_url = result.link_type switch
                {
                    LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
                    _ => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
                };
            }

            _ = TkLogCore.ParseLogAsync(result, is_hide);
            return JdParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);

        }


        public static async Task<APIResult> DyParseAsync(UnionParseRequest request, CancellationToken cancellationToken = default)
        {
            var result = DyUnionPlus.GetFormattedObject(request.Content, request.Ip, request.Oaid);
            string content = request.Content.UrlDecode();
            result.rawContent = content;
            bool IfExceptional = false;
            try
            {
                var overrideContent = await OverrideRuleCore.ProcessAsync(request);
                if (overrideContent != null)
                {
                    result.success = true;
                    result.message = "OK";
                    result.deeplink_url = overrideContent.output_text;

                    _ = TkLogCore.ParseLogAsync(result);
                    return new APIResult(result);
                }
#if DEBUG
#else
                // 2024-06-19 联盟业务下线
                result.success = false;
                result.message = "放弃转链";
                result.reason = "联盟下线";
                _ = TkLogCore.ParseLogAsync(result);
                return new APIResult(result);
#endif



                if (DyUnionPlus.ShouldIgnoreRequest(request.Ip, request.Oaid, out string reason))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = reason;
                    _ = TkLogCore.ParseLogAsync(result);
                    return new APIResult(result);
                }

                var account = PangolinPoolCore.GetOne();
                if (account == null)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "没有匹配账号";
                    _ = TkLogCore.ParseLogAsync(result);
                    return new APIResult(result);
                }
                result = await DyUnionPlus.DyParseAsync(account, content, request.CommerceType, result, cancellationToken);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("was canceled"))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "请求超时";
                }
                else
                {
                    IfExceptional = true;
                    _ = new LoggerLibrary("unionParse", "dy_error")
                        .Info(request.Ip, request.Oaid)
                        .Info(content)
                        .Info(ex.Message, ex.StackTrace)
                        .SaveAsync();
                    NotifyCore.Notify(new NifyMessage
                    {
                        message = $"【转链异常DY】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
                        priority = NifyMessagePriority.high,
                        tags = ["red_circle"]
                    });
                    result.success = false;
                    result.message = "内部错误";
                    result.reason = "转链接口异常";
                }
            }
            _ = TkLogCore.ParseLogAsync(result);
            return new APIResult(new
            {
                result.success,
                result.message,
                link_type = result.link_type.ToString(),
                channel = result?.channel.ToString(),
                content = result?.rawContent.ToString(),
                taoToken = result?.taoToken.ToString(),
                result.channel_type,
                result.itemName,
                result.shortLinkurl,
                result.deeplink_url,
            }, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
        }

        public static async Task<APIResult> PddParseAsync(UnionParseRequest request, CancellationToken cancellationToken = default)
        {
            var result = PddUnionPlus.GetFormattedObject(request);

            var overrideContent = await OverrideRuleCore.ProcessAsync(request);
            if (overrideContent != null)
            {
                result.success = true;
                result.message = "OK";
                result.commercial = true;
                result.deeplink_url = overrideContent.output_text;

                _ = TkLogCore.ParseLogAsync(result);
                return PddParseOutput(result);
            }

            string content = request.Content;
            result.rawContent = content;
            if (string.IsNullOrEmpty(result.shortLinkurl))
            {
                result.success = false;
                result.deeplink_url = PddUnionPlus.GetDeeplink(string.Empty);
                result.message = "放弃转链";
                result.reason = "纯口令";
                _ = TkLogCore.ParseLogAsync(result);
                return PddParseOutput(result);
            }

            bool IfExceptional = false;
            try
            {
                var config = TkConfigCore.Get();

                if (!string.IsNullOrEmpty(config.pdd_blacklist_regular))
                {
                    var blacklist = config.pdd_blacklist_regular.Split('\n')
                    .Where(line => !string.IsNullOrWhiteSpace(line))
                    .ToList();
                    bool anyMatch = false;
                    foreach (string pattern in blacklist)
                    {
                        if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
                    }
                    if (anyMatch)
                    {
                        result.success = false;
                        result.deeplink_url = PddUnionPlus.GetDeeplink(result.shortLinkurl);
                        result.message = "放弃转链";
                        result.reason = "规则排除";
                        _ = TkLogCore.ParseLogAsync(result);
                        return PddParseOutput(result);
                    }
                }
                //============================== 放弃转链-地区过滤 ==============================
                if (request.AccountId == 0 && PddUnionPlus.ShouldIgnoreRequest(config, request, out string reason))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = reason;
                    result.deeplink_url = PddUnionPlus.GetDeeplink(result.shortLinkurl);
                    _ = TkLogCore.ParseLogAsync(result);
                    return PddParseOutput(result);
                }

                if (!TestParseCore.InWhitelist(result.ip, result.oaid) && PddUnionPlus.FlowControlIgnoreRequest(config, request, out reason))
                {
                    result.success = false;
                    result.link_type = LinkTypeEnum.unknown;
                    result.channel_type = ChannelTypeEnum.pdd;
                    result.message = "放弃转链";
                    result.reason = reason;
                    result.accountId = 0;
                    result.accountName = string.Empty;
                    result.content = content;
                    result.deeplink_url = PddUnionPlus.GetDeeplink(result.shortLinkurl);
                    _ = TkLogCore.ParseLogAsync(result);
                    return PddParseOutput(result);
                }

                var precheck = await PddUnionPlus.PrecheckGoodsIdAsync(result.shortLinkurl, cancellationToken);
                switch (precheck)
                {
                    case RrecheckGoodsIdResult.InvalidLink:
                        result.message = "放弃转链";
                        result.reason = "无效链接";
                        break;
                    case RrecheckGoodsIdResult.Empty:
                        result.message = "放弃转链";
                        result.reason = $"无效的商品precheck";
                        break;

                    case RrecheckGoodsIdResult.Exception:
                        result.message = "转链失败";
                        result.reason = $"商品预检异常";
                        break;
                }

                if (precheck != RrecheckGoodsIdResult.Success)
                {
                    result.success = false;
                    result.link_type = LinkTypeEnum.unknown;
                    result.channel_type = ChannelTypeEnum.pdd;
                    result.accountId = 0;
                    result.accountName = string.Empty;
                    result.content = content;
                    result.deeplink_url = PddUnionPlus.GetDeeplink(result.shortLinkurl);
                    _ = TkLogCore.ParseLogAsync(result);
                    return PddParseOutput(result);
                }




                PddPoolDTO account = null;
                // 直接调用GetOne获取账号
                // 新的调度策略已经在内部处理了：
                // 1. 基于时间间隔的账号选择
                // 2. 并发安全的账号预留（Redis SETNX）
                // 3. 依次尝试多个候选账号
                // 因此不需要外层重试逻辑
                account = PddPoolCore.GetOne(PddUnionWorkMode.All, request);

                if (account == null)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "没有匹配账号";
                    result.deeplink_url = PddUnionPlus.GetDeeplink(result.shortLinkurl);
                    _ = TkLogCore.ParseLogAsync(result);
                    return PddParseOutput(result);
                }

                result.accountId = account.id;
                result.accountName = account.name;
                result.proxy_node = account.nodeName;

                // 更新当前日使用统计
                PddPoolCore.UpdateAccountUsage(account.id);

                var plus = new PddUnionPlus(account);
                result = await plus.PddParseAsync(content, request.CommerceType, result, cancellationToken);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("was canceled"))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "请求超时";
                }
                else
                {
                    IfExceptional = true;
                    _ = new LoggerLibrary("unionParse", "pdd_error")
                        .Info(request.Ip, request.Oaid)
                        .Info(content)
                        .Info(ex.Message, ex.StackTrace)
                        .SaveAsync();
                    NotifyCore.Notify(new NifyMessage
                    {
                        message = $"【转链异常PDD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
                        priority = NifyMessagePriority.high,
                        tags = ["red_circle"]
                    });
                    result.success = false;
                    result.message = "内部错误";
                    result.reason = "转链接口异常";
                }
            }
            _ = TkLogCore.ParseLogAsync(result);
            return PddParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);

        }
        public static async Task<APIResult> GoodsPddParseAsync(UnionParseRequest request, CancellationToken cancellationToken = default)
        {
            var result = PddUnionPlus.GetFormattedObject(request);

            string content = request.Content;
            content = content.UrlDecode();
            result.rawContent = content;
            string goods_pattern = @"(?:goods_id=|goods_id%3D|goods_id%253D)(\d+)";
            Match match = Regex.Match(content, goods_pattern);

            if (match.Success)
            {
                string goods_id = match.Groups[1].Value; // 返回匹配的 URL
                if (string.IsNullOrEmpty(content))
                {
                    result.success = false;
                    result.deeplink_url = string.Empty;
                    result.message = "放弃转链";
                    result.reason = "无效商品ID";
                    _ = TkLogCore.ParseLogAsync(result);
                    return PddParseOutput(result);
                }
                content = $"https://mobile.yangkeduo.com/goods.html?goods_id={goods_id}";
                result.shortLinkurl = content;
            }
            else
            {
                result.success = false;
                result.deeplink_url = string.Empty;
                result.message = "放弃转链";
                result.reason = "无效商品ID";
                _ = TkLogCore.ParseLogAsync(result);
                return PddParseOutput(result);
            }

            if (string.IsNullOrEmpty(result.shortLinkurl))
            {
                result.success = false;
                result.deeplink_url = string.IsNullOrEmpty(result.shortLinkurl) ? string.Empty : PddUnionPlus.GetDeeplink(result.shortLinkurl);
                result.message = "放弃转链";
                result.reason = "纯口令";
                _ = TkLogCore.ParseLogAsync(result);
                return PddParseOutput(result);
            }

            bool IfExceptional = false;
            try
            {
                var config = TkConfigCore.Get();

                if (!string.IsNullOrEmpty(config.pdd_blacklist_regular))
                {
                    var blacklist = config.pdd_blacklist_regular.Split('\n')
                    .Where(line => !string.IsNullOrWhiteSpace(line))
                    .ToList();
                    bool anyMatch = false;
                    foreach (string pattern in blacklist)
                    {
                        if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
                    }
                    if (anyMatch)
                    {
                        result.success = false;
                        result.deeplink_url = string.IsNullOrEmpty(result.shortLinkurl) ? string.Empty : PddUnionPlus.GetDeeplink(result.shortLinkurl);
                        result.message = "放弃转链";
                        result.reason = "规则排除";
                        _ = TkLogCore.ParseLogAsync(result);
                        return PddParseOutput(result);
                    }
                }
                //============================== 放弃转链-地区过滤 ==============================
                if (request.AccountId == 0 && PddUnionPlus.ShouldIgnoreRequest(config, request, out string reason))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = reason;
                    result.deeplink_url = string.IsNullOrEmpty(result.shortLinkurl) ? string.Empty : PddUnionPlus.GetDeeplink(result.shortLinkurl);
                    _ = TkLogCore.ParseLogAsync(result);
                    return PddParseOutput(result);
                }
                if (!TestParseCore.InWhitelist(result.ip, result.oaid) && PddUnionPlus.FlowControlIgnoreRequest(config, request, out reason))
                {
                    result.success = false;
                    result.link_type = LinkTypeEnum.unknown;
                    result.channel_type = ChannelTypeEnum.pdd;
                    result.message = "放弃转链";
                    result.reason = reason;
                    result.accountId = 0;
                    result.accountName = string.Empty;
                    result.content = content;
                    result.deeplink_url = PddUnionPlus.GetDeeplink(result.shortLinkurl);
                    _ = TkLogCore.ParseLogAsync(result);
                    return PddParseOutput(result);
                }

                var precheck = await PddUnionPlus.PrecheckGoodsIdAsync(result.shortLinkurl, cancellationToken);
                switch (precheck)
                {
                    case RrecheckGoodsIdResult.InvalidLink:
                        result.message = "放弃转链";
                        result.reason = "无效链接";
                        break;
                    case RrecheckGoodsIdResult.Empty:
                        result.message = "放弃转链";
                        result.reason = $"无效的商品precheck";
                        break;

                    case RrecheckGoodsIdResult.Exception:
                        result.message = "转链失败";
                        result.reason = $"商品预检异常";
                        break;
                }

                if (precheck != RrecheckGoodsIdResult.Success)
                {
                    result.success = false;
                    result.link_type = LinkTypeEnum.unknown;
                    result.channel_type = ChannelTypeEnum.pdd;
                    result.accountId = 0;
                    result.accountName = string.Empty;
                    result.content = content;
                    result.deeplink_url = PddUnionPlus.GetDeeplink(result.shortLinkurl);
                    _ = TkLogCore.ParseLogAsync(result);
                    return PddParseOutput(result);
                }



                PddPoolDTO account = null;
                // 直接调用GetOne获取账号
                // 新的调度策略已经在内部处理了：
                // 1. 基于时间间隔的账号选择
                // 2. 并发安全的账号预留（Redis SETNX）
                // 3. 依次尝试多个候选账号
                // 因此不需要外层重试逻辑
                account = PddPoolCore.GetOne(PddUnionWorkMode.All, request);
                if (account == null)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "没有匹配账号";
                    result.deeplink_url = string.IsNullOrEmpty(result.shortLinkurl) ? string.Empty : PddUnionPlus.GetDeeplink(result.shortLinkurl);
                    _ = TkLogCore.ParseLogAsync(result);
                    return PddParseOutput(result);
                }

                result.accountId = account.id;
                result.accountName = account.name;
                result.proxy_node = account.nodeName;

                // 更新当前日使用统计
                PddPoolCore.UpdateAccountUsage(account.id);

                var plus = new PddUnionPlus(account);
                result = await plus.PddParseAsync(content, request.CommerceType, result, cancellationToken);
                if (!result.success)
                {
                    result.deeplink_url = string.IsNullOrEmpty(result.shortLinkurl) ? string.Empty : PddUnionPlus.GetDeeplink(result.shortLinkurl);
                }
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("was canceled"))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "请求超时";
                }
                else
                {
                    IfExceptional = true;
                    _ = new LoggerLibrary("unionParse", "pdd_error")
                        .Info(request.Ip, request.Oaid)
                        .Info(content)
                        .Info(ex.Message, ex.StackTrace)
                        .SaveAsync();
                    NotifyCore.Notify(new NifyMessage
                    {
                        message = $"【转链异常PDD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
                        priority = NifyMessagePriority.high,
                        tags = ["red_circle"]
                    });
                    result.success = false;
                    result.message = "内部错误";
                    result.reason = "转链接口异常";
                }
            }
            _ = TkLogCore.ParseLogAsync(result);
            return PddParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);

        }
        private static APIResult PddParseOutput(PddDataDTO result, APIResultCodeEnum code = APIResultCodeEnum.OK)
        {
            string itemName = result.itemName;
            switch (result.riskStrategy)
            {
                case "tbpush":
                case "icon":
                    itemName = string.Empty;
                    break;
            }

            return new APIResult(new
            {
                //result.success,
                success = ValidateDeeplinkIfRequired(result.success, result.deeplink_url),
                result.message,
                result.commercial,
                exposeTracks = TracksCore.BuildPath(TrackType.Expose, result),
                clickTracks = TracksCore.BuildPath(TrackType.Click, result),
                sub_message = result.reason,
                home_page = "pinduoduo://com.xunmeng.pinduoduo/".Equals(result.deeplink_url),
                link_type = result.link_type.ToString(),
                channel = result?.channel.ToString(),
                result.itemId,
                itemName,
                result.shortLinkurl,
                result.deeplink_url,
            }, code);
        }



        public static async Task<APIResult> KsParseAsync(UnionParseRequest request, CancellationToken cancellationToken = default)
        {
            var result = KsUnionPlus.GetFormattedObject(request.Content, request.Ip, request.Oaid);
            string content = request.Content.UrlDecode();
            result.rawContent = content;
            bool IfExceptional = false;
            try
            {
                var config = TkConfigCore.Get();


                var overrideContent = await OverrideRuleCore.ProcessAsync(request);
                if (overrideContent != null)
                {
                    result.success = true;
                    result.message = "OK";
                    result.deeplink_url = overrideContent.output_text;

                    _ = TkLogCore.ParseLogAsync(result);
                    return KsParseOutput(result);
                }


                if (!string.IsNullOrEmpty(config.ks_blacklist_regular))
                {
                    var blacklist = config.ks_blacklist_regular.Split('\n')
                    .Where(line => !string.IsNullOrWhiteSpace(line))
                    .ToList();
                    bool anyMatch = false;
                    foreach (string pattern in blacklist)
                    {
                        if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
                    }
                    if (anyMatch)
                    {
                        result.success = false;
                        result.deeplink_url = string.Empty;
                        result.message = "放弃转链";
                        result.reason = "规则排除";
                        _ = TkLogCore.ParseLogAsync(result);
                        return KsParseOutput(result);
                    }
                }



                //============================== 放弃转链-地区过滤 ==============================
                if (request.AccountId == 0 && KsUnionPlus.ShouldIgnoreRequest(config, request.Ip, request.Oaid, out string reason))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = reason;
                    result.deeplink_url = KsUnionPlus.GetDeeplink(string.Empty, LinkTypeEnum.baseDomain);
                    _ = TkLogCore.ParseLogAsync(result);
                    return KsParseOutput(result);
                }
                var account = request.AccountId > 0 ? KsPoolCore.GetOne(request.AccountId, KsPoolCore.KsAction.parse) : KsPoolCore.GetOne(KsPoolCore.KsAction.parse);
                if (account == null)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "没有匹配账号";
                    result.deeplink_url = KsUnionPlus.GetDeeplink(string.Empty, LinkTypeEnum.baseDomain);
                    _ = TkLogCore.ParseLogAsync(result);
                    return KsParseOutput(result);
                }
                result.accountId = account.id;
                result.accountName = account.name;

                var plus = new KsUnionPlus(account);

                result = await plus.KsParseAsync(content, request.CommerceType, result, cancellationToken);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("was canceled"))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "请求超时";
                }
                else
                {
                    IfExceptional = true;
                    _ = new LoggerLibrary("unionParse", "jd_error")
                        .Info(request.Ip, request.Oaid)
                        .Info(content)
                        .Info(ex.Message, ex.StackTrace)
                        .SaveAsync();
                    NotifyCore.Notify(new NifyMessage
                    {
                        message = $"【转链异常JD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
                        priority = NifyMessagePriority.high,
                        tags = ["red_circle"]
                    });
                    result.success = false;
                    result.message = "内部错误";
                    result.reason = "转链接口异常";
                }
                result.deeplink_url = KsUnionPlus.GetDeeplink(string.Empty, LinkTypeEnum.baseDomain);

            }
            _ = TkLogCore.ParseLogAsync(result);
            return KsParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);

        }
        private static APIResult KsParseOutput(KsDataDTO result, APIResultCodeEnum code = APIResultCodeEnum.OK)
        {
            return new APIResult(new
            {
                result.success,
                result.message,
                link_type = result.link_type.ToString(),
                channel = result?.channel.ToString(),
                result.itemId,
                result.itemName,
                result.shortLinkurl,
                result.deeplink_url,
            }, code);
        }


        public static async Task<APIResult> SpecialTextParseAsync(UnionParseRequest request, CancellationToken cancellationToken = default)
        {

            var result = new TkDataDTO()
            {
                message = string.Empty,
                subCode = TkSubCodeEnum.Other,
                channel = TkChannelEnum.tb,
                accountName = string.Empty,
                success = false,
                content = request.QueryText,
                link_type = LinkTypeEnum.unknown,
                ip = request.Ip,
                oaid = request.Oaid,
                couponAmount = 0,
                taoToken = string.Empty,
                elapsedTime = 0,
                shortLinkurl = string.Empty,
                deeplink_url = string.Empty,
                create_time = DateTime.Now
            };
            bool IfExceptional = false;
            try
            {
                var overrideContent = await OverrideRuleCore.ProcessAsync(request);
                if (overrideContent != null)
                {
                    result.success = true;
                    result.message = "OK";
                    result.deeplink_url = overrideContent.output_text;
                    return new APIResult(new { result.success, result.message, result.reason, result.deeplink_url });
                }
                else
                {
                    result.success = false;
                    result.message = "无效的 QueryText";
                    return new APIResult(new { result.success, result.message, result.reason, deeplink_url = "" });
                }
            }
            catch (Exception ex)
            {
                result.success = false;
                result.message = "内部错误";
                result.reason = "转链接口异常";
                return new APIResult(new { result.success, result.message, result.reason, deeplink_url = "" }, APIResultCodeEnum.NotAcceptable);
            }
        }

    }

}
