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 Dataoke;
using System.Text.RegularExpressions;
using Org.BouncyCastle.Ocsp;
using System.Diagnostics;
using TencentCloud.Fmu.V20191213.Models;
using Microsoft.VisualBasic;
using System.Text.Json;
using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Security.Cryptography;
using Google.Protobuf.WellKnownTypes;
using Microsoft.Extensions.FileSystemGlobbing.Internal;
using System.Web;


namespace molilian.core
{
    public partial class JdUnionPlus
    {
        private const string VIDEO_URL_PREFIX = "https://h5.m.jd.com/active/faxian/video/index.html";


        public static string GetLink(string content)
        {
            if (string.IsNullOrEmpty(content)) return content;
            string result = content;
            //string pattern = @"https?:\/\/?([\da-z\.-]+)\.([a-z]{2,6})(:\d{1,5})?([\/\w\.-]*)*\/?(#[\S]+)?(\?[\S]+)?";

            //openjd://virtual?params={%22category%22:%22jump%22,%20%22des%22:%22m%22,%20%22url%22:%22https://item.m.jd.com/product/10197819484796.html%22}
            //openapp.jdmobile://virtual?params={%22category%22:%22jump%22,%20%22des%22:%22m%22,%20%22url%22:%22https://item.m.jd.com/product/10197819484796.html%22}

            // 处理 openjd:// 和 openapp.jdmobile:// 格式的 deeplink
            if (content.StartsWith("openjd://virtual?params=") || content.StartsWith("openapp.jdmobile://virtual?params="))
            {
                try
                {
                    string paramsStr = content.GetContentPart("params={", "}");
                    if (!string.IsNullOrEmpty(paramsStr))
                    {
                        paramsStr = $"{{{paramsStr}}}";
                        string decodedParams = HttpUtility.UrlDecode(paramsStr);

                        // 使用正则提取 "url" 字段的值
                        var urlMatch = Regex.Match(decodedParams, @"""url""\s*:\s*""([^""]+)""");
                        if (urlMatch.Success)
                        {
                            return urlMatch.Groups[1].Value;
                        }
                    }
                }
                catch
                {
                    // 如果解析失败,继续使用默认逻辑
                }
            }

            Regex regex = new(AlimamaPlus._url_pattern);
            MatchCollection matches = regex.Matches(content);

            foreach (Match m in matches.Cast<Match>())
            {
                string url = m.Value;
                return url;
            }
            return string.Empty;
        }

        public static string GetItemId(string url)
        {
            if (string.IsNullOrEmpty(url)) return string.Empty;

            string[] patterns = [
                @"https?://(?:i-)?item(?:\.m)?\.jd\.com/(?:product/)?(\d+)\.html(?:\?.*)?"
                //@"https?:\/\/b2b\.m\.jd\.com\/goods-detail\/.*[?&]skuId=(\d+)"
            ];

            foreach (var pattern in patterns)
            {
                Match match = Regex.Match(url, pattern);
                if (match.Success)
                {
                    string idNumber = match.Groups[1].Value;  // 捕获组1包含数字ID
                    return idNumber;
                }
            }
            return string.Empty;
        }

        public static string GetDeeplink(string url, string clickId)
        {
            var config = TkConfigCore.Get();
            if (string.IsNullOrEmpty(config.dp_style)) return GetDefaultStyleDeeplink(url);

            Random rand = new();
            int randomValue = rand.Next(0, 101);
            if (randomValue > config.dp_style_percentage) return GetDefaultStyleDeeplink(url);

            if (string.IsNullOrEmpty(clickId)) clickId = config.dp_style_default_str;

            var ts = DateTime.Now.Convert2UnixTimestamp(true);
            string virtual_params;

            if (!string.IsNullOrEmpty(url) && url.StartsWith(VIDEO_URL_PREFIX))
            {
                // 处理视频URL的情况
                var queryString = url.Substring(VIDEO_URL_PREFIX.Length + 1); // +1 for the '?' character
                var queryParams = HttpUtility.ParseQueryString(queryString);
                var paramsDict = queryParams.AllKeys.ToDictionary(k => k, k => queryParams[k]);
                paramsDict["category"] = "jump";
                paramsDict["m_param"] = $"{{\"jdv\":\"0|oppo_seedling|-|widget|{clickId}|{ts}\"}}";
                virtual_params = JsonSerializer.Serialize(paramsDict);
            }
            else if (string.IsNullOrEmpty(url))
            {
                virtual_params = $"{{\"category\":\"jump\",\"des\":\"HomePage\",\"m_param\":{{\"jdv\":\"0|oppo_seedling|-|widget|{clickId}|{ts}\"}}";
            }
            else
            {
                virtual_params = $"{{\"category\":\"jump\",\"des\":\"m\",\"url\":\"{url}\",\"m_param\":{{\"jdv\":\"0|oppo_seedling|-|widget|{clickId}|{ts}\"}}}}";
            }

            string result = $"openapp.jdmobile://virtual?params={virtual_params.UrlEncode()}";
            return result;
        }
        public static string GetDefaultStyleDeeplink(string url)
        {
            if (string.IsNullOrEmpty(url)) return "openapp.jdmobile://";

            string virtual_params;

            if (url.StartsWith(VIDEO_URL_PREFIX))
            {
                // 处理视频URL的情况
                var queryString = url.Substring(VIDEO_URL_PREFIX.Length + 1);
                var queryParams = HttpUtility.ParseQueryString(queryString);
                var paramsDict = queryParams.AllKeys.ToDictionary(k => k, k => queryParams[k]);
                paramsDict["category"] = "jump";
                virtual_params = JsonSerializer.Serialize(paramsDict);
            }
            else
            {
                virtual_params = $"{{\"category\":\"jump\",\"des\":\"m\",\"sourceValue\":\"babel-act\",\"sourceType\":\"babel\",\"url\":\"{url}\",\"M_sourceFrom\":\"h5auto\",\"msf_type\":\"auto\"}}";
            }
            string result = $"openapp.jdmobile://virtual?params={virtual_params.UrlEncode()}";
            return result;
        }


