using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RFrameGenerate.Model;
using RFramework.SQLQuery;
using RFramework.SQLServer;
using Wechat.EnterprisePay;
using Wechat.WeiXinHongBao;
using Wechat;
using RFrameGenerate.DAL.Enums;
using RFrameGenerate.Common;
using RFrameGenerate.Model.PageModel;

namespace RFrameGenerate.BLL
{
    public class WithdrawsManage
    {
        #region List<T_BAS_Withdraws> GetWithdrawsList
        /// <summary>
        /// get withdraws list
        /// </summary>
        /// <param name="gridModel"></param>
        /// <param name="userName"></param>
        /// <returns></returns>
        public static List<T_BAS_Withdraws> GetWithdrawsList(GridModel gridModel, string userName)
        {
            using (var query = Factory.CreateT_BAS_Withdraws())
            {
                return query.GetPageList(gridModel, c => c.Name.SqlLike(userName), true, k => k.ApplyDateTime, DAL.Enums.OrderMethods.DESC);
            }
        }
        #endregion

        #region Result UpdateApprovalState

        /// <summary>
        /// updata approval by withdrawGuid (or memberGuid)
        /// </summary>
        /// <param name="state"></param>
        /// <param name="withdrawGuid"></param>
        /// <param name="remark"></param>
        /// <param name="balance"></param>
        /// <param name="memberGuid"></param>
        /// <returns></returns>
        public static Result UpdateApprovalState(int state, Guid withdrawGuid, string remark, Guid memberGuid, string ip)
        {
            var lockitem = CrowdPeriodLock.GetLock(withdrawGuid);
            lock (lockitem)
            {
                try
                {
                    using (var tran = new SqlRTransaction())
                    {
                        var queryMember = Factory.CreateT_BAS_Member(tran);
                        var queryWithdraw = Factory.CreateT_BAS_Withdraws(tran);
                        var member = queryMember.GetFirstData(a => a.MemberGuid == memberGuid && a.MerchantGuid == RFrameGenerate.Common.CurrentManage.MerchantGuid);
                        var witdraw = queryWithdraw.GetFirstData(a => a.WithdrawGuid == withdrawGuid);
                        if (witdraw.State == 0)
                        {
                            string appid = RFrameGenerate.Common.CurrentManage.AppId;
                            string openid = member.MemberOpenID;
                            string partner_trade_no = witdraw.WithdrawGuid.ToString().Replace("-", "");

                            var querymerapayway = Factory.CreateT_BAS_MerchantsPayWay(tran);
                            var querypayway = Factory.CreateT_BAS_PayWays(tran);
                            var payway = querypayway.GetFirstData(a => a.Name == "微信支付");
                            var merapayway = querymerapayway.GetFirstData(a => a.MerchantGuid == RFrameGenerate.Common.CurrentManage.MerchantGuid && a.PayWayGuid == payway.PayWayGuid);
                            if (state == 1)//同意打款
                            {
                                PT_BAS_PayWayByOrderNo pay = new PT_BAS_PayWayByOrderNo()
                                {
                                    Prop = merapayway.Prop,
                                };
                                string cerpath = pay.GetValue(DictionaryConst.PayWays.WeiXin.Cer);
                                string key = pay.GetValue(DictionaryConst.PayWays.WeiXin.Key);
                                string mchid = pay.GetValue(DictionaryConst.PayWays.WeiXin.MChid);

                                EnterpriseRequestModel send = new EnterpriseRequestModel(key)
                                {
                                    mchid = mchid,
                                    key = key,
                                    amount = (witdraw.ApplyAmount.Value * 100).ToString("0"),
                                    check_name = "NO_CHECK",
                                    desc = remark,
                                    mch_appid = appid,
                                    openid = openid,
                                    partner_trade_no = partner_trade_no,
                                    re_user_name = member.MemberNickName,
                                    spbill_create_ip = ip,
                                };
                                var er = WeiXinEnterpriseRequest.Pay(send, cerpath, mchid);
                                //if (er.VerifySign() != true)
                                if (er.return_code != "SUCCESS" || er.result_code != "SUCCESS")
                                {
                                    //return_code=SUCCESS,return_msg=,result_code=SUCCESS,err_code=,err_code_des=
                                    //"付款失败,return_code=FAIL,return_msg=帐号余额不足，请用户充值或更换支付卡后再支付.,result_code=,err_code=,err_code_des="
                                    if (er.return_msg.Contains("余额不足") == true)
                                    {
                                        return new Result(false, "帐号余额不足，请用户充值或更换支付卡后再支付");
                                    }
                                    else
                                    {
                                        if (string.IsNullOrEmpty(er.return_msg) != true)
                                            return new Result(false, er.return_msg);
                                        else
                                            return new Result(false, er.err_code_des);

                                    }

                                }
                            }

                            decimal amount = member.Amount;
                            decimal AmountFrozen = member.AmountFrozen;
                            decimal Balance = member.Balance;

                            tran.BeginTransaction();
                            if (state == 1)//同意
                            {
                                amount = member.Amount - witdraw.ApplyAmount.Value;
                                AmountFrozen = member.AmountFrozen - witdraw.ApplyAmount.Value;
                                MemberAccountManage.SetMemberAccountType(member.MemberGuid, withdrawGuid, MemberAccountConst.TradingType.提现成功, tran);
                            }
                            else//拒绝
                            {
                                AmountFrozen = member.AmountFrozen - witdraw.ApplyAmount.Value;
                                Balance = member.Balance + witdraw.ApplyAmount.Value;

                                //添加会员账户记录 Bing 160423
                                MemberAccountManage.AddMemberAccount(member.MemberGuid, MemberAccountConst.TradingType.提现失败, witdraw.WithdrawGuid, witdraw.ApplyAmount.Value, tran, member.Balance, member.MerchantGuid);
                            }

                            SendTemplate(state, memberGuid, witdraw.ApplyAmount.Value, "微信钱包", witdraw.ApplyDateTime.Value);


                            queryMember.Update(c => new object[]
                                    {
                                        c.Amount==amount,
                                        c.AmountFrozen==AmountFrozen,
                                        c.Balance==Balance,

                                    }, s => s.MemberGuid == memberGuid);
                            queryWithdraw.Update(a => new object[]
                                    {
                                        a.Remark==remark,
                                        a.State == state                    
                                    }, b => b.WithdrawGuid == withdrawGuid);
                            tran.Commit();
                            return new Result(true);
                        }
                        else
                        {
                            return new Result(false, "您已同意,请勿再次同意.");
                        }
                    }
                }
                catch (Exception ex)
                {
                    return new Result(false, ex.Message);
                }
                finally
                {
                    lockitem.IsUse = false;
                }
            }
        }

