using JiaZhiQuan.Common.Models.CacheModel;
using static JiaZhiQuan.Common.UserGrow;
using System.Collections.Generic;
using System.Threading.Tasks;
using System;
using Wicture.DbRESTFul.Cache;
using Wicture.DbRESTFul.Infrastructure.Repository;
using Wicture.DbRESTFul;
using JiaZhiQuan.Common.Messaging;
using Microsoft.VisualBasic;
using static JiaZhiQuan.Common.Models.GrowModel.GrowthRepositoryModel;
using JiaZhiQuan.Common.Models.PO;
using NPOI.XWPF.UserModel;
using CSRedis;

namespace JiaZhiQuan.Common
{
    public static partial class RepositoryExtension
    {
        /// <summary>
        /// 首次完善资料至100%
        /// </summary>
        /// <returns></returns>
        private static async Task CompleteSelfDataTask(DbRESTFulRepository repository, long userId, DateTime completeTime)
        {
            //插入并更新
            OnceTaskLog onceTaskLog = new OnceTaskLog() { userId = userId, completeSelfDataTime = completeTime, now = DateTime.Now };
            await repository.QuerySingleOrDefaultAsync<dynamic>(@$" insert into n_user_grow_once_task_log 
                    (userId,completeSelfDataTime,createAt,updateAt) values(@userId,@completeSelfDataTime,@now,@now)
                   ON DUPLICATE KEY UPDATE completeSelfDataTime= @completeSelfDataTime,updateAt=@now ", onceTaskLog);
        }
        /// <summary>
        /// 首次完成实名认证
        /// </summary>
        /// <returns></returns>
        private static async Task RealNameAuth(DbRESTFulRepository repository, long userId, DateTime completeTime)
        {
            OnceTaskLog onceTaskLog = new OnceTaskLog() { userId = userId, realNameAuthTime = completeTime, now = DateTime.Now };
            await repository.QuerySingleOrDefaultAsync<dynamic>(@$" insert into n_user_grow_once_task_log 
                    (userId,realNameAuthTime,createAt,updateAt) values(@userId,@realNameAuthTime,@now,@now)
                   ON DUPLICATE KEY UPDATE realNameAuthTime= @realNameAuthTime,updateAt=@now ", onceTaskLog);
        }
        /// <summary>
        /// 首次通过创作者认证或优质创作者认证
        /// </summary>
        /// <returns></returns>
        private static async Task AuthorAuth(DbRESTFulRepository repository, long userId, DateTime completeTime)
        {
            OnceTaskLog onceTaskLog = new OnceTaskLog() { userId = userId, authorAuthTime = completeTime, now = DateTime.Now };
            await repository.QuerySingleOrDefaultAsync<dynamic>(@$" insert into n_user_grow_once_task_log 
                    (userId,authorAuthTime,createAt,updateAt) values(@userId,@authorAuthTime,@now,@now)
                   ON DUPLICATE KEY UPDATE authorAuthTime= @authorAuthTime,updateAt=@now ", onceTaskLog);
        }
        /// <summary>
        /// 申请提现一次
        /// </summary>
        /// <returns></returns>
        private static async Task Withdrawal(DbRESTFulRepository repository, long userId, DateTime completeTime)
        {
            string objStr = "withdrawalTime";
            //插入并更新,看看这种写法有没有问题。
            OnceTaskLog onceTaskLog = new OnceTaskLog() { userId = userId, withdrawalTime = completeTime, now = DateTime.Now };
            await repository.QuerySingleOrDefaultAsync<dynamic>(@$" insert into n_user_grow_once_task_log 
                    (userId,{objStr},createAt,updateAt) values(@userId,@{objStr},@now,@now)
                   ON DUPLICATE KEY UPDATE {objStr}= @{objStr} ,updateAt=@now ", onceTaskLog);
        }

        public static async Task<TaskCompleteResult> DoOnceTask(this DbRESTFulRepository repository, long userId, Dictionary<string, object> data,
            TaskEvent taskEvent, Producer producer, RedisCacheProvider redis)
        {
            using var redisLock = redis.Lock($"{userId}_{(int)taskEvent}", 1);
            if (redisLock == null) return new TaskCompleteResult { isComplete = false };
            if (await repository.OnceTaskCheckComplete(userId, taskEvent))
            {
                //LoggerManager.Logger.Info($"一次性任务{taskEvent}已完成过，请不要重复完成。");
                return new TaskCompleteResult { isComplete = false };
            }
            DateTime completeTime = ((DateTime?)data?["completeTime"]) ?? DateTime.Now;
            //加经验
            var taskInfo = await repository.GetTaskInfo(taskEvent);
            if (null == taskInfo) return new TaskCompleteResult { isComplete = false };
            var res = await UserAddExperience(repository, userId, taskInfo, producer);
            if (!res) return new TaskCompleteResult { isComplete = false };
            //任务完成
            switch (taskEvent)
            {
                case TaskEvent.CompleteSelfData:
                    await CompleteSelfDataTask(repository, userId, completeTime);
                    break;
                case TaskEvent.RealNameAuth:
                    await RealNameAuth(repository, userId, completeTime);
                    break;
                case TaskEvent.AuthorAuth:
                    await AuthorAuth(repository, userId, completeTime);
                    break;
                case TaskEvent.Withdrawal:
                    await Withdrawal(repository, userId, completeTime);
                    break;
                default: throw new NotSupportedException("只支持一次性任务");
            }
            return new TaskCompleteResult { isComplete = res, taskImage = taskInfo.taskImage, taskMessage = $"{taskInfo.taskName}完成，+{taskInfo.experience}成长值", };
        }

        public static async Task<bool> OnceTaskCheckComplete(
            this DbRESTFulRepository repository, long userId, TaskEvent taskEvent)
        {
            OnceTaskLog onceTaskLog = await repository.QuerySingleOrDefaultAsync<OnceTaskLog>
                    (@$"select userId,completeSelfDataTime,realNameAuthTime,authorAuthTime,withdrawalTime 
                    from n_user_grow_once_task_log where userId={userId}");
            return taskEvent switch
            {
                TaskEvent.CompleteSelfData => CheckTimeComplete(onceTaskLog?.completeSelfDataTime),
                TaskEvent.RealNameAuth => CheckTimeComplete(onceTaskLog?.realNameAuthTime),
                TaskEvent.AuthorAuth => CheckTimeComplete(onceTaskLog?.authorAuthTime),
                TaskEvent.Withdrawal => CheckTimeComplete(onceTaskLog?.withdrawalTime),
                _ => throw new NotSupportedException("只支持一次性任务")
            };
        }

        //公司成立时间
        public static readonly DateTime minTime = DateTime.Parse("2020-01-01");
        public static bool CheckTimeComplete(DateTime? completeTime)
        {
            return completeTime != null && completeTime > minTime;
        }
    }
}
