using molilian.core;
using dodohold.core;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
using System.Net;
using static QRCoder.PayloadGenerator;
using MySqlX.XDevAPI;
using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
namespace molilian.api.Controllers
{


    [ApiController]
    [MyAuthorize("admin")]
    [Route("api/[controller]/[action]")]
    [Route("coupon_api/[controller]/[action]")]
    public class TaobaoController : ControllerBase
    {
        readonly IAuthorizationProvider provider = new AdminProvider();
        protected IHttpContextAccessor _accessor;
        public TaobaoController(IHttpContextAccessor accessor)
        {
            _accessor = accessor;
        }

        [HttpPost]
        public async Task<ActionResult> updateCookies([FromBody] JsonElement form)
        {
            var clientIp = _accessor.HttpContext.GetUserIp();
            var token = provider.Get(_accessor.HttpContext);
            string user_agent = _accessor.HttpContext.Request.UserAgent();


            string cookie = form.Read<string>("cookie", string.Empty);
            var accountId = TkPoolCore.UpdateCookies(cookie, user_agent);
            bool success = accountId > 0;
            if (success)
            {
                //string desc = ObjectComparer.PrintCompareToString(old, form).Trim();
                OperationLogCore.LogOperation(token.AccessKey, clientIp, $"tk_pool:{accountId}:cookie", string.Empty, cookie);
            }
            return new APIResult(new
            {
                data = new { success, msg = success ? "更新成功" : "更新失败，请检查输入的cookie" },
            });
        }


        [HttpPost]
        public async Task<ActionResult> update([FromBody] JsonElement form)
        {
            var clientIp = _accessor.HttpContext.GetUserIp();
            var token = provider.Get(_accessor.HttpContext);

            int id = form.Read<int>("id", 0);
            string name = form.Read<string>("name", string.Empty);
            string val = form.Read<string>("val", string.Empty);

            if (id == 0)
            {
                return new APIResult(new { data = new { success = false, msg = "更新失败，请检查输入的cookie" } });
            }

            int result;
            switch (name)
            {
                case "enable_fake_click":
                case "enable_parse":
                case "enable_coupon":
                case "enable_sync_order":
                case "enable_promotionQuery":
                case "enable_deep_url":
                case "status":
                    bool bVal = val.Equals("True");
                    result = new DBContext.Table("tk_pool")
                           .Add(name, bVal)
                           .Add("last_time", DateTime.Now)
                           .Where("id=@id", new { id })
                           .Update();
                    break;
                case "check_status":
                    //检查状态
                    var arr = EndPointCore.NotifyCheckDeepUrl(id);
                    string suspended_endpoint = string.Empty;
                    var log = new LoggerLibrary("check_suspended_endpoint");

                    foreach ((string node, string message) in arr)
                    {
                        log.Info(node, message);
                        if (message.Contains("霸下验证码"))
                        {
                            suspended_endpoint += $"{node},";
                        }
                    }
                    result = new DBContext.Table("tk_pool")
                           .Add("suspended_endpoint", suspended_endpoint)
                           .Add("last_time", DateTime.Now)
                           .Where("id=@id", new { id })
                           .Update();

                    log.SaveAsync();
                    break;
                default:
                    return new APIResult(new { data = new { success = false, msg = "更新失败，未授权操作" } });
            }
            bool success = result > 0;
            if (success)
            {
                //string desc = ObjectComparer.PrintCompareToString(old, form).Trim();
                OperationLogCore.LogOperation(token.AccessKey, clientIp, $"tk_pool:{id}:{name}", string.Empty, val);
                await EndPointCore.NotifyReload(true);

            }
            return new APIResult(new
            {
                data = new { success, msg = success ? "更新成功" : "更新失败，请检查输入信息" },
            });
        }


