using RFrameGenerate.Common;
using RFrameGenerate.DAL.Interface;
using RFrameGenerate.Model;
using RFramework.SQLServer;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Caching;

namespace RFrameGenerate.BLL.Marketing
{
    public class StoreCouponsManage
    {
        #region 读取数据

        public static T_SA_StoreCoupons GetCouponsByActivity(Guid storeActivityGuid)
        {
            if (storeActivityGuid == Guid.Empty) return new T_SA_StoreCoupons();

            using (var query = Factory.CreateT_SA_StoreCoupons())
            {
                return query.GetFirstData(m => m.StoreActivityGuid == storeActivityGuid);
            }
        }

        /// <summary>
        /// 读取数据
        /// </summary>
        public static T_SA_StoreCoupons GetCouponsByActivity(Guid storeActivityGuid, Dictionary<Guid, T_SA_StoreCoupons> cache)
        {
            var model = CacheHelper.GetDicCache<Guid, T_SA_StoreCoupons>(storeActivityGuid, cache);

            if (model != null) return model;

            using (var query = Factory.CreateT_SA_StoreCoupons())
            {
                model = query.GetFirstData(m => m.StoreActivityGuid == storeActivityGuid);
            }
            if (model == null) model = new T_SA_StoreCoupons();

            CacheHelper.SetDicCache<Guid, T_SA_StoreCoupons>(storeActivityGuid, model, cache);

            return model;
        }

        #endregion

        #region 逻辑处理

        /// <summary>
        /// 领取优惠券
        /// </summary>
        public static Result GetCoupons(Guid activityGuid, Guid couponsGuid, Guid memberGuid, out int receivedNum)
        {
            receivedNum = 0;
            var coupons = GetCacheCoupons(activityGuid, couponsGuid);

            var state = CheckCoupons(coupons);

            if (!state.State) return new Result(false, state.Msg);

            int memberReceived = GetMemberReviced(activityGuid, memberGuid);

            if (memberReceived >= coupons.EachNum) return new Result(false, string.Format("你已领取{0}张，每人限领{0}张", coupons.EachNum));

            lock (coupons)
            {
                state = CheckCoupons(coupons);

                if (!state.State) return new Result(false, state.Msg);

                SqlRTransaction trans = null;
                IQuery<T_SA_StoreCoupons> couponsQuery = null;
                IQuery<T_SA_ActivityDetail> detailQuery = null;

                try
                {
                    trans = new SqlRTransaction();
                    trans.BeginTransaction();

                    couponsQuery = Factory.CreateT_SA_StoreCoupons(trans);
                    detailQuery = Factory.CreateT_SA_ActivityDetail(trans);

                    var rNum = coupons.ReceivedNum + 1;

                    couponsQuery.Update(m => new object[]{
                        m.ReceivedNum == rNum,                       
                    }, v => v.StoreCouponsGuid == coupons.StoreCouponsGuid);

                    var model = new Model.T_SA_ActivityDetail();

                    model.ActivityDetailGuid = Guid.NewGuid();
                    if (coupons.ValidityType == 1)
                    {
                        model.StartDate = DateTime.Now;
                        model.ExpiryDate = DateTime.Now.AddDays(coupons.ValidityDays.Value);
                    }
                    else
                    {
                        model.StartDate = coupons.StartDate;
                        model.ExpiryDate = coupons.EndDate;
                    }
                    model.StoreActivityGuid = coupons.StoreActivityGuid;
                    model.MemberGuid = memberGuid;
                    model.VoucherMoney = coupons.Amount;
                    model.VoucheCode = DateTime.Now.ToString("yyyyMMddHHmmssfff") + RFrameGenerate.Common.RadomCode.DigitalCode(5);
                    model.State = DictionaryConst.CouponsState.NotUsed;

                    detailQuery.Add(model);

                    trans.Commit();
                    coupons.ReceivedNum = coupons.ReceivedNum + 1;
                    receivedNum = (coupons.TotalNum - coupons.ReceivedNum).Value;

                    return new Result(true);
                }
                catch (Exception ex)
                {
                    Wechat.LogManage.Log("Thread ID : " + System.Threading.Thread.CurrentThread.ManagedThreadId + " 获取优惠券失败！ Message :" + ex.Message);
                    Wechat.LogManage.Log("Thread ID : " + System.Threading.Thread.CurrentThread.ManagedThreadId + " 获取优惠券失败！ Source :" + ex.Source);
                    Wechat.LogManage.Log("Thread ID : " + System.Threading.Thread.CurrentThread.ManagedThreadId + " 获取优惠券失败！ StackTrace :" + ex.StackTrace);
                }
                finally
                {
                    if (couponsQuery != null) couponsQuery.Dispose();
                    if (detailQuery != null) detailQuery.Dispose();

                    if (trans != null)
                    {
                        trans.Dispose();

                        if (trans.SqlConnection != null && trans.SqlConnection.State != System.Data.ConnectionState.Closed)
                        {
                            trans.SqlConnection.Close();
                        }
                    }
                }



            }
            return new Result(true);

        }