        public static void SendTemplate(int state, Guid memberGuid, decimal amount, string way, DateTime applydate)//state=1 同意
        {
            try
            {
                using (var tran = new SqlRTransaction())
                {
                    var querytemp = Factory.CreateT_BAS_MessageTemplate(tran);
                    var merchGuid = HeadPay.GetPayMerchantGuid(CurrentManage.MerchantUserID);
                    var template = querytemp.GetFirstData(a => a.MerchantGuid == merchGuid && a.TemplateNo == DictionaryConst.TemplateMessage.提现审核结果通知, false, null, OrderMethods.Default, RFramework.SQLServer.Enums.LockType.Default, false);
                    if (template != null)
                    {
                        var memeber = MemberManage.GetMemberByGuid(memberGuid);
                        Wechat.Model.SendTempateKey send = new Wechat.Model.SendTempateKey();
                        send.first = new Wechat.Model.TempateKey("first", "您的提现申请已处理");
                        send.keys = new List<Wechat.Model.TempateKey>();
                        send.keys.Add(new Wechat.Model.TempateKey("keyword1", amount.ToString("0.00")));
                        send.keys.Add(new Wechat.Model.TempateKey("keyword2", way));
                        send.keys.Add(new Wechat.Model.TempateKey("keyword3", applydate.ToString("yyyy/MM/dd HH:mm:ss")));
                        send.keys.Add(new Wechat.Model.TempateKey("keyword4", state == 1 ? "已同意" : "审核未通过"));
                        send.keys.Add(new Wechat.Model.TempateKey("keyword5", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
                        send.remark = new Wechat.Model.TempateKey("remark", "感谢您的使用,祝您生意兴隆。");

                        weixinopen.WeiXinOpenRequest.SendMessageTemplate(memeber.MemberOpenID, template.TemplateID, CurrentManage.DomainWx.Replace("shop.", string.Format("{0}.shop.", CurrentManage.MerchantUserID)) + "My/Index", send, Common.CurrentManage.AppId);
                    }
                }
            }
            catch (Exception ex)
            {
                Wechat.LogManage.Log("提现审核通送模板消息出错" + ex.Message);
            }
        }

        #endregion

        public static List<T_BAS_Withdraws> GetList()
        {
            using (var query = Factory.CreateT_BAS_Withdraws())
            {
                Guid memeberGuid = RFrameGenerate.Common.CurrentUser.GetCurrUserGuid();
                return query.GetList(a => a.MemberGuid == memeberGuid, false, b => b.ApplyDateTime, OrderMethods.DESC);
            }
        }

        public static Result ApplyAmoutn(string name, string tel, decimal amount, string payno, string withdrawstype)
        {
            if (string.IsNullOrEmpty(name) == true)
                return new Result(false, "申请提现姓名不能为空");
            if (string.IsNullOrEmpty(tel) == true)
                return new Result(false, "申请提现手机号不能为空");
            if (amount <= 0)
                return new Result(false, "可能余额不足,无法提现");

            var lockitem = CrowdPeriodLock.GetLock(CurrentUser.GetCurrUserGuid());
            lock (lockitem)
            {
                try
                {
                    using (var tran = new RFramework.SQLServer.SqlRTransaction())
                    {
                        var queryParam = Factory.CreateT_SYS_Parameter(tran);
                        var minWithdraw = queryParam.GetFirstData(a => a.MerchantGuid == RFrameGenerate.Common.CurrentManage.MerchantGuid && a.ParameterName == ParameterName.Withdraw.MinAmount);
                        decimal minwithdrawvalue = decimal.Parse(minWithdraw.ParameterValue);
                        if (amount < minwithdrawvalue)
                            return new Result(false, "最低提现金额不能低于" + minwithdrawvalue + "元");

                        var query = Factory.CreateT_BAS_Withdraws(tran);
                        DateTime day = DateTime.Now;
                        DateTime dtfrom = new DateTime(day.Year, day.Month, 1);
                        DateTime dtto = dtfrom.AddMonths(1).AddSeconds(-1);

                        var maxtime = queryParam.GetFirstData(a => a.MerchantGuid == RFrameGenerate.Common.CurrentManage.MerchantGuid && a.ParameterName == ParameterName.Withdraw.ExtNumber);
                        decimal maxtimevalue = decimal.Parse(maxtime.ParameterValue);
                        if (query.GetCount(a => a.MerchantGuid == RFrameGenerate.Common.CurrentManage.MerchantGuid && a.MemberGuid == RFrameGenerate.Common.CurrentUser.GetCurrUserGuid() && a.ApplyDateTime >= dtfrom && a.ApplyDateTime <= dtto) >= maxtimevalue)
                        {
                            return new Result(false, "一个月最多申请" + maxtime.ParameterValue + "次");
                        }

                        var queryMember = Factory.CreateT_BAS_Member(tran);
                        var queryPayAccount = Factory.CreateT_BAS_PayAccount(tran);
                        var member = queryMember.GetFirstData(a => a.MemberGuid == RFrameGenerate.Common.CurrentUser.GetCurrUserGuid());

                        if (amount <= 0)
                            return new Result(false, "申请提现金额不能小于或等于0");
                        if (amount > member.Balance)
                            return new Result(false, "申请提现金额不能大于可用余额");

                        tran.BeginTransaction();
                        if (queryPayAccount.IsExist(a => a.Account == payno && a.MemberGuid == RFrameGenerate.Common.CurrentUser.GetCurrUserGuid()) != true)
                        {
                            queryPayAccount.Add(new T_BAS_PayAccount()
                            {
                                MemberGuid = RFrameGenerate.Common.CurrentUser.GetCurrUserGuid(),
                                Account = payno,
                                Name = name,
                                PayAccountGuid = Guid.NewGuid(),
                                PayType = withdrawstype,
                                Remark = "自动添加",
                            });
                        }
                        var memBalance = member.Balance;
                        member.Balance = memBalance - amount;
                        member.AmountFrozen += amount;
                        queryMember.Update(member);
                        var wdEntity = new T_BAS_Withdraws()
                        {
                            MemberGuid = RFrameGenerate.Common.CurrentUser.GetCurrUserGuid(),
                            ApplyDateTime = DateTime.Now,
                            ApplyAmount = amount,
                            State = RFrameGenerate.BLL.DictionaryConst.Withdraws.Handling,
                            CarNo = payno,
                            Name = name,
                            MerchantGuid = RFrameGenerate.Common.CurrentManage.MerchantGuid,
                            Telephone = tel,
                            WithdrawalPeople = name,
                            WithdrawalWay = withdrawstype,
                            WithdrawGuid = Guid.NewGuid(),
                            WithdrawsAmount = member.Balance,
                            Remark = "",
                            UpdateDateTime = DateTime.Now,
                        };
                        query.Add(wdEntity);


                        //添加会员账户记录 Bing 160423
                        MemberAccountManage.AddMemberAccount(member.MemberGuid, MemberAccountConst.TradingType.提现申请, wdEntity.WithdrawGuid, -wdEntity.ApplyAmount.Value, tran, memBalance, member.MerchantGuid);

                        tran.Commit();
                    }
                    return new Result(true);
                }
                catch (Exception ex)
                {
                    return new Result(false, ex.Message);
                }
                finally
                {
                    lockitem.IsUse = false;
                }
            }
        }
    }
}