        //public static string GetDefaultStyleDeeplink(string url)
        //{
        //    if (string.IsNullOrEmpty(url)) return "openapp.jdmobile://";
        //    string virtual_params = $"{{\"category\":\"jump\",\"des\":\"m\",\"sourceValue\":\"babel-act\",\"sourceType\":\"babel\",\"url\":\"{url}\",\"M_sourceFrom\":\"h5auto\",\"msf_type\":\"auto\"}}";
        //    string result = $"openapp.jdmobile://virtual?params={virtual_params.UrlEncode()}";
        //    return result;
        //}

        public static JdDataDTO GetFormattedObject(UnionParseRequest request)
        {
            string shortLinkurl = GetLink(request.Content);
            string deeplink_url = GetDefaultStyleDeeplink(shortLinkurl);

            return new JdDataDTO()
            {
                message = string.Empty,
                link_type = LinkTypeEnum.unknown,
                channel = TkChannelEnum.jd,
                accountName = string.Empty,
                success = false,
                content = request.Content,
                ip = request.Ip,
                oaid = request.Oaid,
                elapsedTime = 0,
                itemName = "点击打开京东APP",
                shortLinkurl = shortLinkurl,
                deeplink_url = deeplink_url,
                create_time = DateTime.Now,
                end_point = _end_point,
                parse_type = request.Type,
                riskStrategy = request.RiskStrategy,
                launchScene = request.LaunchScene,
            };
        }

        public static bool IsAffLlink(string url)
        {
            Uri uri = new(url);
            if (uri.Host.Equals("`u.jd.com", StringComparison.OrdinalIgnoreCase))
            {
                return true;
            }
            return false;
        }
        public static string? GetDesiredUrl(string url)
        {
            try
            {
                WebClientUtility client = new()
                {
                    AllowAutoRedirect = false,
                    Referer = "http://www.jd.com",
                    Proxy = ProxyNodesCore.RandomOne()
                };
#if DEBUG
                client.Proxy = null;
#endif
                var response = client.Request(url);
                if (!response.Successed) return null;

                var target_url = response.ResponseMessage?.Headers?.Location?.ToString();

                if (!url.StartsWith("https://3.cn")) return null;
                return target_url;
            }
            catch (Exception ex)
            {
            }
            return null;
        }

        public static LinkTypeEnum GetLinkType(string url, out string desiredUrl, out string itemId)
        {
            desiredUrl = url;
            itemId = string.Empty;

            if (string.IsNullOrEmpty(url)) return LinkTypeEnum.unknown;
            string lowerUrl = url.ToLower();
            Uri uri = new(url);

            if ("3.cn".Equals(uri.Host))
            {
                var target_url = GetDesiredUrl(url);
                return GetLinkType(target_url, out desiredUrl, out itemId);
            }

            string[] arr = ["mall.jd.com", "shop.m.jd.com", "shop.jd.com"];
            if (arr.Contains(uri.Host)) return LinkTypeEnum.profile;

            arr = ["lives.jd.com"];
            if (arr.Contains(uri.Host)) return LinkTypeEnum.live;

            arr = ["u.jd.com"];
            if (arr.Contains(uri.Host)) return LinkTypeEnum.other_aff;

            arr = ["h5.m.jd.com"];
            if (arr.Contains(uri.Host)) return LinkTypeEnum.video;

            if (lowerUrl.Contains("h5.m.jd.com/active/faxian/video/index.html"))
                return LinkTypeEnum.video;

            if (lowerUrl.Contains("eco.m.jd.com/content/dr_home/index.html"))
                return LinkTypeEnum.profile;

            if (uri.Host.Contains("jd.com"))
            {
                itemId = GetItemId(url);
                if (!string.IsNullOrEmpty(itemId)) return LinkTypeEnum.goods;
                return LinkTypeEnum.baseDomain;
            }
            return LinkTypeEnum.unknown;
        }

        static bool ContainsSpecialFormat(string content)
        {
            // 使用正则表达式匹配内容中是否含有特定格式的字符串
            string pattern = @"[！$￥%]+[a-zA-Z0-9]+[！$￥%]]*";
            return Regex.IsMatch(content, pattern);
        }

