using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using dodohold.core;
using Dataoke;
using Google.Protobuf.WellKnownTypes;
using System.Diagnostics;
using System.Text.Json;
using TencentCloud.Tcm.V20210413.Models;


namespace molilian.core
{
    public partial class DataokeCore
    {
        private static readonly object _lockObj = new();
        private static IEnumerable<DataokeDTO> _cached;
        public static DataokeDTO? GetOne(string domain = "")
        {
            var list = List();
            if (!list.Any()) return null;
            domain = domain.ToLower();
            return list.Where(e => FilterReferer(e, domain)).OrderBy(l => Guid.NewGuid()).FirstOrDefault();
        }

        public static IEnumerable<DataokeDTO> List(bool force = false)
        {
            if (!force && _cached != null) return _cached;

            string cache_key = $"cache:dataoke_pool";
            var list = RedisHelper.Get<IEnumerable<DataokeDTO>>(cache_key);
            if (force || list == null)
            {
                lock (_lockObj)
                {
                    list = new DBContext.Table("dataoke_pool")
                        .Where("status=@status", new { status = 1 })
                        .Select<DataokeDTO>();
                    if (list == null) return default;
                    RedisHelper.Set(cache_key, list, 30 * 86400);
                }
            }
            _cached = list;
            return list;
        }


        private static bool FilterReferer(DataokeDTO item, string domain)
        {
            if (string.IsNullOrEmpty(domain)) return true;
            if (string.IsNullOrEmpty(item.domain)) return true;

            if (domain.Contains(item.domain)) return true;
            return false;
        }



        public static void Refresh()
        {
            _ = List(true);
        }

        public static void Disabled(string name)
        {
            string cache_key = $"cache:dataoke_pool:{name}:disabled";
            long count = RedisHelper.IncrBy(cache_key);
            RedisHelper.Expire(cache_key, 10);
            if (count > 1) return;

            new DBContext.Table("dataoke_pool")
                .Add("status", 0)
                .Where("name=@name", new { name })
                .Update();
            _ = List(true);

            NotifyCore.Notify(new NifyMessage
            {
                message = $"【大淘客:{name}】调用异常",
                priority = NifyMessagePriority.high,
                tags = ["red_circle"]
            });
        }


        public static JdDataDTO JdParse(JdDataDTO result, DataokeDTO api, JdPoolDTO account, string content)
        {
            string message = string.Empty;
            string url = JdUnionPlus.GetLink(content);
            string shortLinkurl = url;

            var plus = new DataokePlus(api.app_key, api.app_secret);
            string body = plus.JDParse(account.unionid, url);

            //result.link_type = plus.IsAffLlink(url) ? LinkTypeEnum.other_aff : LinkTypeEnum.goods;
            result.link_type = JdUnionPlus.GetLinkType(url, out string out_url, out string itemId);
            url = out_url;
            result.itemId = itemId;

            if (result.link_type == LinkTypeEnum.other_aff)
            {
                result.success = false;
                result.link_type = LinkTypeEnum.unknown;
                result.channel_type = ChannelTypeEnum.jd;
                message = "其他推广链接";
                result.accountName = string.Empty;
                result.content = content;
                result.shortLinkurl = url;
                result.deeplink_url = JdUnionPlus.GetDeeplink(null);
            }
            else
            {
                JsonElement root;
                try
                {
                    root = body.Convert2JsonElement();
                }
                catch
                {
                    throw new APIException(body);
                }
                int code = root.Read("code", -1);
                bool success = code == 0;
                if (success)
                {
                    shortLinkurl = root.PathRead("data.shortUrl", string.Empty);
                }
                else
                {
                    message = body;
                }

                result.content = shortLinkurl;
                result.shortLinkurl = shortLinkurl;
                result.success = success;
                result.message = message;
                result.accountName = account.name;

                GoodsDetailDTO goods = null;
                if (success) goods = plus.GetGoods(shortLinkurl);
                result.deeplink_url = JdUnionPlus.GetDeeplink(shortLinkurl);

                if (goods != null)
                {
                    result.itemName = goods.skuName;
                }
            }

            return result;
        }

        public static GoodsDetailDTO? GetCoupon(DataokeDTO api, JdPoolDTO account, string url, string itemId)
        {
            var plus = new DataokePlus(api.app_key, api.app_secret);
            var item = plus.GetDetails([itemId]);
            if (item != null)
            {
                try
                {
                    string body = plus.JDParse(account.unionid, url, item.couponLink);
                    JsonElement root = body.Convert2JsonElement();
                    int code = root.Read("code", -1);
                    if (code != 0) return null;

                    item.couponLink = root.PathRead("data.shortUrl", string.Empty);
                }
                catch
                {
                    return null;
                }
            }
            return item;
        }

    }
}
