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

namespace XYY.Service.Standard.Finance.Charging.Base
{

    /// <summary>
    /// 附加费处理
    /// 需要传入跟踪号、申报价值、计费重、计费时间、客户Id，返回最终结算价（CNY）
    /// </summary>
    public interface IAttachedService : IChargesService<ExpressFeechargesModel>
    {
        Task<ApiJsonModel> RefreshRedisCache();
        Task<ApiJsonModel> RefreshRedis20230324Cache();

        Task<ApiJsonModel> Test(string zipcode);
    }

    public class AttachedService : IAttachedService
    {
        IUnitOfWork _unitOfWork;
        IDatabase db;
        IServer server;
        ITAttachedZipSet _itAttachedZipSet;
        public AttachedService(RedisHelper helper, IUnitOfWork unitOfWork, IUserRateService userRateService, ITAttachedZipSet itAttachedZipSet)
        {
            _unitOfWork = unitOfWork;
            if (_unitOfWork == null)
                throw new EUExchangeException(EUExchangeException.DB_ConnectionError);
            this.db = helper.GetDatabase();
            server = helper.GetServer();
            this.userRateService = userRateService;
            _itAttachedZipSet = itAttachedZipSet;
        }

        public async Task<ApiJsonModel> Test(string zipcode)
        {
            var status = _itAttachedZipSet.ContainsZip(zipcode);
            return await Task.FromResult(ApiJsonModel.Error(status.ToString()));
        }

        IUserRateService userRateService;


        string FedexOrDhlAttacheZoneKey = "FODAZ";
        string FedexOrDhlAttacheKey = "FODA";
        string ITAttachedZipKey = "ITAttachedZip";
        string ITAttachedZip20230324Key = "ITAttachedZip20230324";
        public async Task<ApiJsonModel> RefreshRedisCache()
        {
            try
            {
                #region 操作
                bool isDelete = await db.KeyDeleteAsync(ITAttachedZipKey);
                string sql = @"select ZipCode from Logistics_RemoteFeePrefixArea where RemoteFeePrefixId = 227";
                var data = await _unitOfWork.QueryBySqlAsync<dynamic>(sql);

                db.SetAdd(ITAttachedZipKey, data.Select(x => (RedisValue)(x.ZipCode)).ToArray());
                #endregion
            }
            catch (Exception ex)
            {
                return ApiJsonModel.Error(ex.Message);
            }
            try
            {
                bool isDelete = await db.KeyDeleteAsync(ITAttachedZipKey);
                string sql = @"select distinct ZipCode from Logistics_RemoteFeePrefixArea where RemoteFeePrefixId = 228";
                var data = await _unitOfWork.QueryBySqlAsync<dynamic>(sql);
                db.SetAdd(ITAttachedZipKey, data.Select(x => (RedisValue)(x.ZipCode)).ToArray());
            }
            catch (Exception ex)
            {
                return ApiJsonModel.Error(ex.Message);
            }
            return ApiJsonModel.OK("成功");
        }
        public async Task<ApiJsonModel> RefreshRedis20230324Cache()
        {
            try
            {
                #region 操作
                bool isDelete = await db.KeyDeleteAsync(ITAttachedZip20230324Key);
                string sql = @"select ZipCode from Logistics_RemoteFeePrefixArea where RemoteFeePrefixId = 20230324";
                var data = await _unitOfWork.QueryBySqlAsync<dynamic>(sql);

                db.SetAdd(ITAttachedZip20230324Key, data.Select(x => (RedisValue)(x.ZipCode)).ToArray());
                #endregion
            }
            catch (Exception ex)
            {
                return ApiJsonModel.Error(ex.Message);
            }
            return ApiJsonModel.OK("成功");
        }

        private class BaseIds
        {
            public int Id { get; set; }
            public DateTime EnableTime { get; set; }
            public int CustomerId { get; set; }
        }

        private class FedexOrDhlAttache
        {
            public string CountryCode
            {
                get; set;
            }

            /// <summary>
            /// 首重重量（克）
            /// </summary>
            public int FristWeight
            {
                get; set;
            }

            /// <summary>
            /// 续重重量（克）
            /// </summary>
            public int ContinuedWeight
            {
                get; set;
            }
        }