        /// <summary>
        /// 账号列表
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult list([FromBody] JsonElement form)
        {
            var token = provider.Get(_accessor.HttpContext);

            int page = form.Read("current", 1);
            int size = form.Read("pageSize", 10);
            string keyword = form.Read("name", string.Empty);
            bool getTotal = form.Read("getTotal", true);
            string _status = form.Read("status", string.Empty);
            int status = _status switch
            {
                "online" => 1,
                "offline" => 0,
                _ => -1,
            };
            var lastTime = form.PathReadArray<string>("lastTime[]");

            string sort = form.Read<string>("sort");
            string order = form.Read<string>("order");

            string filter = string.Empty;
            if (!string.IsNullOrEmpty(keyword))
            {
                filter += $" AND (`name` LIKE @keyword OR `description` LIKE @keyword)";
                keyword = $"%{keyword}%";
            }
            DateTime stime = DateTime.MinValue, etime = DateTime.MinValue;
            if (lastTime.Count == 2)
            {
                if (DateTime.TryParse(lastTime[0], out stime) && DateTime.TryParse(lastTime[1], out etime))
                {
                    etime = etime.AddDays(1).AddSeconds(-1);
                    filter += $" AND last_time BETWEEN @stime AND @etime";
                }
            }
            if (status != -1)
            {
                filter += $" AND status=@status";

            }

            filter = filter.StringTrimStart(" AND ");

            //排序
            string orderBy = "id DESC";
            if (!string.IsNullOrEmpty(order))
            {
                order = "descending".Equals(order) ? "DESC" : "ASC";
                orderBy = sort switch
                {
                    //"num" => $"num {order}",
                    _ => $"{sort} {order}",
                };
            }

            using var conn = DBContext.GetOpenConnection();
            var result = new DBContext.Table(conn, "tk_pool")
                .Where(filter, new { keyword, status, stime, etime })
                .Page(size, page)
                .Order(orderBy)
                .PageList<TkPoolDTO>(getTotal);

            foreach (var item in result.List)
            {
                item.current_amt = Math.Round(TkPoolCore.GetIncomeAmt($"{item.id}"), 2);
                item.cookies = string.Empty;
            }
            return new APIResult(new { data = result });
        }


