using molilian.core;
using dodohold.core;
using Microsoft.AspNetCore.Mvc;
using Org.BouncyCastle.Ocsp;
using System.Text.Json;
using System.Runtime.InteropServices;
using System.Net;
using System.Security.Cryptography;
using Microsoft.AspNetCore.Authentication;
using TencentCloud.Ecm.V20190719.Models;
using COSXML.Network;
using System.Linq;
using static dodohold.core.ZTOExpress.CreateOrderArgs;
using MySqlX.XDevAPI;
using TencentCloud.Ame.V20190916.Models;

namespace molilian.api.Controllers
{
    [ApiController]
    [Route("[controller]/[action]")]
    public class TkController : ControllerBase
    {

        protected IHttpContextAccessor _accessor;
        public TkController(IHttpContextAccessor accessor)
        {
            _accessor = accessor;
        }


        /// <summary>
        /// oppo调用
        /// </summary>
        /// <param name="s">正文</param>
        /// <param name="c">渠道。tb/jd</param>
        /// <param name="a">分配的客户端账号</param>
        /// <param name="t">11位时间戳</param>
        /// <param name="sign">签名</param>
        /// <param name="ip">客户的IP</param>
        /// <param name="oaid">客户的唯一ID</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> unionParse([FromBody] JsonElement form, [FromQuery] string a = "", [FromQuery] int t = 0, [FromQuery] string sign = "")
        {
            //正文
            var content = form.Read("s", string.Empty);
            var channel = form.Read("c", string.Empty);
            var ip = form.Read("ip", string.Empty);
            var oaid = form.Read("oaid", string.Empty);


            //验证签名
            if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(sign))
            {
                return new APIResult(new { success = false, message = "验证错误" }, APIResultCodeEnum.Unauthorized);
            }

            DateTime time1 = t.Convert2Datetime();
            if (time1 < DateTime.Now.AddMinutes(-10))
            {
                return new APIResult(new { success = false, message = "验证错误2" }, APIResultCodeEnum.Unauthorized);
            }

            var account = ApiAccountCore.GetOne(a);
            if (account == null)
            {
                return new APIResult(new { success = false, message = "验证错误3" }, APIResultCodeEnum.Unauthorized);
            }
            string app_sign = $"{account.api_secret}@{t}".MD5();
            if (sign != app_sign)
            {
                return new APIResult(new { success = false, message = "验证错误4" }, APIResultCodeEnum.Unauthorized);
            }
            return await UnionParseCore.UnionParseAsync(content, channel, ip, oaid);
        }

        [HttpPost]
        public async Task<ActionResult> unsafeParse([FromBody] JsonElement form)
        {
            var content = form.Read("s", string.Empty);
            var channel = form.Read("c", string.Empty);
            var ip = form.Read("ip", string.Empty);
            var oaid = form.Read("oaid", string.Empty);
            int accountid = form.Read("aid", 0);
#if DEBUG
            ip = "127.0.0.1";
            oaid = "test-oaid";
#endif
            return await UnionParseCore.UnionParseAsync(content, channel, ip, oaid, accountid);
        } 

        [HttpGet]
        public async Task<ActionResult> tesjd(int aid, int num = 100)
        {
            var channel = "jd";
            string ip = "127.0.0.1";
            string oaid = "test-oaid";

            var list = new DBContext.Table("jd_parse_logs_success").Order("RAND()").Limit(num).Select<dynamic>();
            foreach (var item in list)
            {
                await UnionParseCore.UnionParseAsync(item.rawContent, channel, ip, oaid, aid);
            }
            return new APIResult(new { success = true, message = "ok" });
        }

        [HttpGet]
        public async Task<ActionResult> tespdd(int aid, int num = 10, int time = 10)
        {
            var channel = "pdd";
            string ip = "127.0.0.1";
            string oaid = "test-oaid";

            long[] ids = [202388161458,
637136869820,
437298318944,
450267426247,
539858704020,
454418994546,
333101893158,
548124555533,
536810064160,
394420905274,
265854971073,
470187982089,
460166587606,
606201132000,
636576970817,
503020436844,
64075414938,
564823147084,
400331744081,
549023673392,
510533263139,
426302139303,
606182099388,
592309700176,
509945035718,
536810064160,
562434609588,
210550635424,
602689684700,
394649770525,
295709990348,
241991260035,
310685408148,
636576970817,
335033136305,
629347481399,
437298318944,
524348092851,
484213318266,
397252362715,
6326358156,
450204411089,
616697299054,
602623733449,
549023673392,
367065511257,
605812755181,
562434609588,
265854971073,
476300076415];

            for (int i = 0; i <= time; i++)
            {
                for (int j = 0; j <= num; j++)
                {
                    long currentId = ids[j % ids.Length];
                    string content = $"https://mobile.yangkeduo.com/goods.html?goods_id={currentId}";
                    _ = UnionParseCore.UnionParseAsync(content, channel, ip, oaid, aid);
                }
                Thread.Sleep(1000);
            }
            return new APIResult(new { success = true, message = "ok" });

        }



