using dodohold.core;
using Sayaka.Common;


namespace molilian.core
{
    public partial class JdUnionPlus
    {

        public class EstimateCommDTO
        {
            public int id { get; set; } = 0;
            public int accountId { get; set; } = 0;
            public string accountName { get; set; } = string.Empty;
            public DateTime report_date { get; set; } = DateTime.MinValue;
            public DateTime create_time { get; set; } = DateTime.Now;
            public DateTime last_time { get; set; } = DateTime.MinValue;


            public decimal cosFee { get; set; }
            public int downloadDetail { get; set; }
            public int feeType { get; set; }
            public string feeTypeStr { get; set; } = string.Empty;
            public string payMonth { get; set; } = string.Empty;
            public int platform { get; set; }
            public string platformStr { get; set; } = string.Empty;
            public int showDetail { get; set; }
            public int status { get; set; }
            public int unionType { get; set; }
            public string unionTypeStr { get; set; } = string.Empty;
        }


        public async Task<List<DateTime>> queryEstimateCommList(CancellationToken cancellationToken = default)
        {
            List<DateTime> changed_dates = new List<DateTime>();

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

            string useragent = _account.user_agent;
            if (string.IsNullOrEmpty(useragent)) useragent = ProviderFakeUserAgent.RandomComputer;

            bool hasNext = true;
            int pageNo = 1;
            while (hasNext)
            {
                var args = new
                {
                    funName = "queryEstimateCommList",
                    param = new
                    {
                        startTime = "",
                        endTime = "",
                        unionType = "",
                        status = "",
                        pageNo,
                        pageSize = 20
                    },
                    //,"param":{"endTime":"","startTime":"","unionType":"","status":null,"pageNo":1,"pageSize":20}}

                };

                string data = args.Convert2Json().UrlEncode();
                string url = $"https://api.m.jd.com/api?functionId=union_balance_service&appid=unionpc&loginType=3&body={data}";

                WebClientUtility client = new WebClientUtility();
                client.Proxy = _proxy;
#if DEBUG
                client.Proxy = null;
#endif
                client.SetContentType("application/x-www-form-urlencoded");
                client.AddHeaders("X-Referer-Page", "https://union.jd.com/proManager/index");
                client.AddHeaders("X-Rp-Client", "h5_1.0.0");
                client.AddHeaders("Referer", "https://union.jd.com/");
                client.AddHeaders("Origin", "https://union.jd.com");
                client.UserAgent = useragent;
                client.AddHeaders("Cookie", cookies);
                client.Post($"body={data}");
                DateTime stime = DateTime.Now;
                var response = await client.RequestAsync(url, "POST", cancellationToken);
                TimeSpan ts2 = DateTime.Now - stime;
                string xx = ts2.TotalSeconds.ToString();

                string body = response.Body();
                var root = body.Convert2JsonElement();
                int code = root.Read<int>("code");
                string message = root.Read<string>("message");
                hasNext = root.Read<bool>("hasNext", false);
                pageNo++;
                if (code == 200 && "success".Equals(message))
                {
                    var list = root.ElementRead("result");
                    string filter = "report_date=@report_date AND accountId=@accountId" +
                        " AND unionType=@unionType AND feeType=@feeType AND platform=@platform";

                    foreach (var item in list.EnumerateArray())
                    {
                        var report = item.GetRawText().Convert2Object<EstimateCommDTO>();

                        if (DateTime.TryParseExact(report.payMonth, "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out DateTime report_date))
                        {
                            changed_dates.Add(report_date.Date);

                            var exist = new DBContext.Table("jd_estimate_comm")
                                .Fields("id")
                                .Get<dynamic>(filter,
                                    new
                                    {
                                        report_date = report_date.Date,
                                        accountId = _account.id,
                                        report.unionType,
                                        report.feeType,
                                        report.platform
                                    }
                                    );


                            var update = new DBContext.Table("jd_estimate_comm")
                                .Add("accountId", _account.id)
                                .Add("accountName", _account.name)
                                .Add("cosFee", report.cosFee)
                                .Add("feeType", report.feeType)
                                .Add("feeTypeStr", report.feeTypeStr)
                                .Add("platform", report.platform)
                                .Add("platformStr", report.platformStr)
                                .Add("status", report.status)
                                .Add("unionType", report.unionType)
                                .Add("unionTypeStr", report.unionTypeStr)
                                .Add("last_time", DateTime.Now);

                            if (exist == null)
                            {
                                update.Add("report_date", report_date.Date)
                                .Add("create_time", DateTime.Now)
                                .Create(DBContext.InsertType.REPLACE);
                            }
                            else
                            {
                                update.Where("id=@id", new { exist.id }).Update();
                            }
                        }
                    }

                }
                else
                {
                    throw new APIException(body);
                }
            }
            return changed_dates;
        }

    }
}