        [HttpPost]
        public ActionResult report_dailys([FromBody] JsonElement form)
        {
            int page = form.Read("current", 1);
            int size = form.Read("pageSize", 10);
            bool getTotal = form.Read("getTotal", true);
            string sort = form.Read<string>("sort");
            string order = form.Read<string>("order");

            var report_date = form.PathReadArray<string>("query_date[]");
            string dailys_accountName = "all";
            int dailys_accountId = 0;

            string filter = string.Empty;
            DateTime stime = DateTime.MinValue, etime = DateTime.MinValue;
            if (report_date.Count == 2)
            {
                if (DateTime.TryParse(report_date[0], out stime) && DateTime.TryParse(report_date[1], out etime))
                {
                    etime = etime.AddDays(1).AddSeconds(-1);
                    filter += $" AND A.report_date BETWEEN @stime AND @etime";
                }
            }

            filter = filter.StringTrimStart(" AND ");

            //排序
            string orderBy = "A.report_date DESC";
            if (!string.IsNullOrEmpty(order))
            {
                order = "descending".Equals(order) ? "DESC" : "ASC";
                orderBy = sort switch
                {
                    _ => $"A.{sort} {order}",
                };
            }

            var result = new DBContext.Table("v_tk_report_dailys")
                .LeftJoin("daily_logs",
                "B.log_date = A.report_date AND B.channel=0 AND B.accountId=@dailys_accountId",
                "total_count, B.abandon_count, B.success_count, B.abandon_percentage, B.success_percentage," +
                "B.parse_total_count, B.parse_abandon_count, B.parse_success_count, B.parse_abandon_percentage, B.parse_success_percentage," +
                "B.coupon_total_count, B.coupon_abandon_count, B.coupon_success_count, B.coupon_abandon_percentage, B.coupon_success_percentage," +
                "B.tool_total_count, B.tool_abandon_count, B.tool_success_count, B.tool_abandon_percentage, B.tool_success_percentage")
                .Where(filter, new { dailys_accountId, dailys_accountName, stime, etime })
                .Page(size, page)
                .Order(orderBy)
                .PageList<TkReportDTO>(getTotal);

            foreach (var item in result.List)
            {
                if (item.report_date.Date < DateTime.Now.Date) continue;
                if (item.total_count == 0)
                {
                    item.total_count = TkLogCore.GetTotal($":total:tb:{item.report_date:yyyyMMdd}");
                    if (item.total_count > 0)
                    {
                        item.success_count = TkLogCore.GetTotal($":total:tb:success:{item.report_date:yyyyMMdd}");
                        item.abandon_count = TkLogCore.GetTotal($":total:tb:放弃转链:{item.report_date:yyyyMMdd}");
                        if (item.total_count > 0)
                        {
                            item.success_percentage = $"{item.success_count / (double)item.total_count * 100:f2}%";
                            item.abandon_percentage = $"{item.abandon_count / (double)item.total_count * 100:f2}%";
                        }
                    }
                }

                if (item.parse_total_count == 0)
                {
                    item.parse_total_count = TkLogCore.GetTotal($":parse_total:tb:{item.report_date:yyyyMMdd}");
                    if (item.parse_total_count > 0)
                    {
                        item.parse_success_count = TkLogCore.GetTotal($":parse_total:tb:success:{item.report_date:yyyyMMdd}");
                        item.parse_abandon_count = TkLogCore.GetTotal($":parse_total:tb:放弃转链:{item.report_date:yyyyMMdd}");
                        if (item.parse_total_count > 0)
                        {
                            item.parse_success_percentage = $"{item.parse_success_count / (double)item.parse_total_count * 100:f2}%";
                            item.parse_abandon_percentage = $"{item.parse_abandon_count / (double)item.parse_total_count * 100:f2}%";
                        }
                    }
                }

                if (item.coupon_total_count == 0)
                {
                    item.coupon_total_count = TkLogCore.GetTotal($":coupon_total:tb:{item.report_date:yyyyMMdd}", false);
                    if (item.coupon_total_count > 0)
                    {
                        item.coupon_success_count = TkLogCore.GetTotal($":coupon_total:tb:success:{item.report_date:yyyyMMdd}", false);
                        item.coupon_abandon_count = TkLogCore.GetTotal($":coupon_total:tb:放弃转链:{item.report_date:yyyyMMdd}", false);
                        if (item.coupon_total_count > 0)
                        {
                            item.coupon_success_percentage = $"{item.coupon_success_count / (double)item.coupon_total_count * 100:f2}%";
                            item.coupon_abandon_percentage = $"{item.coupon_abandon_count / (double)item.coupon_total_count * 100:f2}%";
                        }
                    }
                }

                if (item.tool_total_count == 0)
                {
                    item.tool_total_count = TkLogCore.GetTotal($":parse_total:tool:{item.report_date:yyyyMMdd}");
                    if (item.tool_total_count > 0)
                    {
                        item.tool_success_count = TkLogCore.GetTotal($":parse_total:tool:success:{item.report_date:yyyyMMdd}");
                        item.tool_abandon_count = TkLogCore.GetTotal($":parse_total:tool:放弃转链:{item.report_date:yyyyMMdd}");
                        if (item.tool_total_count > 0)
                        {
                            item.tool_success_percentage = $"{item.tool_success_count / (double)item.tool_total_count * 100:f2}%";
                            item.tool_abandon_percentage = $"{item.tool_abandon_count / (double)item.tool_total_count * 100:f2}%";
                        }

                    }
                }
            }
            return new APIResult(new
            {
                data = result
            });
        }

