using Elasticsearch.Net;
using JiaZhiQuan.Common.ElasticSearch;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Senparc.Weixin.MP.Containers;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Wicture.DbRESTFul;
using Wicture.DbRESTFul.Cache;
using Wicture.DbRESTFul.Infrastructure.Repository;

namespace JiaZhiQuan.Common
{
    public static partial class RepositoryExtension
    {


        /// <summary>
        /// 先获取用户的前100标签，如果超过50个，则随机取30个
        /// </summary>
        public async static Task<List<string>> GetUserTags(this DbRESTFulRepository repository, RedisCacheProvider cacheProvider, long userId, IDbConnection conn = null)
        {
            if (userId == 0) return new List<string>();
            List<string> tags;
            // 先从Redis中尝试获取
            var key = CacheKeys.UserTags(userId);
            if (await cacheProvider.KeyExist(key))
            {
                tags = (await cacheProvider.Get<List<string>>(key)) ?? new List<string>();
            }
            else
            {
                // 从数据库获取
                var records = await repository.QueryAsync<UserTagModel>($"select createDate, `tag`, `count` from n_user_tags_records where userId={userId} order by createDate desc, `count` desc limit 100", null, conn);
                var now = DateTime.Now;
                var dic = new Dictionary<string, double>();
                records.ForEach(e =>
                {
                    var days = Math.Ceiling((now - e.createDate).TotalDays);
                    if (days <= 0) days = 1;
                    e.hot = (e.count + 1) / Math.Pow(days, 1.5);
                    if (dic.ContainsKey(e.tag))
                    {
                        dic[e.tag] += e.hot;
                    }
                    else
                    {
                        dic[e.tag] = e.hot;
                    }
                });
                tags = dic.OrderByDescending(e => e.Value).Select(e => e.Key).ToList();
                var size = 10;
                if (tags.Count > size)
                {
                    tags = tags.Take(size).ToList();
                }
                await cacheProvider.Set(key, tags, CacheKeys.UserTagsCacheSecs);
            }
            //if (tags.Count > 50)
            //{
            //    tags.Shuffle();
            //    tags = tags.Take(30).ToList();
            //}
            return tags;
        }


        /// <summary>
        /// 获取用户App上展示的标签列表
        /// </summary>
        public static List<string> GetUserPublicTags(this DbRESTFulRepository repository, int mpRole, int superior, string job, int jobHidden)
        {
            var tags = new List<string>();
            if (mpRole > 0 && superior > 0)
            {
                tags.Add("优质创作者");
            }
            if (!string.IsNullOrEmpty(job) && jobHidden == 0)
            {
                tags.Add(job);
            }
            return tags;
        }

        public async static Task UpdateUserPublicTags(this DbRESTFulRepository repository, long userId, IDbConnection conn = null, IDbTransaction trans = null)
        {
            var info = await repository.QuerySingleOrDefaultAsync<dynamic>($"select mpRole, superior, job, jobHidden from n_user where id={userId}", null, conn, trans);
            if (info != null)
            {
                var tags = GetUserPublicTags(repository, (int)info.mpRole, (int)info.superior, (string)info.job, (int)info.jobHidden);
                await repository.QueryAsync<dynamic>($"update n_user set publicTags=@tags where id={userId}", new { tags = string.Join('\n', tags) }, conn, trans, false);
            }
        }
    }

}
