using dodohold.core;
using CSRedis;
using System.Data;
using static dodohold.core.ZTOExpress.CreateOrderArgs;
using YunhuiKit;

namespace molilian.core
{
    public partial class TkLogCore
    {

        static string queue_deeplink_parse_key = "queue:parse_logs:deeplink";
        static readonly System.Text.RegularExpressions.Regex[] deeplink_log_content_exclude_patterns =
        [
            // 例：😆 AaSWvWlmhEf 😆 CA4422
            new(@"^[^A-Za-z0-9]*[A-Za-z0-9]{11}[^A-Za-z0-9]+[A-Za-z]{2}\d{3,4}\s*$", System.Text.RegularExpressions.RegexOptions.Compiled),
        ];

        public static async Task<int> InsertDeeplinkLogAsync(int limit, YunhuiKit.RedisClient redis)
        {
            int total = 0;
            using var connection = DBContext.GetOpenConnection();
            connection.Open();
            using var transaction = connection.BeginTransaction();
            try
            {

                for (int i = 0; i < limit; i++)
                {
                    var data = await redis.LPopAsync<DeeplinkParseDataDTO>(queue_deeplink_parse_key);
                    if (data == null) break;


                    if (TestParseCore.InWhitelist(data.ip, data.oaid))
                    {
                        save_dp_parse_logs(data, "deeplink_parse_logs_test", connection, transaction);
                    }
                    else
                    {
                        //save_dp_parse_logs(data, "deeplink_parse_logs", connection, transaction);

                        //if (save_dailys_log)
                        {
                            string daily_table = $"deeplink_parse_logs_{data.create_time:yyyyMMdd}";
                            save_dp_parse_logs(data, daily_table, connection, transaction);
                        }

                        if (data.success)
                        {
                            //save_dp_parse_logs(data, "deeplink_parse_logs_success", connection, transaction);
                        }
                        else
                        {
                            save_dp_parse_logs(data, "deeplink_parse_logs_fail", connection, transaction);
                            save_dp_parse_logs(data, $"deeplink_parse_logs_fail_{data.create_time:yyyyMMdd}", connection, transaction);
                        }
                    }
                    total++;
                }
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                new LoggerLibrary("TkLogCore_error", "task_insert_parse_deeplink_logs")
                      .Info(ex.Message, ex.StackTrace)
                      .SaveAsync();
                throw;
            }
            finally
            {
                connection.Close();
            }
            return total;
        }


        public static int task_insert_parse_deeplink_logs(int limit, CSRedisClient redis)
        {
            int total = 0;
            using var connection = DBContext.GetOpenConnection();
            connection.Open();
            using var transaction = connection.BeginTransaction();
            try
            {

                for (int i = 0; i < limit; i++)
                {
                    var data = redis.LPop<DeeplinkParseDataDTO>(queue_deeplink_parse_key);
                    if (data == null) break;


                    if (TestParseCore.InWhitelist(data.ip, data.oaid))
                    {
                        save_dp_parse_logs(data, "deeplink_parse_logs_test", connection, transaction);
                    }
                    else
                    {
                        //save_dp_parse_logs(data, "deeplink_parse_logs", connection, transaction);

                        //if (save_dailys_log)
                        {
                            string daily_table = $"deeplink_parse_logs_{data.create_time:yyyyMMdd}";
                            save_dp_parse_logs(data, daily_table, connection, transaction);
                        }

                        if (data.success)
                        {
                            //save_dp_parse_logs(data, "deeplink_parse_logs_success", connection, transaction);
                        }
                        else
                        {
                            save_dp_parse_logs(data, "deeplink_parse_logs_fail", connection, transaction);
                        }
                    }
                    total++;
                }
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                new LoggerLibrary("TkLogCore_error", "task_insert_parse_deeplink_logs")
                      .Info(ex.Message, ex.StackTrace)
                      .SaveAsync();
                throw;
            }
            finally
            {
                connection.Close();
            }
            return total;
        }