        [HttpPost]
        public ActionResult report_list([FromBody] JsonElement form)
        {
            int page = form.Read("current", 1);
            int size = form.Read("pageSize", 10);
            bool getTotal = form.Read("getTotal", true);
            string sort = form.Read<string>("sort");
            string order = form.Read<string>("order");

            var report_date = form.PathReadArray<string>("query_date[]");
            int accountId = form.Read("accountId", 0);

            string filter = string.Empty;
            if (accountId != 0)
            {
                filter += $" AND accountId=@accountId";
            }

            DateTime stime = DateTime.MinValue, etime = DateTime.MinValue;
            if (report_date.Count == 2)
            {
                if (DateTime.TryParse(report_date[0], out stime) && DateTime.TryParse(report_date[1], out etime))
                {
                    etime = etime.AddDays(1).AddSeconds(-1);
                    filter += $" AND report_date BETWEEN @stime AND @etime";
                }
            }

            filter = filter.StringTrimStart(" AND ");

            //排序
            string orderBy = "id DESC";
            if (!string.IsNullOrEmpty(order))
            {
                order = "descending".Equals(order) ? "DESC" : "ASC";
                orderBy = sort switch
                {
                    _ => $"{sort} {order}",
                };
            }

            var result = new DBContext.Table("tk_report")
                .Where(filter, new { accountId, stime, etime })
                .Page(size, page)
                .Order(orderBy)
                .PageList<TkReportDTO>(getTotal);



            foreach (var item in result.List)
            {
#if DEBUG
#else
                if (item.report_date.Date < DateTime.Now.Date) continue;
#endif
                //var tk = TkPoolCore.GetOne(item.accountId);
                //if (tk != null) item.accountName = tk.company;
                string accountName = $"{TkChannelEnum.tb}_{item.accountId}";

                if (item.total_count == 0)
                {
                    item.total_count = TkLogCore.GetTotal($":total:{accountName}:{item.report_date:yyyyMMdd}");
                    if (item.total_count > 0)
                    {
                        //todo  过度用， 0613 跑两天就可以删掉
                        accountName = item.accountName;
                        item.total_count = TkLogCore.GetTotal($":total:{accountName}:{item.report_date:yyyyMMdd}");
                    }
                    if (item.total_count > 0)
                    {
                        item.success_count = TkLogCore.GetTotal($":total:{accountName}:success:{item.report_date:yyyyMMdd}");
                        item.abandon_count = TkLogCore.GetTotal($":total:{accountName}:放弃转链:{item.report_date:yyyyMMdd}");
                        if (item.total_count > 0)
                        {
                            item.success_percentage = $"{item.success_count / (double)item.total_count * 100:f2}%";
                            item.abandon_percentage = $"{item.abandon_count / (double)item.total_count * 100:f2}%";
                        }
                    }
                }

                if (item.parse_total_count == 0)
                {
                    item.parse_total_count = TkLogCore.GetTotal($":parse_total:{accountName}:{item.report_date:yyyyMMdd}");
                    if (item.parse_total_count > 0)
                    {
                        item.parse_success_count = TkLogCore.GetTotal($":parse_total:{accountName}:success:{item.report_date:yyyyMMdd}");
                        item.parse_abandon_count = TkLogCore.GetTotal($":parse_total:{accountName}:放弃转链:{item.report_date:yyyyMMdd}");
                        if (item.parse_total_count > 0)
                        {
                            item.parse_success_percentage = $"{item.parse_success_count / (double)item.parse_total_count * 100:f2}%";
                            item.parse_abandon_percentage = $"{item.parse_abandon_count / (double)item.parse_total_count * 100:f2}%";
                        }
                    }
                }

                if (item.coupon_total_count == 0)
                {
                    item.coupon_total_count = TkLogCore.GetTotal($":coupon_total:{accountName}:{item.report_date:yyyyMMdd}", false);
                    if (item.coupon_total_count > 0)
                    {
                        item.coupon_success_count = TkLogCore.GetTotal($":coupon_total:{accountName}:success:{item.report_date:yyyyMMdd}", false);
                        item.coupon_abandon_count = TkLogCore.GetTotal($":coupon_total:{accountName}:放弃转链:{item.report_date:yyyyMMdd}", false);
                        if (item.coupon_total_count > 0)
                        {
                            item.coupon_success_percentage = $"{item.coupon_success_count / (double)item.coupon_total_count * 100:f2}%";
                            item.coupon_abandon_percentage = $"{item.coupon_abandon_count / (double)item.coupon_total_count * 100:f2}%";
                        }
                    }
                }

                if (item.tool_total_count == 0)
                {
                    item.tool_total_count = TkLogCore.GetTotal($":parse_total:tool:{item.report_date:yyyyMMdd}");
                    if (item.tool_total_count > 0)
                    {
                        item.tool_success_count = TkLogCore.GetTotal($":parse_total:tool:success:{item.report_date:yyyyMMdd}");
                        item.tool_abandon_count = TkLogCore.GetTotal($":parse_total:tool:放弃转链:{item.report_date:yyyyMMdd}");
                        if (item.tool_total_count > 0)
                        {
                            item.tool_success_percentage = $"{item.tool_success_count / (double)item.tool_total_count * 100:f2}%";
                            item.tool_abandon_percentage = $"{item.tool_abandon_count / (double)item.tool_total_count * 100:f2}%";
                        }
                    }
                }
            }
            return new APIResult(new { data = result });
        }