        public static T_ST_ActivityCoupons GetCacheCoupons(Guid activityGuid, Guid couponsGuid)
        {
            string key = string.Format("{0}_{1}", activityGuid, couponsGuid);

            var model = HttpContext.Current.Cache[key] as T_ST_ActivityCoupons;

            if (model != null) return model;

            lock (typeof(StoreCouponsManage))
            {
                if (model != null) return model;

                model = GetActivityCoupons(activityGuid, couponsGuid);

                if (model == null) return null;

                HttpContext.Current.Cache.Add(key, model, null, DateTime.Now.AddMinutes(20), TimeSpan.Zero, CacheItemPriority.Default, null);

                return model;
            }
        }

        private static T_ST_ActivityCoupons GetActivityCoupons(Guid activityGuid, Guid couponsGuid)
        {
            using (var query = Factory.CreateT_ST_ActivityCoupons())
            {
                return query.GetFirstData(m => m.MerchantGuid == CurrentManage.MerchantGuid && m.StoreActivityGuid == activityGuid && m.StoreCouponsGuid == couponsGuid);
            }
        }

        /// <summary>
        /// 检查优惠券是否合法
        /// </summary>
        private static Result CheckCoupons(T_ST_ActivityCoupons coupons)
        {
            if (coupons == null) return new Result(false, "不存在活动！");

            int state = StoreActivityManage.CurrentState(coupons.State.Value, coupons.StartDate.Value, coupons.EndDate.Value);

            if (state == DictionaryConst.ActivityState.Closed) return new Result(false, "活动已关闭！");

            if (state == DictionaryConst.ActivityState.End) return new Result(false, "活动已结束");

            if (state == DictionaryConst.ActivityState.NotBeginning) return new Result(false, "活动未开始，不能领取！");

            if (state == DictionaryConst.ActivityState.Unknown) return new Result(false, "活动状态错误，不能领取！");

            if (coupons.ReceivedNum >= coupons.TotalNum) return new Result(false, "优惠券已领取完！");

            return new Result(true);
        }

        private static int GetMemberReviced(Guid activityGuid, Guid memberGuid)
        {
            using (var query = Factory.CreateT_SA_ActivityDetail())
            {
                return query.GetCount(m => m.MemberGuid == memberGuid && m.StoreActivityGuid == activityGuid);
            }
        }

        #endregion

        #region 优惠券领取模板消息

        public static Result SendTemplate(Guid[] membersGuid, Guid activityGuid, Guid couponsGuid)
        {
            var template = MessageTemplateManage.GetTemplateMessage(DictionaryConst.TemplateMessage.优惠券通知);

            if (template == null) return new Result(false, "不存在模板消息，请添加模板消息");

            var coupons = GetActivityCoupons(activityGuid, couponsGuid);

            var state = CheckCoupons(coupons);

            if (!state.State) return new Result(false, state.Msg);

            var members = MemberManage.GetMembersByGuid(membersGuid, m => new { m.MemberOpenID });

            if (members == null || members.Count <= 0) return new Result(false, "不存在会员，请选择会员！");

            int success = 0;
            foreach (var member in members)
            {
                var result = SendTemplate(member.MemberOpenID, template.TemplateID, coupons);

                success = result.State ? success + 1 : success;
            }
            if (success > 0) return new Result(true, string.Format("成功发送{0}，失败{1}", success, members.Count - success));

            return new Result(false, "发送失败！");
        }

        public static Result SendTemplate(string memberOpenID, string templateID, T_ST_ActivityCoupons coupon)
        {
            if (string.IsNullOrEmpty(memberOpenID)) return new Result(false, "发送会员ID不能为空！");

            if (string.IsNullOrEmpty(templateID)) return new Result(false, "发送模板ID不能为空！");

            if (coupon == null) return new Result(false, "发送优惠券为空！");

            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", string.Format("无线专享{0}减{1}", coupon.ServiceConditions == 1 ? "无线" : "满" + ((int)coupon.ServiceConditionsMoney).ToString(), (int)coupon.Amount)));
            send.keys.Add(new Wechat.Model.TempateKey("keyword2", CurrentManage.MerchantUserID));
            send.remark = new Wechat.Model.TempateKey("remark", "请您尽快支付！");

            var result = weixinopen.WeiXinOpenRequest.SendMessageTemplate(memberOpenID, templateID, CurrentManage.CurrentDomainWx + "Order/Index", send, CurrentManage.AppId);

            if (result.state) return new Result(true);

            return new Result(false, "发送模板消息错误！" + result.errmsg);
        }
        #endregion
    }
}