        //public static int task_insert_parse_deeplink_logs(IDbConnection connection, IDbTransaction transaction, int limit, CSRedisClient redis)
        //{
        //    int total = 0;

        //    for (int i = 0; i < limit; i++)
        //    {
        //        var data = redis.LPop<DeeplinkParseDataDTO>(queue_deeplink_parse_key);
        //        if (data == null) break;

        //        if (_test_oaid.Equals(data.oaid) ||
        //             data.ip.Contains("127.0.0"))
        //        {
        //            var test_data = data.Convert2Json().Convert2Object<TestDeeplinkParseDataDTO>();
        //            connection.Insert(test_data);
        //        }
        //        else
        //        {
        //            connection.Insert(data);
        //            if (!data.success)
        //            {
        //                var success_data = data.Convert2Json().Convert2Object<FilDeeplinkParseDataDTO>();
        //                connection.Insert(success_data);
        //            }
        //            else
        //            {
        //                var success_data = data.Convert2Json().Convert2Object<SuccessDeeplinkParseDataDTO>();
        //                connection.Insert(success_data);
        //            }
        //        }
        //        total++;
        //    }
        //    return total;
        //}
        public static async Task ParseLogAsync(DeeplinkParseDataDTO response)
        {
            try
            {
                var ts = DateTime.Now - response.create_time;
                response.elapsedTime = (int)ts.TotalMilliseconds;
                _ = RedisKit.RPushAsync(queue_deeplink_parse_key, response);

                if (!TestParseCore.InWhitelist(response.ip, response.oaid))
                {
                    await SaveParseCacheAsync(response.channel_name, 0, "tool",
                        response.success, response.message, response.reason,
                        response.deeplink_url);
                }
            }
            catch (Exception ex) { }
        }


        private static int save_dp_parse_logs(DeeplinkParseDataDTO data, string tablename, IDbConnection connection, IDbTransaction transaction)
        {


            //public int channel_id { get; set; } = 0;
            //public string channel_name { get; set; } = "unknown";
            //public bool success { get; set; } = true;
            //public string message { get; set; } = string.Empty;
            //public string reason { get; set; } = string.Empty;
            //public string content { get; set; } = string.Empty;
            //public string ip { get; set; } = string.Empty;
            //public string oaid { get; set; } = string.Empty;
            //public string deeplink_url { get; set; } = string.Empty;
            //public string itemName { get; set; } = string.Empty;
            //public int elapsedTime { get; set; } = 0;
            //public DateTime create_time { get; set; } = DateTime.Now;
            //public string end_point { get; set; } = string.Empty;

            string content = data.content;
            if (content.Length > 20000) content = $"{content[..20000]}...";
            if (tablename.StartsWith("deeplink_parse_logs_fail") && DeeplinkLogContentExcluded(content))
            {
                return 0;
            }

            return new DBContext.Table(connection, tablename)
                .Add("end_point", data.end_point)
                .Add("channel_name", data.channel_name)
                .Add("success", data.success)
                .Add("message", data.message)
                .Add("reason", data.reason)
                .Add("content", content)
                .Add("ip", data.ip)
                .Add("oaid", data.oaid)
                .Add("deeplink_url", data.deeplink_url)
                .Add("itemName", data.itemName)
                .Add("elapsedTime", data.elapsedTime)
                .Add("create_time", data.create_time)
                .Create(DBContext.InsertType.NORMAL, transaction);
        }

        private static bool DeeplinkLogContentExcluded(string content)
        {
            if (string.IsNullOrWhiteSpace(content)) return false;

            foreach (var pattern in deeplink_log_content_exclude_patterns)
            {
                try
                {
                    if (pattern.IsMatch(content))
                    {
                        return true;
                    }
                }
                catch
                {
                }
            }

            return false;
        }

    }

}