        [HttpPost]
        public ActionResult report_hourtrend([FromBody] JsonElement form)
        {
            int page = form.Read("current", 1);
            int size = form.Read("pageSize", 10);
            bool getTotal = form.Read("getTotal", true);
            string sort = form.Read<string>("sort");
            string order = form.Read<string>("order");

            var report_date = form.PathReadArray<string>("query_date[]");
            int accountId = form.Read("accountId", 0);

            string filter = string.Empty;
            if (accountId != 0)
            {
                filter += $" AND accountId=@accountId";
            }

            DateTime stime = DateTime.MinValue, etime = DateTime.MinValue;
            if (report_date.Count == 2)
            {
                if (DateTime.TryParse(report_date[0], out stime) && DateTime.TryParse(report_date[1], out etime))
                {
                    etime = etime.AddDays(1).AddSeconds(-1);
                    if (etime > DateTime.Now) etime = DateTime.Now;
                    filter += $" AND report_date BETWEEN @stime AND @etime";
                }
            }

            filter = filter.StringTrimStart(" AND ");

            //排序
            string orderBy = "id ASC";
            if (!string.IsNullOrEmpty(order))
            {
                order = "descending".Equals(order) ? "DESC" : "ASC";
                orderBy = sort switch
                {
                    _ => $"{sort} {order}",
                };
            }

            using var conn = DBContext.GetOpenConnection();
            var result = new DBContext.Table(conn, "tk_report_hourtrend")
                .Where(filter, new { accountId, stime, etime })
                .Page(size, page)
                .Order(orderBy)
                .PageList<TkReportDTO>(getTotal);

            foreach (var item in result.List)
            {

#if DEBUG
#else
                if (item.report_date.Date < DateTime.Now.Date) continue;
#endif
                string accountName = $"{TkChannelEnum.tb}_{item.accountId}";
                if (item.total_count == 0)
                {
                    item.total_count = TkLogCore.GetTotal($":total:{accountName}:{item.report_date:yyyyMMddHH}");
                    if (item.total_count == 0)
                    {
                        //todo  过度用， 0613 跑两天就可以删掉
                        accountName = item.accountName;
                        item.total_count = TkLogCore.GetTotal($":total:{accountName}:{item.report_date:yyyyMMddHH}");
                    }
                    if (item.total_count == 0) continue;
                    item.success_count = TkLogCore.GetTotal($":total:{item.accountName}:success:{item.report_date:yyyyMMddHH}");
                    item.abandon_count = TkLogCore.GetTotal($":total:{item.accountName}:放弃转链:{item.report_date:yyyyMMddHH}");
                    if (item.total_count > 0)
                    {
                        item.success_percentage = $"{item.success_count / (double)item.total_count * 100:f2}%";
                        item.abandon_percentage = $"{item.abandon_count / (double)item.total_count * 100:f2}%";
                    }
                }

                if (item.parse_total_count == 0)
                {
                    item.parse_total_count = TkLogCore.GetTotal($":parse_total:{accountName}:{item.report_date:yyyyMMddHH}");
                    if (item.parse_total_count > 0)
                    {
                        item.parse_success_count = TkLogCore.GetTotal($":parse_total:{item.accountName}:success:{item.report_date:yyyyMMddHH}");
                        item.parse_abandon_count = TkLogCore.GetTotal($":parse_total:{item.accountName}:放弃转链:{item.report_date:yyyyMMddHH}");
                        if (item.parse_total_count > 0)
                        {
                            item.parse_success_percentage = $"{item.parse_success_count / (double)item.parse_total_count * 100:f2}%";
                            item.parse_abandon_percentage = $"{item.parse_abandon_count / (double)item.parse_total_count * 100:f2}%";
                        }
                    }
                }

                if (item.coupon_total_count == 0)
                {
                    item.coupon_total_count = TkLogCore.GetTotal($":coupon_total:{accountName}:{item.report_date:yyyyMMddHH}", false);
                    if (item.coupon_total_count > 0)
                    {
                        item.coupon_success_count = TkLogCore.GetTotal($":coupon_total:{item.accountName}:success:{item.report_date:yyyyMMddHH}", false);
                        item.coupon_abandon_count = TkLogCore.GetTotal($":coupon_total:{item.accountName}:放弃转链:{item.report_date:yyyyMMddHH}", false);
                        if (item.coupon_total_count > 0)
                        {
                            item.coupon_success_percentage = $"{item.coupon_success_count / (double)item.coupon_total_count * 100:f2}%";
                            item.coupon_abandon_percentage = $"{item.coupon_abandon_count / (double)item.coupon_total_count * 100:f2}%";
                        }
                    }
                }

                if (item.tool_total_count == 0)
                {
                    item.tool_total_count = TkLogCore.GetTotal($":tool_total:{accountName}:{item.report_date:yyyyMMddHH}");
                    if (item.tool_total_count > 0)
                    {
                        item.tool_success_count = TkLogCore.GetTotal($":tool_total:{item.accountName}:success:{item.report_date:yyyyMMddHH}");
                        item.tool_abandon_count = TkLogCore.GetTotal($":tool_total:{item.accountName}:放弃转链:{item.report_date:yyyyMMddHH}");
                        if (item.tool_total_count > 0)
                        {
                            item.tool_success_percentage = $"{item.tool_success_count / (double)item.tool_total_count * 100:f2}%";
                            item.tool_abandon_percentage = $"{item.tool_abandon_count / (double)item.tool_total_count * 100:f2}%";
                        }
                    }
                }
            }
            return new APIResult(new { data = result });
        }