        [HttpPost]
        public async Task<ActionResult> unionCoupon([FromBody] JsonElement form, [FromQuery] string a = "", [FromQuery] int t = 0, [FromQuery] string sign = "")
        {
            //正文
            var content = form.Read("s", string.Empty);
            var dplink = form.Read("dp", string.Empty);
            var channel = form.Read("c", string.Empty);
            var ip = form.Read("ip", string.Empty);
            var oaid = form.Read("oaid", string.Empty);

            //验证签名
            if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(sign))
            {
                return new APIResult(new { success = false, message = "验证错误" }, APIResultCodeEnum.Unauthorized);
            }

            DateTime time1 = t.Convert2Datetime();
            if (time1 < DateTime.Now.AddMinutes(-10))
            {
                return new APIResult(new { success = false, message = "验证错误2" }, APIResultCodeEnum.Unauthorized);
            }

            var account = ApiAccountCore.GetOne(a);
            if (account == null)
            {
                return new APIResult(new { success = false, message = "验证错误3" }, APIResultCodeEnum.Unauthorized);
            }
            string app_sign = $"{account.api_secret}@{t}".MD5();
            if (sign != app_sign)
            {
                return new APIResult(new { success = false, message = "验证错误4" }, APIResultCodeEnum.Unauthorized);
            }
            return await UnionCouponCore.UnionCouponAsync(content, dplink, channel, ip, oaid);
        }


        [HttpPost]
        public async Task<ActionResult> unsafeCoupon([FromBody] JsonElement form)
        {
            var content = form.Read("s", string.Empty);
            var dplink = form.Read("dp", string.Empty);
            var channel = form.Read("c", string.Empty);
            var ip = form.Read("ip", string.Empty);
            var oaid = form.Read("oaid", string.Empty);
#if DEBUG
            ip = "127.0.0.1";
            oaid = "test-oaid";
#endif
            return await UnionCouponCore.UnionCouponAsync(content, dplink, channel, ip, oaid);
        }

        /// <summary>
        /// 第三方调用
        /// </summary>
        /// <param name="s"></param>
        /// <param name="s2"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ActionResult> parse(string s, string s2 = "", string ip = "", string oaid = "")
        {
            AlimamaPlus alimama = null;
            ip = AlimamaPlus.OppoDecode(ip);
            oaid = AlimamaPlus.OppoDecode(oaid);
            var result = AlimamaPlus.GetFormattedObject(s, ip, oaid);
            string body = "";
            string content = s.UrlDecode();
            string content2 = s2.UrlDecode();
            string account_name = string.Empty;
            result.rawContent = content;
            result.rawContent2 = content2;

            try
            {
                if (AlimamaPlus.ShouldIgnoreRequest(ip, oaid, out string reason))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = reason;
                    _ = TkLogCore.LogAsync(result);
                    return new APIResult(new
                    {
                        result.success,
                        result.message,
                        result.content,
                        result.couponAmount,
                        result.taoToken,
                        result.shortLinkurl,
                        result.deeplink_url,
                    });
                }

                var account = TkPoolCore.GetOne(TkPoolCore.TkAction.parse);
                if (account == null)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "没有匹配账号";
                    _ = TkLogCore.LogAsync(result);
                    return new APIResult(new
                    {
                        result.success,
                        result.message,
                        result.content,
                        result.couponAmount,
                        result.taoToken,
                        result.shortLinkurl,
                        result.deeplink_url,
                    });
                }

                result.accountId = account.id;
                result.accountName = account.company;
                account_name = account.name;
                alimama = new AlimamaPlus(account);

                if (alimama.ShouldIgnoreOtherAff(s2))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "其他推广链接";
                    _ = TkLogCore.LogAsync(result);
                    return new APIResult(new
                    {
                        result.success,
                        result.message,
                        result.content,
                        result.couponAmount,
                        result.taoToken,
                        result.shortLinkurl,
                        result.deeplink_url,
                    });

                }
                result = await alimama.UnionParseAsync(content, result);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("was canceled"))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "请求超时";
                }
                else
                {
                    //new LoggerLibrary("api_error", "parse")
                    //.Info(s, s2)
                    //.Info($"【taobao】{account_name}", body)
                    //.Info(ex.Message, ex.StackTrace)
                    //.SaveAsync();
                    NotifyCore.Notify(new NifyMessage
                    {
                        message = $"【转链接口异常】{result.accountName}\n{content}\n{content2}\n{body}\n\n{ex.Message}\n{ex.StackTrace}",
                        priority = NifyMessagePriority.high,
                        tags = ["red_circle"]
                    });
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "转链接口异常";
                }
            }

            _ = TkLogCore.LogAsync(result, alimama);
            return new APIResult(new
            {
                result.success,
                result.message,
                result.content,
                result.couponAmount,
                result.taoToken,
                result.shortLinkurl,
                result.deeplink_url,
            });
        }

        [HttpGet]
        public ActionResult parse2(string s, string s2 = "", string ip = "", string oaid = "")
        {
            AlimamaPlus alimama = null;
            ip = AlimamaPlus.OppoDecode(ip);
            oaid = AlimamaPlus.OppoDecode(oaid);
            var result = AlimamaPlus.GetFormattedObject(s, ip, oaid);
            string body = "";
            string content = s.UrlDecode();
            string content2 = s2.UrlDecode();
            string account_name = string.Empty;
            result.rawContent = content;
            result.rawContent2 = content2;

            try
            {
                if (AlimamaPlus.ShouldIgnoreRequest(ip, oaid, out string reason))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = reason;
                    _ = TkLogCore.LogAsync(result);
                    return new APIResult(new
                    {
                        result.success,
                        result.message,
                        result.content,
                        result.couponAmount,
                        result.taoToken,
                        result.shortLinkurl,
                        result.deeplink_url,
                    });
                }

                var account = TkPoolCore.GetOne(TkPoolCore.TkAction.parse);
                if (account == null)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "没有匹配账号";
                    _ = TkLogCore.LogAsync(result);
                    return new APIResult(new
                    {
                        result.success,
                        result.message,
                        result.content,
                        result.couponAmount,
                        result.taoToken,
                        result.shortLinkurl,
                        result.deeplink_url,
                    });
                }

                account_name = account.name;
                alimama = new AlimamaPlus(account);

                if (alimama.ShouldIgnoreOtherAff(s2))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "其他推广链接";
                    _ = TkLogCore.LogAsync(result);
                    return new APIResult(new
                    {
                        result.success,
                        result.message,
                        result.content,
                        result.couponAmount,
                        result.taoToken,
                        result.shortLinkurl,
                        result.deeplink_url,
                    });

                }
                alimama.UnionParse(content, ref result);
                //result.ip = ip;
                //result.oaid = oaid;

            }
            catch (Exception ex)
            {
                _ = new LoggerLibrary("api_error", "parse")
                    .Info(s, s2)
                    .Info($"【taobao】{account_name}", body)
                    .Info(ex.Message, ex.StackTrace)
                    .SaveAsync();
                NotifyCore.Notify(new NifyMessage
                {
                    message = $"【转链接口异常】{account_name}\n{content}\n{content2}\n{body}\n\n{ex.Message}\n{ex.StackTrace}",
                    priority = NifyMessagePriority.high,
                    tags = ["red_circle"]
                });
                result.success = false;
                result.message = "放弃转链";
                result.reason = "转链接口异常";
            }

            _ = TkLogCore.LogAsync(result, alimama);
            return new APIResult(new
            {
                result.success,
                result.message,
                result.content,
                result.couponAmount,
                result.taoToken,
                result.shortLinkurl,
                result.deeplink_url,
            });
        }


        [HttpGet]
        public ActionResult jd_parse(string s, string s2 = "", string ip = "", string oaid = "")
        {
            var result = JdUnionPlus.GetFormattedObject(s, ip, oaid);
            string body = "";
            string content = s.UrlDecode();
            string content2 = s2.UrlDecode();
            try
            {
                if (AlimamaPlus.ShouldIgnoreRequest(ip, oaid, out string reason))
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = reason;
                    result.rawContent = content;
                    result.rawContent2 = content2;
                    _ = TkLogCore.LogAsync(result);
                    return new APIResult(result);
                }

                var api = DataokeCore.GetOne();
                if (api == null)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "没有匹配账号";
                    result.rawContent = content;
                    result.rawContent2 = content2;
                    _ = TkLogCore.LogAsync(result);
                    return new APIResult(result);
                }

                var account = JdPoolCore.GetOne();
                if (account == null)
                {
                    result.success = false;
                    result.message = "放弃转链";
                    result.reason = "没有匹配账号";
                    result.rawContent = content;
                    result.rawContent2 = content2;
                    _ = TkLogCore.LogAsync(result);
                    return new APIResult(result);
                }
                result = DataokeCore.JdParse(result, api, account, content);
            }
            catch (Exception ex)
            {

                _ = new LoggerLibrary("api_error")
                    .Info(s, s2)
                    .Info("【jd】", body)
                    .Info(ex.Message, ex.StackTrace)
                    .SaveAsync();
                NotifyCore.Notify(new NifyMessage
                {
                    message = $"【转链接口异常】\n{content}\n{content2}\n{body}\n\n{ex.Message}\n{ex.StackTrace}",
                    priority = NifyMessagePriority.high,
                    tags = ["red_circle"]
                });
                result.success = false;
                result.message = "放弃转链";
                result.reason = "转链接口异常";
            }
            result.rawContent = content;
            result.rawContent2 = content2;
            _ = TkLogCore.LogAsync(result);
            return new APIResult(new
            {
                result.success,
                result.message,
                result.shortLinkurl,
                result.itemId,
                result.itemName,
                result.deeplink_url,
            });
        }


        [HttpGet]
        public async Task<ActionResult> Reload()
        {
            await EndPointCore.NotifyReload();
            return new APIResult(new
            {
                success = true,
                message = "ok",
            });
        }

        [HttpGet]
        public async Task<ActionResult> dplist([FromQuery] string query = "", [FromQuery] string a = "", [FromQuery] int t = 0, [FromQuery] string sign = "")
        {
#if DEBUG

#else
            //验证签名
            if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(sign))
            {
                return new APIResult(new { success = false, message = "验证错误" }, APIResultCodeEnum.Unauthorized);
            }

            DateTime time1 = t.Convert2Datetime();
            if (time1 < DateTime.Now.AddMinutes(-10))
            {
                return new APIResult(new { success = false, message = "验证错误2" }, APIResultCodeEnum.Unauthorized);
            }

            var account = ApiAccountCore.GetOne(a);
            if (account == null)
            {
                return new APIResult(new { success = false, message = "验证错误3" }, APIResultCodeEnum.Unauthorized);
            }
            string app_sign = $"{account.api_secret}@{t}".MD5();
            if (sign != app_sign)
            {
                return new APIResult(new { success = false, message = "验证错误4" }, APIResultCodeEnum.Unauthorized);
            }

            if (string.IsNullOrEmpty(query))
            {
                return new APIResult(new { success = false, message = "查询条件不能为空" });
            }