        public async Task<JdDataDTO> JdParseAsync(string content, UnionParseRequest request, JdDataDTO result, CancellationToken cancellationToken = default)
        {

            string message = "OK";
            string url = GetLink(content);
            if (string.IsNullOrEmpty(url))
            {
                result.success = false;
                result.link_type = LinkTypeEnum.unknown;
                result.channel_type = ChannelTypeEnum.jd;
                result.message = "放弃转链";
                result.reason = "纯口令";
                result.accountId = 0;
                result.accountName = string.Empty;
                result.content = content;
                result.shortLinkurl = url;
                result.deeplink_url = GetDefaultStyleDeeplink(url);
                return result;
            }
            string shortLinkurl = url;

            //result.link_type = plus.IsAffLlink(url) ? LinkTypeEnum.other_aff : LinkTypeEnum.goods;
            result.shortLinkurl = url;
            result.link_type = GetLinkType(url, out string out_url, out string itemId);
            url = out_url;
            result.itemId = itemId;

            switch (result.link_type)
            {
                case LinkTypeEnum.profile:
                case LinkTypeEnum.live:
                case LinkTypeEnum.video:

                    result.success = false;
                    result.channel_type = ChannelTypeEnum.jd;
                    result.message = "放弃转链";
                    result.reason = result.link_type switch
                    {
                        LinkTypeEnum.profile => "店铺",
                        LinkTypeEnum.live => "直播",
                        LinkTypeEnum.video => "视频",
                        _ => "非标链接",
                    };
                    result.accountId = 0;
                    result.accountName = string.Empty;
                    result.content = content;
                    result.shortLinkurl = url;
                    result.deeplink_url = GetDefaultStyleDeeplink(url);
                    return result;
                case LinkTypeEnum.other_aff:
                    result.success = false;
                    result.link_type = LinkTypeEnum.unknown;
                    result.channel_type = ChannelTypeEnum.jd;
                    result.message = "放弃转链";
                    result.reason = "其他推广链接";
                    result.accountId = 0;
                    result.accountName = string.Empty;
                    result.content = content;
                    result.shortLinkurl = url;
                    result.deeplink_url = GetDefaultStyleDeeplink(url);
                    return result;
                default:
                    if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(result.itemId) ||
                        (!url.StartsWith("https://item.jd.com/") &&
                        !url.StartsWith("http://item.jd.com/") &&
                        !url.StartsWith("https://item.m.jd.com/product/") &&
                        !url.StartsWith("http://item.m.jd.com/product/") &&
                        !url.StartsWith("http://item.m.jd.com/product/")))
                    {
                        result.success = false;
                        //result.link_type = LinkTypeEnum.unknown;
                        result.channel_type = ChannelTypeEnum.jd;
                        result.message = "放弃转链";
                        result.reason = "非标链接";
                        result.accountId = 0;
                        result.accountName = string.Empty;
                        result.content = content;
                        result.shortLinkurl = shortLinkurl;
                        result.deeplink_url = result.link_type switch
                        {
                            LinkTypeEnum.other_aff or
                            LinkTypeEnum.baseDomain or
                            LinkTypeEnum.goods => GetDefaultStyleDeeplink(result.shortLinkurl),
                            _ => GetDefaultStyleDeeplink(result.shortLinkurl),
                        };
                        return result;
                    }
                    break;
            }
            if (!TestParseCore.InWhitelist(result.ip, result.oaid) && FlowControlIgnoreRequest(_config, request, out string reason))
            {
                result.success = false;
                result.link_type = LinkTypeEnum.unknown;
                result.channel_type = ChannelTypeEnum.jd;
                result.message = "放弃转链";
                result.reason = reason;
                result.accountId = 0;
                result.accountName = string.Empty;
                result.content = content;
                result.shortLinkurl = url;
                result.deeplink_url = result.link_type switch
                {
                    LinkTypeEnum.other_aff or LinkTypeEnum.goods => GetDefaultStyleDeeplink(result.shortLinkurl),
                    _ => GetDefaultStyleDeeplink(result.shortLinkurl),
                };
                return result;
            }

            switch (request.CommerceType)
            {
                case 1:
                case 2:
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = $"厂商放弃{request.CommerceType}";
                    return result;
            }

            switch (_account.work_mode)
            {
                case JdUnionWorkMode.SiteApi:
                    result = await GetPromotionBySiteAsync(result, url, request.ClickId, cancellationToken);
                    break;
                case JdUnionWorkMode.AffApi:
                    result = await GetPromotionByAffAsync(result, url, request.ClickId, cancellationToken);
                    break;
                case JdUnionWorkMode.Ddx:
                    result = await GetPromotionByDdxAsync(result, url, request.ClickId, cancellationToken);
                    break;
                case JdUnionWorkMode.JingFen:
                    result = await GetPromotionByCrawlerJingfenAsync(result, url, request.ClickId, cancellationToken);
                    break;
                case JdUnionWorkMode.Crawler:
                default:
                    result = await GetPromotionByCrawlerAsync(result, url, request.ClickId, cancellationToken);
                    break;
            }
            return result;
        }
    }
}