        [HttpPost]
        public ActionResult chartData([FromBody] JsonElement form)
        {
            var result = new List<dynamic>();
            var reason_result = new List<dynamic>();

            var report_date = form.PathReadArray<string>("query_date[]");
            var accountName = form.Read("accountName", string.Empty);
            var isHourtrend = form.Read<bool>("isLeaf", false);
            var total_key = form.Read("total_key", "total");

            DateTime stime = DateTime.MinValue;
            if (!DateTime.TryParse(report_date[0], out stime)) return new APIResult(new { data = result, data2 = reason_result });

            string _report_date = stime.ToString("yyyyMMdd");
            if (isHourtrend) _report_date = stime.ToString("yyyyMMddHH");



            if (string.IsNullOrEmpty(accountName)) accountName = "tb";
            if (total_key == "tool_total")
            {
                accountName = "tool";
                total_key = "parse_total";

                string cacheKey = $":{total_key}:{accountName}:{_report_date}";
                double total = TkLogCore.GetTotal(cacheKey);
                if (total > 0)
                {
                    string[] keys = ["bdpan", "wemeet"];

                    foreach (var keyname in keys)
                    {
                        //                    string[] keys = ["bdpan:success", "bdpan:fail", "wemeet:success", "wemeet:fail"];

                        cacheKey = $":{total_key}:{keyname}:{_report_date}";
                        total = TkLogCore.GetTotal(cacheKey);

                        cacheKey = $":{total_key}:{keyname}:success:{_report_date}";
                        int value = TkLogCore.GetTotal(cacheKey);
                        if (value == 0) continue;
                        result.Add(new { name = $"{keyname}-成功", value, increases = Math.Round(value / total * 100, 2) });


                        cacheKey = $":{total_key}:{keyname}:fail:{_report_date}";
                        value = TkLogCore.GetTotal(cacheKey);
                        if (value == 0) continue;
                        result.Add(new { name = $"{keyname}-失败", value, increases = Math.Round(value / total * 100, 2) });
                    }

                    cacheKey = $":{total_key}:{accountName}:reason:{_report_date}";
                    string[] reason_keys = TkLogCore.GetTotalKeys(cacheKey);

                    foreach (var keyname in reason_keys)
                    {
                        cacheKey = $":{total_key}:{accountName}:{keyname}:{_report_date}";
                        int value = TkLogCore.GetTotal(cacheKey);
                        if (value == 0) continue;
                        reason_result.Add(new { name = keyname, value, increases = Math.Round(value / total * 100, 2) });
                    }
                    reason_result = reason_result.OrderByDescending(item => item.value).ToList();
                }
                return new APIResult(new { total, data = result, data2 = reason_result });
            }
            else
            {
                string cacheKey = $":{total_key}:{accountName}:{_report_date}";
                double total = TkLogCore.GetTotal(cacheKey, false);
                if (total > 0)
                {
                    string[] keys = ["success"];

                    cacheKey = $":{total_key}:{accountName}:message:{_report_date}";
                    string[] message_keys = TkLogCore.GetTotalKeys(cacheKey, false);

                    var combinedKeys = keys.Union(message_keys).ToList();
                    combinedKeys.RemoveAll(item => item == "fail");
                    combinedKeys.RemoveAll(item => item == "OK");

                    foreach (var keyname in combinedKeys)
                    {
                        cacheKey = $":{total_key}:{accountName}:{keyname}:{_report_date}";
                        int value = TkLogCore.GetTotal(cacheKey, false);
                        if (value == 0) continue;
                        result.Add(new { name = keyname, value, increases = Math.Round(value / total * 100, 2) });
                    }
                    result = result.OrderByDescending(item => item.value).ToList();

                    cacheKey = $":{total_key}:{accountName}:reason:{_report_date}";
                    string[] reason_keys = TkLogCore.GetTotalKeys(cacheKey, false);

                    foreach (var keyname in reason_keys)
                    {
                        if ("没有优惠券".Equals(keyname)) continue;
                        cacheKey = $":{total_key}:{accountName}:{keyname}:{_report_date}";
                        int value = TkLogCore.GetTotal(cacheKey, false);
                        if (value < 50) continue;
                        reason_result.Add(new { name = keyname, value, increases = Math.Round(value / total * 100, 2) });
                    }
                    reason_result = reason_result.OrderByDescending(item => item.value).ToList();
                }
                return new APIResult(new { total, data = result, data2 = reason_result });
            }
        }

