using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XYY.Core.Standard.Data.Infrastructure;
using XYY.Core.Standard.Data.Redis;
using XYY.Service.Standard.Finance.Charging.Base;
using XYY.Service.Standard.Finance.Charging.Express;
using Dapper;
using XYY.Service.Standard.Finance.Charging.EUExchange;
using XYY.Core.Standard.Mvc;
using System.Threading;

namespace XYY.Service.Standard.Finance.Charging.UserRate
{
    /// <summary>
    /// 用户汇率转算
    /// </summary>
    public interface IUserRateService : IChargesService<ExpressFeechargesModel>
    {
        Task<ApiJsonModel> RefreshRedisCache();
    }
    public class UserRateService : IUserRateService
    {
        IUnitOfWork _unitOfWork;
        IDatabase db;
        IServer server;
        public UserRateService(RedisHelper helper, IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
            if (_unitOfWork == null)
                throw new UserRateException(UserRateException.DB_ConnectionError);
            this.db = helper.GetDatabase();
            server = helper.GetServer();
        }

        public async Task<ApiJsonModel> Charges(ExpressFeechargesModel t)
        {
            ThreadPool.SetMinThreads(200, 200);
            var fb = new UserRateBase(t.Currency, t.TransactionTime, 0);
            var set = await db.SortedSetRangeByScoreAsync(fb.Key, 0, fb.DateTimeVersion, order: Order.Descending, take: 1);
            if (set.Length == 0 || Convert.ToDecimal(set[0]) == 0)
            {
                return ApiJsonModel.Error("必须传入汇率");
            }
            else
            {
                var fee = Convert.ToDecimal(set[0]);
                t.SettlementRate = fee;
                t.SettlementAmount = Math.Round(t.AmountinOriginalCurrency * t.SettlementRate, 2);
                t.SettlementCurrency = "CNY";
                return ApiJsonModel.OK();
            }
        }

        /// <summary>
        /// 重新加载所有汇率
        /// </summary>
        /// <returns></returns>
        public async Task<ApiJsonModel> RefreshRedisCache()
        {
            try
            {
                ThreadPool.SetMinThreads(200, 200);
                #region 操作
                await db.DeleteScanKey( "UserRate*");
                string sql = @"select Currency,StartDate,EndDate,convert(decimal(10,4),ToCNY) as ToCNY from Finance_CustomerRate(nolock)";
                var data = await _unitOfWork.QueryBySqlAsync<dynamic>(sql);
                foreach (var item in data)
                {
                    UserRateBase Base = new UserRateBase(item.Currency, item.StartDate, (double)item.ToCNY);
                    db.SortedSetAdd(Base.Key, Base.Rate.ToString(), Base.DateTimeVersion);
                }
                foreach (var i in data.GroupBy(x => x.Currency))
                {
                    var item = i.OrderByDescending(x => x.EndDate).FirstOrDefault();
                    if (item != null)
                    { 
                        UserRateBase Base = new UserRateBase(item.Currency, item.EndDate.AddDays(1), 0);
                        db.SortedSetAdd(Base.Key, Base.Rate.ToString(), Base.DateTimeVersion);
                    }
                }
                #endregion
            }
            catch (Exception ex)
            {
                return ApiJsonModel.Error(ex.Message);
            }
            return ApiJsonModel.OK("成功");
        }
    }
}
