using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using dodohold.core;
using Spire.Pdf.Exporting.XPS.Schema;
using System.Xml.Linq;
using System.Net;
using TencentCloud.Mrs.V20200910.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authentication;
using Spire.Pdf.Graphics;
using Google.Protobuf.WellKnownTypes;
using TencentCloud.Tcm.V20210413.Models;
using System.Diagnostics;
using System.Threading;
using TencentCloud.Soe.V20180724.Models;
using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
using System.Runtime.Intrinsics.Arm;
using ZstdSharp.Unsafe;
using System.Text.RegularExpressions;
using static dodohold.core.ZTOExpress.CreateOrderArgs;
using System.Security.Cryptography;
using System.Threading.Channels;


namespace molilian.core
{
    public partial class UnionParseCore
    {
        public static async Task<ActionResult> UnionParseAsync(string content, string channel, string ip, string oaid, int accountid = 0)
        {
            content = content.Trim();
            return channel switch
            {
                "wemeet" => await WemeetParseAsync(content, ip, oaid),
                "bdpan" => PanParse(content, ip, oaid),
                "jd" => await JdParseAsync(content, ip, oaid, accountid),
                "ks" => await KsParseAsync(content, ip, oaid, accountid),
                "dy" => await DyParseAsync(content, ip, oaid),
                "pdd" => await PddParseAsync(content, ip, oaid, accountid),
                "tb" => await TaobaoParseAsync(content, ip, oaid, accountid),
                _ => await DeeplinkParseCore.ParseAsync(content, channel, ip, oaid),
            };
        }

        //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 APIResult PanParse(string content, string ip, string oaid)
        {
            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 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);
        }