        [HttpPost]
        public ActionResult chartData2([FromBody] JsonElement form)
        {
            var result = new List<dynamic>();
            var reason_result = new List<dynamic>();

            var report_date = form.PathReadArray<string>("query_date[]");
            var accountName = form.Read("accountName", string.Empty);
            var isHourtrend = form.Read<bool>("isLeaf", false);
            var total_key = form.Read("total_key", "total");

            if (string.IsNullOrEmpty(accountName)) accountName = "tb";

            DateTime stime = DateTime.MinValue;
            if (!DateTime.TryParse(report_date[0], out stime)) return new APIResult(new { data = result, data2 = reason_result });

            string _report_date = stime.ToString("yyyyMMdd");
            if (isHourtrend) _report_date = stime.ToString("yyyyMMddHH");

            string cacheKey = $":{total_key}:{accountName}:{_report_date}";
            double total = TkLogCore.GetTotal(cacheKey);
            if (total > 0)
            {
                string[] keys = ["success"];

                cacheKey = $":{total_key}:{accountName}:message:{_report_date}";
                string[] message_keys = TkLogCore.GetTotalKeys(cacheKey);

                var combinedKeys = keys.Union(message_keys).ToList();
                combinedKeys.RemoveAll(item => item == "fail");
                combinedKeys.RemoveAll(item => item == "OK");


                foreach (var keyname in combinedKeys)
                {
                    cacheKey = $":{total_key}:{accountName}:{keyname}:{_report_date}";
                    int value = TkLogCore.GetTotal(cacheKey);
                    if (value == 0) continue;
                    result.Add(new { name = keyname, value, increases = Math.Round(value / total * 100, 2) });
                }
                result = result.OrderByDescending(item => item.value).ToList();

                cacheKey = $":{total_key}:{accountName}:reason:{_report_date}";
                string[] reason_keys = TkLogCore.GetTotalKeys(cacheKey);

                foreach (var keyname in reason_keys)
                {
                    if ("没有优惠券".Equals(keyname)) continue;
                    cacheKey = $":{total_key}:{accountName}:{keyname}:{_report_date}";
                    int value = TkLogCore.GetTotal(cacheKey);
                    if (value == 0) continue;
                    reason_result.Add(new { name = keyname, value, increases = Math.Round(value / total * 100, 2) });
                }
                reason_result = reason_result.OrderByDescending(item => item.value).ToList();
            }
            return new APIResult(new { total, data = result, data2 = reason_result });
        }



