
using dodohold.core;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.FileSystemGlobbing.Internal;
using Sayaka.Common;
using Spire.Pdf.Annotations;
using System.Text.RegularExpressions;
using System.Xml.Linq;
namespace molilian.core
{
    public partial class DeeplinkParseCore
    {


        private static string _end_point;
        private static readonly string[] separators = ["\r\n", "\n"];

        static DeeplinkParseCore()
        {
            _end_point = Environment.GetEnvironmentVariable("EndPoint");
        }


        public static DeeplinkParseDataDTO GetFormattedObject(string content, string channel, string ip = "", string oaid = "")
        {
            return new DeeplinkParseDataDTO()
            {
                message = string.Empty,
                success = false,
                content = content,
                ip = ip,
                oaid = oaid,
                elapsedTime = 0,
                create_time = DateTime.Now,
                end_point = _end_point,
            };
        }

        public static async Task<ActionResult> ParseAsync(string content, string channel, string ip, string oaid)
        {
            var result = GetFormattedObject(content, channel, ip, oaid);
            content = content.Trim();

            var rule = DeeplinkParseRuleCore.GetOne(channel);
            if (rule == null)
            {
                result.success = false;
                result.message = "转链失败";
                result.reason = "无效平台";

                _ = TkLogCore.ParseLogAsync(result);
                return new APIResult(new
                {
                    result.success,
                    result.message,
                    result.reason,
                });
            }
            result.channel_id = rule.channel_id;
            result.channel_name = rule.channel_name;

            result = await GenerateDeeplink(content, rule, result);

            _ = TkLogCore.ParseLogAsync(result);
            return new APIResult(new
            {
                result.success,
                result.message,
                channel = result.channel_name,
                result.deeplink_url,
                result.itemName,
            });

        }

        public static async Task<DeeplinkParseDataDTO> GenerateDeeplink(string text, DeeplinkParseRuleDTO config, DeeplinkParseDataDTO result)
        {
            try
            {
                var list = config.rules.Convert2Object<List<DeeplinkParseRule>>();

                foreach (var rule in list)
                {
                    var e = await WorkEachRule(text, config, result, rule);
                    if (e != null) return e;
                }
            }
            catch (Exception ex)
            {
            }

            result.success = false;
            return result;
        }

        private static async Task<DeeplinkParseDataDTO?> WorkEachRule(string text, DeeplinkParseRuleDTO config, DeeplinkParseDataDTO result, DeeplinkParseRule rule)
        {
            if (!rule.enable) return null;

            string content = text;

            if (!string.IsNullOrEmpty(rule.url_pattern))
            {
                var regex = new Regex(rule.url_pattern);
                var match = regex.Match(content);
                if (!match.Success) return null;

                content = match.Groups[1].Value;
            }

            string url = ToolParsePlus.GetLink(text);
            try
            {
                switch (rule.url_action)
                {
                    case UrlAction.Redirect:
                        {
                            var response = await new WebClientUtility
                            {
                                Proxy = ProxyNodesCore.RandomOne(),
                                AllowAutoRedirect = false
                            }.RequestAsync(url);
                            if (response.ResponseMessage != null)
                            {
                                content = response.ResponseMessage.Headers.Location.ToString();
                                content = content.UrlDecode();
                            }
                        }
                        break;
                    case UrlAction.Body:
                        {
                            var response = await new WebClientUtility
                            {
                                Proxy = ProxyNodesCore.RandomOne(),
                                UserAgent = ProviderFakeUserAgent.RandomMobile,
                                AllowAutoRedirect = true
                            }.RequestAsync(url);
                            content = response.Body();
                        }
                        break;
                    case UrlAction.None:
                        //{
                        //    content = url;
                        //}
                        break;
                }
            }
            catch (Exception ex)
            {
                //Console.WriteLine($"{url}\t{rule.url_action}\t{ex.Message}");
            }

            if (rule.childs.Count > 0)
            {
                foreach (var sub_rule in rule.childs)
                {
                    var e = await WorkEachRule(content, config, result, sub_rule);
                    if (e != null) return e;
                }
                return null;
            }


            if (!string.IsNullOrEmpty(rule.body_pattern))
            {
                var regex = new Regex(rule.body_pattern);
                var match = regex.Match(content);
                if (!match.Success) return null;

            }

            var deeplink = rule.deeplink_template;
            var prompt_text = rule.prompt_text;

            try
            {
                var regex = new Regex(rule.pattern);
                var match = regex.Match(content);
                if (match.Success)
                {
                    if (match.Groups.Count > 1)
                    {
                        for (var i = 1; i < match.Groups.Count; i++)
                        {
                            string val = match.Groups[i].Value;
                            if (deeplink.Contains("{url:"))
                            {
                                deeplink = deeplink.Replace($"{{url:{i - 1}}}", val.UrlEncode());
                            }
                            if (prompt_text.Contains("{url:"))
                            {
                                prompt_text = prompt_text.Replace($"{{url:{i - 1}}}", val.UrlEncode());
                            }

                            //atob
                            if (deeplink.Contains("{atob:"))
                            {
                                deeplink = deeplink.Replace($"{{atob:{i - 1}}}", val.FromBase64());
                            }
                            if (prompt_text.Contains("{atob:"))
                            {
                                prompt_text = prompt_text.Replace($"{{atob:{i - 1}}}", val.FromBase64());
                            }

                            //btoa
                            if (deeplink.Contains("{btoa:"))
                            {
                                deeplink = deeplink.Replace($"{{btoa:{i - 1}}}", val.ToBase64());
                            }
                            if (prompt_text.Contains("{btoa:"))
                            {
                                prompt_text = prompt_text.Replace($"{{btoa:{i - 1}}}", val.ToBase64());
                            }


                            deeplink = deeplink.Replace($"{{{i - 1}}}", val);
                            prompt_text = prompt_text.Replace($"{{{i - 1}}}", val);
                        }

                        deeplink = Regex.Replace(deeplink, @"\{\d+\}", string.Empty);
                        prompt_text = Regex.Replace(prompt_text, @"\{\d+\}", string.Empty);

                        if (!string.IsNullOrEmpty(deeplink))
                        {
                            result.deeplink_url = deeplink;
                            result.itemName = prompt_text;
                            result.success = true;
                            return result;
                        }
                    }
                    else
                    {
                        result.deeplink_url = deeplink;
                        result.itemName = prompt_text;
                        result.success = true;
                        return result;

                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error processing pattern '{rule.pattern}': {ex.Message}");
            }

            return null;

        }

    }

}