        public async Task<ApiJsonModel> Charges(ExpressFeechargesModel t)
        {
            decimal ceilingWeight = Math.Ceiling((decimal)t.BillingWeight);
            //意大利偏远费
            if (t.PublicExpressId == 22)
            {
                if (string.IsNullOrEmpty(t.ZipCode))
                {
                    return ApiJsonModel.Error("邮编不能为空");
                }

                var zipExistsStatus = _itAttachedZipSet.ContainsZip(t.ZipCode);
                if (zipExistsStatus == ContainsZipStatus.NoData)
                {
                    var ex = new EUExchangeException(EUExchangeException.Redis_NoData);
                    return ApiJsonModel.Error(ex.Message);
                }
                else if (zipExistsStatus == ContainsZipStatus.Exists)
                {
                    //包含偏远邮编 
                    t.SettlementAmount = 10.0m;
                    t.SettlementCurrency = "CNY";
                    t.SettlementRate = 1;
                    t.AmountinOriginalCurrency = t.SettlementAmount;
                }

                //if (!db.KeyExists(ITAttachedZipKey))
                //{
                //    var ex = new EUExchangeException(EUExchangeException.Redis_NoData);
                //    return ApiJsonModel.Error(ex.Message);
                //}


                //if (db.SetContains(ITAttachedZipKey, t.ZipCode))
                //{
                //    //包含偏远邮编 
                //    t.SettlementAmount = 8.0m;
                //    t.SettlementCurrency = "CNY";
                //    t.SettlementRate = 1;
                //    t.AmountinOriginalCurrency = t.SettlementAmount;
                //}
            }

            //澳洲WJY偏远费
            if (t.PublicExpressId == 17)
            {
                if (string.IsNullOrEmpty(t.TrackingNumber))
                    return ApiJsonModel.Error("必须传入跟踪号");

                if (t.TrackingNumber.StartsWith("WJY")
                    || t.TrackingNumber.StartsWith("UR")
                    || t.TrackingNumber.StartsWith("WQB")
                    || t.TrackingNumber.StartsWith("33")
                    || t.TrackingNumber.StartsWith("34")
                    || t.TrackingNumber.StartsWith("36"))
                {
                    if (t.TransactionTime < DateTime.Parse("2022-11-15"))
                    {
                        t.SettlementAmount = 25;
                    }
                    else if (t.TransactionTime < DateTime.Parse("2023-01-01"))
                    {
                        t.SettlementAmount = 27.5m;
                    }
                    else if (t.TransactionTime < DateTime.Parse("2023-02-10"))
                    {
                        t.SettlementAmount = 30.5m;
                    }
                    else if(t.TransactionTime< DateTime.Parse("2023-06-24"))
                    {
                        t.SettlementAmount = 25m;
                    }
                    else
                    {
                        t.SettlementAmount = 20m;
                    }
                }
                t.SettlementCurrency = "CNY";
                t.SettlementRate = 1;
                t.AmountinOriginalCurrency = t.SettlementAmount;
            }
            bool lhj = new int[] { 221, 252 }.Contains(t.CustomerId);
            //Fedex快递附加费
            int[] fedexDhl = new int[] { 48 };


            //DHL附加费
            if ((t.PublicExpressId == 50 || t.PublicExpressId == 48 || t.PublicExpressId == 231 || t.PublicExpressId == 232))
            {
                List<dynamic> attachFees = (await _unitOfWork.Connection.QueryAsync<dynamic>("TestAttachFee", new
                {
                    OpWeight = t.BillingWeight * 1000,
                    CustomerId = t.CustomerId,
                    ReceiverTime = t.TransactionTime,
                    CoutryCode = t.CountryCode,
                    ReceiverZipCode = string.Empty
                }, _unitOfWork.Transaction, null, System.Data.CommandType.StoredProcedure)).ToList();
                var at = attachFees.FirstOrDefault(x => x.ChannelId == t.PublicExpressId);
                if (at != null)
                {
                    t.SettlementCurrency = "CNY";
                    t.SettlementRate = 1;
                    t.AmountinOriginalCurrency = at.Fee;
                    t.SettlementAmount = at.Fee;
                }
            }

            //中东附加费
            if (t.PublicExpressId == 92)
            {
                if (string.IsNullOrEmpty(t.CountryCode))
                {
                    return ApiJsonModel.Error("必须传入国家");
                }
                t.CountryCode = t.CountryCode.ToUpper();

                decimal baseFee = 0;
                var temp = new ExpressFeechargesModel { Currency = "USD", AmountinOriginalCurrency = 1, TransactionTime = t.TransactionTime };
                var u = await userRateService.Charges(temp);
                if (!u.success)
                    return u;
                decimal userRate = temp.SettlementAmount;

                if (t.CountryCode == "AE")
                {
                    baseFee = t.GoodsDeclared * 0.05m * userRate;
                }
                else if (t.CountryCode == "BH")
                {
                    baseFee = t.GoodsDeclared * 0.05m * userRate + 21;
                }
                else if (t.CountryCode == "OM" && t.GoodsDeclared > 24)
                {
                    baseFee = t.GoodsDeclared * 0.05m * userRate;
                }
                else if (t.CountryCode == "KW")
                {
                    baseFee = t.GoodsDeclared * 0.0625m * userRate + 35;
                }
                else if (t.CountryCode == "SA")
                {
                    baseFee = t.GoodsDeclared * 0.15m * userRate;
                }
                else if (t.CountryCode == "QA")
                {
                    baseFee = 59;
                }

                string[] country = new string[] { "AE", "BH", "OM", "KW" };
                if (t.TransactionTime > DateTime.Parse("2021-11-16")
                    && country.Contains(t.CountryCode)
                    && lhj
                    )
                {
                    baseFee += (22m * ceilingWeight);
                }
                else if (t.TransactionTime > DateTime.Parse("2021-11-16")
                    && t.CountryCode == "SA"
                    && lhj)
                {
                    baseFee += (11m * ceilingWeight);
                }
                else if (t.TransactionTime > DateTime.Parse("2021-09-23")
                    && country.Contains(t.CountryCode))
                {
                    baseFee += (20m * ceilingWeight);
                }
                else if (t.TransactionTime > DateTime.Parse("2021-10-22")
                    && t.CountryCode == "SA")
                {
                    baseFee += (10m * ceilingWeight);
                }
                t.SettlementAmount = baseFee;
                t.AmountinOriginalCurrency = 0;
                t.Currency = "USD";
                t.SettlementCurrency = "CNY";
                t.SettlementRate = userRate;
            }

            //线上
            if (t.IsOnline)
            {
                t.SettlementAmount += 1;
            }

            //
            ///计算结果取两位小位
            t.SettlementAmount = Math.Round(t.SettlementAmount, 2, MidpointRounding.AwayFromZero);
            return ApiJsonModel.OK(t);
        }
    }
}