        [HttpPost]
        public ActionResult settle_bills_total([FromBody] JsonElement form)
        {
            int page = form.Read("current", 1);
            int size = form.Read("pageSize", 10);
            bool getTotal = form.Read("getTotal", true);
            string sort = form.Read<string>("sort");
            string order = form.Read<string>("order");

            var belongTime = form.PathReadArray<string>("query_date[]");

            string filter = string.Empty;
            DateTime stime = DateTime.MinValue, etime = DateTime.MinValue;
            if (belongTime.Count == 2)
            {
                if (DateTime.TryParse(belongTime[0], out stime) && DateTime.TryParse(belongTime[1], out etime))
                {
                    etime = etime.AddDays(1).AddSeconds(-1);
                    filter += $" AND belongTime BETWEEN @stime AND @etime";
                }
            }

            filter = filter.StringTrimStart(" AND ");

            //排序
            string orderBy = "belongTime DESC";
            if (!string.IsNullOrEmpty(order))
            {
                order = "descending".Equals(order) ? "DESC" : "ASC";
                orderBy = sort switch
                {
                    _ => $"{sort} {order}",
                };
            }
            var result = new DBContext.Table("v_tk_report_bills")
                .Where(filter, new { stime, etime })
                .Page(size, page)
                .Order(orderBy)
                .PageList<TkSettleBillDTO>(getTotal);

            return new APIResult(new { data = result });
        }


        [HttpPost]
        public ActionResult settle_bills([FromBody] JsonElement form)
        {
            int page = form.Read("current", 1);
            int size = form.Read("pageSize", 10);
            bool getTotal = form.Read("getTotal", true);
            string sort = form.Read<string>("sort");
            string order = form.Read<string>("order");
            string name = form.Read<string>("keyword");

            var belongTime = form.PathReadArray<string>("query_date[]");

            string filter = string.Empty;
            if (!string.IsNullOrEmpty(name))
            {
                filter += $" AND accountId IN (SELECT ID FROM tk_pool WHERE company=@name)";
            }
            DateTime stime = DateTime.MinValue, etime = DateTime.MinValue;
            if (belongTime.Count == 2)
            {
                if (DateTime.TryParse(belongTime[0], out stime) && DateTime.TryParse(belongTime[1], out etime))
                {
                    etime = etime.AddDays(1).AddSeconds(-1);
                    filter += $" AND belongTime BETWEEN @stime AND @etime";
                }
            }

            filter = filter.StringTrimStart(" AND ");

            //排序
            string orderBy = "belongTime DESC";
            if (!string.IsNullOrEmpty(order))
            {
                order = "descending".Equals(order) ? "DESC" : "ASC";
                orderBy = sort switch
                {
                    _ => $"{sort} {order}",
                };
            }

            var result = new DBContext.Table("tk_settle_bill")
                .Where(filter, new { name, stime, etime })
                .Page(size, page)
                .Order(orderBy)
                .PageList<TkSettleBillDTO>(getTotal);


            //foreach (var item in result.List)
            //{
            //    if (string.IsNullOrEmpty(name))
            //    {
            //        item.accountName = "-";
            //    }
            //}
            return new APIResult(new { data = result });
        }

    }
}