#endif
            string filter = $"batchId=@query";
            var account_list = TkPoolCore.List();
            List<int> account_ids = [];
            if (account_list.Any())
            {
                account_ids = account_list.Where(e => e.enable_fake_click).Select(e => e.id).ToList();
                filter += $" AND accountId IN @account_ids";
            }
            string orderBy = "paid_time ASC";

            var data = new DBContext.Table("tk_order_tracking")
                .Where(filter, new { query, account_ids })
                .Order(orderBy)
                .Select<TkOrderTrackingDTO>();

            //fake_click_link_type


            List<object> list = [];
            foreach (var item in data)
            {
                list.Add(new { pid = item.accountId, url = item.deeplinkUrl, item.shortLinkUrl, count = item.click_num, time = item.exp_time });
            }
            var clientIp = _accessor.HttpContext.GetUserIp();
            LoggerLibrary log = new LoggerLibrary("api", "dplist");
            log.Info($"{clientIp}\t{query}\tcount:{list.Count}");

            var ids = data.Select(e => e.Id).ToArray();
            log.Info(string.Join(',', ids));
            _ = log.SaveAsync();

            var update = new DBContext.Table("tk_order_tracking")
                .Add("clicked_num:", "clicked_num+1")
                .Where("id IN @ids", new { ids })
                .Update();

            return new APIResult(new
            {
                success = true,
                message = list.Count == 0 ? "none" : "ok",
                count = list.Count,
                data = list,
            });
        }


        [HttpGet]
        public async Task<ActionResult> unsafeParseDpList([FromQuery] string query = "")
        {
            string filter = $"batchId=@query";
            var account_list = TkPoolCore.List();
            List<int> account_ids = [];
            if (account_list.Any())
            {
                account_ids = account_list.Where(e => e.enable_fake_click).Select(e => e.id).ToList();
                filter += $" AND accountId IN @account_ids";
            }
            string orderBy = "paid_time ASC";

            var data = new DBContext.Table("tk_order_tracking")
                .Where(filter, new { query, account_ids })
                .Order(orderBy)
                .Select<TkOrderTrackingDTO>();

            List<object> list = [];
            foreach (var item in data)
            {
                list.Add(new { pid = item.accountId, url = item.deeplinkUrl, item.shortLinkUrl, count = item.click_num, time = item.exp_time });
            }
            var clientIp = _accessor.HttpContext.GetUserIp();
            LoggerLibrary log = new LoggerLibrary("api", "unsafeParseDpList");
            log.Info($"{clientIp}\t{query}\tcount:{list.Count}");

            var ids = data.Select(e => e.Id).ToArray();
            log.Info(string.Join(',', ids));
            _ = log.SaveAsync();

            return new APIResult(new
            {
                success = true,
                message = list.Count == 0 ? "none" : "ok",
                count = list.Count,
                data = list,
            });
        }



        [HttpPost]
        public async Task<ActionResult> dataReport([FromBody] JsonElement form, [FromQuery] string a = "", [FromQuery] int t = 0, [FromQuery] string sign = "")
        {
            bool debug = form.Read("debug", false);
            var clientIp = _accessor.HttpContext.GetUserIp();
            var log = new LoggerLibrary("ApiReportCore", "dataReport");
            log.Info(clientIp);

            //验证签名
            if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(sign))
            {
                _ = log.Info($"a:{a}\tt:{t}\tsign:{sign}\t", $"message:验证错误")
                    .Info(form.GetRawText())
                    .SaveAsync();
                return new APIResult(new { success = false, message = "验证错误" }, APIResultCodeEnum.Unauthorized);
            }

            DateTime time1 = t.Convert2Datetime();
            if (time1 < DateTime.Now.AddMinutes(-10))
            {
                _ = log.Info($"a:{a}\tt:{t}\tsign:{sign}\t", $"message:验证错误2")
                    .Info(form.GetRawText())
                    .SaveAsync();
                return new APIResult(new { success = false, message = "验证错误2" }, APIResultCodeEnum.Unauthorized);
            }

            var account = ApiAccountCore.GetOne(a);
            if (account == null || !account.enable_report)
            {
                _ = log.Info($"a:{a}\tt:{t}\tsign:{sign}\t", $"message:验证错误3")
                    .Info(form.GetRawText())
                    .SaveAsync();
                return new APIResult(new { success = false, message = "验证错误3" }, APIResultCodeEnum.Unauthorized);
            }
            string app_sign = $"{account.api_secret}@{t}".MD5();
            if (sign != app_sign)
            {
                _ = log.Info($"a:{a}\tt:{t}\tsign:{sign}\tapp_sign:{app_sign}", $"message:验证错误4")
                    .Info(form.GetRawText())
                    .SaveAsync();
                return new APIResult(new { success = false, message = "验证错误4" }, APIResultCodeEnum.Unauthorized);
            }

            try
            {
                var data = await ApiReportCore.ReportDailysAsync(form, clientIp, debug);
                _ = log.Info(form.GetRawText(), data.Convert2Json()).SaveAsync();
                return new APIResult(new { success = true, data });
            }
            catch (Exception ex)
            {
                _ = log.Info(form.GetRawText()).Info(ex.Message, ex.StackTrace).SaveAsync();
                return new APIResult(new { success = false, message = "内部错误" });
            }
        }


        [HttpPost]
        public async Task<ActionResult> unsafeDataReport([FromBody] JsonElement form)
        {
            bool debug = form.Read("debug", false);
            var clientIp = _accessor.HttpContext.GetUserIp();
            var log = new LoggerLibrary("ApiReportCore", "unsafeDataReport");
            log.Info(clientIp);

            try
            {
                var data = await ApiReportCore.ReportDailysAsync(form, clientIp, debug);
                _ = log.Info(form.GetRawText(), data.Convert2Json()).SaveAsync();
                return new APIResult(new { success = true, data });
            }
            catch (Exception ex)
            {
                _ = log.Info(form.GetRawText()).Info(ex.Message, ex.StackTrace).SaveAsync();
                return new APIResult(new { success = false, message = "内部错误" });
            }
        }

    }
}