        public static async Task<APIResult> TaobaoParseAsync(string content,
            string ip = "", string oaid = "",
            int accountid = 0)
        {
            AlimamaPlus alimama = null;
            //content = content.UrlDecode();
            content = content[..Math.Min(1000, content.Length)];
            var result = AlimamaPlus.GetFormattedObject(content, ip, oaid);

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

            result.rawContent = content;
            try
            {
                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);


                //============================== 放弃转链-初步筛选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 = "";
                    _ = TkLogCore.ParseLogAsync(result);

                    return TaobaoParseOutput(result, swData, new
                    {
                        result.success,
                        result.message,
                        result.content,
                        result.itemName,
                        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 = "";
                    _ = TkLogCore.ParseLogAsync(result);

                    return TaobaoParseOutput(result, swData, new
                    {
                        result.success,
                        result.message,
                        result.content,
                        result.itemName,
                        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) || is_aff_link)
                {
                    //没有短链接都放弃
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "初步筛选2";
                    result.subCode = TkSubCodeEnum.Prelim2;
                    result.itemName = "点击打开淘宝APP";
                    _ = TkLogCore.ParseLogAsync(result);

                    return TaobaoParseOutput(result, swData, new
                    {
                        result.success,
                        result.message,
                        result.content,
                        result.itemName,
                        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
                    {
                        result.success,
                        result.message,
                        result.content,
                        result.itemName,
                        result.deeplink_url,
                    });

                }
                //============================== 放弃转链-地区过滤 ==============================
                bool is_ignore2 = AlimamaPlus.ShouldIgnoreRequest(ip, oaid, 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
                    {
                        result.success,
                        result.message,
                        result.content,
                        result.itemName,
                        result.deeplink_url,
                    });
                }

                //============================== 放弃转链-没有匹配账号 ==============================
                TkPoolDTO? account = accountid > 0 ?
                    TkPoolCore.GetOne(accountid) :
                    TkPoolCore.GetOne(TkPoolCore.TkAction.parse);
                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
                    {
                        result.success,
                        result.message,
                        result.content,
                        result.couponAmount,
                        result.taoToken,
                        result.shortLinkurl,
                        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.UnionParse2Async(content, result, 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(ip, oaid)
                        .Info(content)
                        .Info(ex.Message, ex.StackTrace)
                        .SaveAsync();

                    NotifyCore.Notify(new NifyMessage
                    {
                        message = $"【转链异常TB】\n{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);

            return TaobaoParseOutput(result, swData, new
            {
                result.success,
                result.message,
                link_type = result.link_type.ToString(),
                channel = result?.channel.ToString(),
                result.channel_type,
                result.itemId,
                result.itemName,
                result.pic,
                result.promotionPrice,
                result.couponAmount,
                result.couponEffectiveStartTime,
                result?.couponEffectiveEndTime,
                result.shortLinkurl,
                result.deeplink_url,
                result.content,
                result.taoToken,
            });
        }

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

        public static async Task<APIResult> JdParseAsync(string content, string ip, string oaid,
            int accountid = 0, CancellationToken cancellationToken = default)
        {
            var result = JdUnionPlus.GetFormattedObject(content, ip, oaid);
            content = content.UrlDecode();
            result.rawContent = content;
            bool IfExceptional = false;
            try
            {
                var config = TkConfigCore.Get();

                //============================== 放弃转链-地区过滤 ==============================
                if (accountid == 0 && JdUnionPlus.ShouldIgnoreRequest(config, ip, oaid, out string reason))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = reason;
                    _ = TkLogCore.ParseLogAsync(result);
                    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);
                //                }

                var account = accountid > 0 ? JdPoolCore.GetOne(accountid, JdPoolCore.JdAction.parse) : JdPoolCore.GetOne(JdPoolCore.JdAction.parse);
                if (account == null)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "没有匹配账号";
                    _ = TkLogCore.ParseLogAsync(result);
                    return JdParseOutput(result);
                }
                result.accountId = account.id;
                result.accountName = account.name;

                var plus = new JdUnionPlus(account);

                result = await plus.JdParseAsync(content, 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(ip, 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 = "转链接口异常";
                }
            }
            _ = TkLogCore.ParseLogAsync(result);
            return JdParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);

        }

        public static async Task<APIResult> DyParseAsync(string content, string ip, string oaid, CancellationToken cancellationToken = default)
        {
            var result = DyUnionPlus.GetFormattedObject(content, ip, oaid);
            content = content.UrlDecode();
            result.rawContent = content;
            bool IfExceptional = false;
            try
            {
#if DEBUG
#else
                // 2024-06-19 联盟业务下线
                result.success = false;
                result.message = "放弃转链";
                result.reason = "联盟下线";
                _ = TkLogCore.ParseLogAsync(result);
                return new APIResult(result);
#endif


                if (DyUnionPlus.ShouldIgnoreRequest(ip, 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, 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(ip, 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(string content, string ip, string oaid,
            int accountid = 0, CancellationToken cancellationToken = default)
        {
            var result = PddUnionPlus.GetFormattedObject(content, ip, oaid);
            content = content.UrlDecode();
            result.rawContent = content;
            bool IfExceptional = false;
            try
            {
                var config = TkConfigCore.Get();

                //============================== 放弃转链-地区过滤 ==============================
                if (accountid == 0 && PddUnionPlus.ShouldIgnoreRequest(config, ip, oaid, out string reason))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = reason;
                    _ = TkLogCore.ParseLogAsync(result);
                    return PddParseOutput(result);
                }
                var account = PddPoolCore.GetOne(PddUnionWorkMode.All, accountid);
                if (account == null)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "没有匹配账号";
                    _ = TkLogCore.ParseLogAsync(result);
                    return PddParseOutput(result);
                }
                result.accountId = account.id;
                result.accountName = account.name;

                var plus = new PddUnionPlus(account);

                result = await plus.PddParseAsync(content, 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(ip, 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)
        {
            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> KsParseAsync(string content, string ip, string oaid,
            int accountid = 0, CancellationToken cancellationToken = default)
        {
            var result = KsUnionPlus.GetFormattedObject(content, ip, oaid);
            content = content.UrlDecode();
            result.rawContent = content;
            bool IfExceptional = false;
            try
            {
                var config = TkConfigCore.Get();

                //============================== 放弃转链-地区过滤 ==============================
                if (accountid == 0 && KsUnionPlus.ShouldIgnoreRequest(config, ip, oaid, out string reason))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = reason;
                    _ = TkLogCore.ParseLogAsync(result);
                    return KsParseOutput(result);
                }

                var account = accountid > 0 ? KsPoolCore.GetOne(accountid, KsPoolCore.KsAction.parse) : KsPoolCore.GetOne(KsPoolCore.KsAction.parse);
                if (account == null)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "没有匹配账号";
                    _ = TkLogCore.ParseLogAsync(result);
                    return KsParseOutput(result);
                }
                result.accountId = account.id;
                result.accountName = account.name;

                var plus = new KsUnionPlus(account);

                result = await plus.KsParseAsync(content, 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(ip, 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 = "转链接口异常";
                }
            }
            _ = 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);
        }
    }

}
