using dodohold.core;
using Microsoft.AspNetCore.Mvc;
using molilian.core;
using MySqlX.XDevAPI;
using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
using System.Net;
using System.Text.Json;
using System.Xml.Linq;
using TencentCloud.Mrs.V20200910.Models;
using WebSocketSharp.Net;
using static QRCoder.PayloadGenerator;
namespace molilian.api.Controllers
{


    [ApiController]
    [MyAuthorize("admin")]
    [Route("api/[controller]/[action]")]
    public class PddUnionController : ControllerBase
    {
        readonly IAuthorizationProvider provider = new AdminProvider();
        protected IHttpContextAccessor _accessor;
        public PddUnionController(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);
            int id = form.Read<int>("id", 0);
            cookie = cookie.Replace("\r", "").Replace("\n", "").Trim();
            if (!cookie.EndsWith(";")) cookie += ";";

            var accountId = await PddPoolCore.UpdateCookies(cookie, user_agent, id);
            bool success = accountId > 0;
            if (success)
            {
                OperationLogCore.LogOperation(token.AccessKey, clientIp, $"pdd_pool:{accountId}:cookie", string.Empty, cookie);
            }
            return new APIResult(new
            {
                data = new { success, msg = success ? "更新成功" : "更新失败，请检查输入的cookie" },
            });
        }

        /// <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");

            bool show_hide = form.Read("show_hide", false);
            string filter = string.Empty;
            if (!show_hide) filter = "is_hide=0";
            if (!string.IsNullOrEmpty(keyword))
            {
                filter += $" AND (`name` LIKE @keyword OR `duoId` LIKE @keyword OR `pid` LIKE @keyword OR `nodename` LIKE @keyword OR `company` 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}, id DESC",
                };
            }

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

            var proxyNodes = (ProxyNodesCore.AllList() ?? Array.Empty<ProxyNodesDTO>())
                .ToList();

            foreach (var item in result.List)
            {
                item.app_secret = string.Empty;
                item.cookies = string.Empty;
                item.riskCookie = RiskControlCore.GetRiskCookie($"pdd:{item.id}");
                item.proxyStatus = proxyNodes
                    .FirstOrDefault(proxyNode =>
                        ProxyNodesCore.IsMatchNode(proxyNode, item.nodeName))
                    ?.status;
            }
            return new APIResult(new { data = result });
        }

        [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_parse":
                case "enable_sync_revenue":
                case "enable_sync_order":
                case "enable_coupon":
                case "cookie_status":
                case "status":
                    bool bVal = val.Equals("True");
                    result = new DBContext.Table("pdd_pool")
                           .Add(name, bVal)
                           .Add("last_time", DateTime.Now)
                           .Where("id=@id", new { id })
                           .Update();

                    if (bVal && ("status".Equals(name) || "enable_parse".Equals(name)))
                    {
                        PddPoolCore.InitializeNewAccountUsage(id);
                    }
                    break;
                case "time_range":
                    int.TryParse(val, out int iVal);
                    result = new DBContext.Table("pdd_pool")
                           .Add(name, iVal)
                           .Add("last_time", DateTime.Now)
                           .Where("id=@id", new { id })
                           .Update();
                    break;
                case "balance":
                    // todo 更新账户余额
                    var account = new DBContext.Table("pdd_pool").Get<PddPoolDTO>("id=@id", new { id });
                    var plus = new PddUnionPlus(account);
                    result = await plus.queryMallBalance();
                    break;
                default:
                    return new APIResult(new { data = new { success = false, msg = "更新失败，未授权操作" } });
            }
            bool success = result > 0;
            if (success)
            {
                OperationLogCore.LogOperation(token.AccessKey, clientIp, $"pdd_pool:{id}:{name}", string.Empty, val);
                await EndPointCore.NotifyReload(true);
            }
            return new APIResult(new
            {
                data = new { success, msg = success ? "更新成功" : "更新失败，请检查输入信息" },
            });
        }

        [HttpPost]
        public ActionResult estimate_revenue_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 report_date = form.PathReadArray<string>("query_date[]");

            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 report_date BETWEEN @stime AND @etime";
                }
            }

            filter = filter.StringTrimStart(" AND ");

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

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


        [HttpGet]
        public ActionResult RechargeAllOnlineAccountUsage()
        {
            int count = PddPoolCore.RechargeAllOnlineAccountUsage();
            return new APIResult(new { msg = "ok", count });
        }


        [HttpPost]
        public ActionResult estimate_revenue([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 report_date = form.PathReadArray<string>("query_date[]");

            string filter = string.Empty;
            if (!string.IsNullOrEmpty(name))
            {
                filter += $" AND accountId IN (SELECT ID FROM pdd_pool WHERE company=@name AND is_hide=0)";
            }
            else
            {
                filter += $" AND accountId IN (SELECT ID FROM pdd_pool WHERE is_hide=0)";
            }

            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 = "report_date DESC";
            if (!string.IsNullOrEmpty(order))
            {
                order = "descending".Equals(order) ? "DESC" : "ASC";
                orderBy = sort switch
                {
                    _ => $"{sort} {order}",
                };
            }

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

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

    }
}
