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

using RFramework.SQLQuery;

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

        public static List<T_ST_ActivityCoupons> GetPageList(GridModel gridModel, int? state)
        {
            var curDate = DateTime.Now;
            using (var query = Factory.CreateT_ST_ActivityCoupons())
            {
                if (state == null || state == 0)
                    return query.GetPageList(gridModel, m => m.MerchantGuid == CurrentManage.MerchantGuid, false, v => v.StartDate, DAL.Enums.OrderMethods.DESC);
                else if (state == DictionaryConst.ActivityState.Closed)
                    return query.GetPageList(gridModel, m => m.State == DictionaryConst.ActivityState.Closed && m.MerchantGuid == CurrentManage.MerchantGuid, false, v => v.StartDate, DAL.Enums.OrderMethods.DESC);
                else if (state == DictionaryConst.ActivityState.End)
                    return query.GetPageList(gridModel, m => m.State == DictionaryConst.ActivityState.Normal && m.EndDate < curDate && m.MerchantGuid == CurrentManage.MerchantGuid, false, v => v.StartDate, DAL.Enums.OrderMethods.DESC);
                else if (state == DictionaryConst.ActivityState.NotBeginning)
                    return query.GetPageList(gridModel, m => m.State == DictionaryConst.ActivityState.Normal && m.StartDate > curDate && m.MerchantGuid == CurrentManage.MerchantGuid, false, v => v.StartDate, DAL.Enums.OrderMethods.DESC);
                else if (state == DictionaryConst.ActivityState.Show)
                    return query.GetPageList(gridModel, m => m.State == DictionaryConst.ActivityState.Normal && m.StartDate <= curDate && m.EndDate >= curDate && m.MerchantGuid == CurrentManage.MerchantGuid, false, v => v.StartDate, DAL.Enums.OrderMethods.DESC);
                else
                    return new List<T_ST_ActivityCoupons>(0);
            }
        }

        public static T_SA_StoreActivity GetActivity(Guid activityGuid)
        {
            if (activityGuid == Guid.Empty) return new T_SA_StoreActivity();

            using (var query = Factory.CreateT_SA_StoreActivity())
            {
                return query.GetFirstData(m => m.MerchantGuid == CurrentManage.MerchantGuid && m.StoreActivityGuid == activityGuid);
            }
        }

        /// <summary>
        /// 获取有效活动列表
        /// </summary>
        public static List<T_ST_ActivityCoupons> GetAvailableActivities(Guid? couponGuid)
        {
            //是否使用会员等级
            if (MemberLevelManage.UsingMemberLevel())
            {
                using (var query = Factory.CreateT_ST_ActivityCoupons())
                {
                    var memberLevel = MemberLevelManage.CurrentMemberLevel();

                    if (memberLevel == null) memberLevel = new T_BAS_MemberLevel();

                    var vipCoupons = VipCouponManage.GetVIPCouponsByMemberLevel(memberLevel.MemberLevelGuid);

                    if (vipCoupons == null) vipCoupons = new List<T_VIP_VipCoupon>(0);

                    Expression<Func<T_ST_ActivityCoupons, bool>> exp = m => m.State == DictionaryConst.ActivityState.Normal && m.StartDate <= DateTime.Now && m.EndDate >= DateTime.Now && m.MerchantGuid == CurrentManage.MerchantGuid;

                    if (couponGuid != null && couponGuid != Guid.Empty)
                        exp = exp.AndAlso(m => m.StoreCouponsGuid == couponGuid);

                    if (vipCoupons.Count > 0)
                    {
                        var ids = vipCoupons.Select(m => m.CouponGuid.Value).ToArray();

                        exp = exp.AndAlso(m => (m.IsLimit == true && m.StoreCouponsGuid.SqlIn(ids)) || m.IsLimit == false);
                    }
                    else
                    {
                        exp = exp.AndAlso(m => m.IsLimit == false);
                    }

                    return query.GetList(exp, false, v => v.Amount, DAL.Enums.OrderMethods.DESC);
                }
            }
            else
            {
                using (var query = Factory.CreateT_ST_ActivityCoupons())
                {
                    if (couponGuid == null || couponGuid.Value == Guid.Empty)
                        return query.GetList(m => m.State == DictionaryConst.ActivityState.Normal && m.StartDate <= DateTime.Now && m.EndDate >= DateTime.Now && m.MerchantGuid == CurrentManage.MerchantGuid, false, v => v.Amount, DAL.Enums.OrderMethods.DESC);
                    else
                        return query.GetList(m => m.State == DictionaryConst.ActivityState.Normal && m.StartDate <= DateTime.Now && m.EndDate >= DateTime.Now && m.MerchantGuid == CurrentManage.MerchantGuid && m.StoreCouponsGuid == couponGuid.Value, false, v => v.Amount, DAL.Enums.OrderMethods.DESC);
                }
            }
        }

        #endregion

        #region 操作数据

        public static Result SaveActivity(T_SA_StoreActivity activity, T_SA_StoreCoupons coupons, string guids)
        {
            var cbState = CheckActivity(activity, coupons);

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

            if (activity.StoreActivityGuid == Guid.Empty) return Save(activity, coupons, guids);

            var srcActivity = GetActivity(activity.StoreActivityGuid);

            if (srcActivity == null) return new Result(false, "不存在活动！");

            var state = CurrentState(srcActivity);

            if (state != DictionaryConst.ActivityState.NotBeginning) return new Result(false, "活动状态不是未开始，不能修改！");

            return Update(activity, coupons, guids);
        }

        public static Result Save(T_SA_StoreActivity activity, T_SA_StoreCoupons coupons, string guids)
        {
            SqlRTransaction trans = null;
            IQuery<T_SA_StoreActivity> queryActivity = null;
            IQuery<T_SA_StoreCoupons> queryCoupons = null;
            IQuery<T_VIP_VipCoupon> queryVipCoupons = null;

            activity.StoreActivityGuid = Guid.NewGuid();
            activity.MerchantGuid = CurrentManage.MerchantGuid;
            activity.State = DictionaryConst.ActivityState.Normal;
            activity.ActivityType = DictionaryConst.ActivityType.StoreCoupons;

            coupons.StoreCouponsGuid = Guid.NewGuid();
            coupons.StoreActivityGuid = activity.StoreActivityGuid;
            coupons.ReceivedNum = 0;
            coupons.IsLimit = false;

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

                queryActivity = Factory.CreateT_SA_StoreActivity(trans);
                queryCoupons = Factory.CreateT_SA_StoreCoupons(trans);

                if (!string.IsNullOrEmpty(guids))
                {
                    Guid id = Guid.Empty;
                    List<T_VIP_VipCoupon> vip_list = new List<T_VIP_VipCoupon>();
                    foreach (var item in guids.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        if (!Guid.TryParse(item, out id)) continue;
                        vip_list.Add(new T_VIP_VipCoupon()
                        {
                            CouponGuid = coupons.StoreCouponsGuid,
                            MemberLevelGuid = id,
                            MerchantGuid = CurrentManage.MerchantGuid,
                            VipCouponGuid = Guid.NewGuid(),
                            EntityState = EntityStates.ToBeAdd
                        });
                    }
                    if (vip_list.Count > 0)
                    {
                        queryVipCoupons = Factory.CreateT_VIP_VipCoupon(trans);
                        queryVipCoupons.AddList(vip_list);
                        coupons.IsLimit = true;
                    }
                }

                queryActivity.Add(activity);
                queryCoupons.Add(coupons);

                trans.Commit();

                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);

                return new Result(false, ex.Message);
            }
            finally
            {
                if (queryActivity != null) queryActivity.Dispose();
                if (queryCoupons != null) queryCoupons.Dispose();
                if (queryVipCoupons != null) queryVipCoupons.Dispose();

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

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

        public static Result Update(T_SA_StoreActivity activity, T_SA_StoreCoupons coupons, string guids)
        {
            SqlRTransaction trans = null;
            IQuery<T_SA_StoreActivity> queryActivity = null;
            IQuery<T_SA_StoreCoupons> queryCoupons = null;
            IQuery<T_VIP_VipCoupon> queryVipCoupons = null;
            try
            {
                trans = new SqlRTransaction();
                trans.BeginTransaction();

                queryActivity = Factory.CreateT_SA_StoreActivity(trans);
                queryCoupons = Factory.CreateT_SA_StoreCoupons(trans);

                bool isLimit = false;
                if (!string.IsNullOrEmpty(guids))
                {
                    Guid id = Guid.Empty;
                    List<T_VIP_VipCoupon> vip_list = new List<T_VIP_VipCoupon>();
                    foreach (var item in guids.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        if (!Guid.TryParse(item, out id)) continue;
                        vip_list.Add(new T_VIP_VipCoupon()
                        {
                            CouponGuid = coupons.StoreCouponsGuid,
                            MemberLevelGuid = id,
                            MerchantGuid = CurrentManage.MerchantGuid,
                            VipCouponGuid = Guid.NewGuid(),
                            EntityState = EntityStates.ToBeAdd
                        });
                    }
                    if (vip_list.Count > 0)
                    {
                        queryVipCoupons = Factory.CreateT_VIP_VipCoupon(trans);
                        queryVipCoupons.Delete(m => m.CouponGuid == coupons.StoreCouponsGuid);
                        isLimit = true;
                        queryVipCoupons.AddList(vip_list);
                    }
                }
                else
                {
                    queryVipCoupons = Factory.CreateT_VIP_VipCoupon(trans);
                    queryVipCoupons.Delete(m => m.CouponGuid == coupons.StoreCouponsGuid);
                }
                queryActivity.Update(m => new object[]{
                    m.ActivityName  == activity.ActivityName,
                    m.StartDate == activity.StartDate,
                    m.EndDate == activity.EndDate
                }, v => v.StoreActivityGuid == activity.StoreActivityGuid);

                queryCoupons.Update(m => new object[]{
                    m.Amount == coupons.Amount,
                    m.EachNum == coupons.EachNum,
                    m.ServiceConditions == coupons.ServiceConditions,
                    m.ServiceConditionsMoney == coupons.ServiceConditionsMoney,
                    m.TotalNum == coupons.TotalNum,
                    m.ValidityDays == coupons.ValidityDays,
                    m.ValidityEndDate == coupons.ValidityEndDate,
                    m.ValidityStartDate == coupons.ValidityStartDate,
                    m.ValidityType == coupons.ValidityType,                  
                    m.IsLimit == isLimit
                }, v => v.StoreCouponsGuid == coupons.StoreCouponsGuid);
                string key = string.Format("{0}_{1}", activity.StoreActivityGuid, coupons.StoreCouponsGuid);

                HttpContext.Current.Cache.Remove(key);

                trans.Commit();

                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);

                return new Result(false, ex.Message);
            }
            finally
            {
                if (queryActivity != null) queryActivity.Dispose();
                if (queryCoupons != null) queryCoupons.Dispose();
                if (queryVipCoupons != null) queryVipCoupons.Dispose();

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

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

        private static bool IsExists(Guid activityGuid)
        {
            if (activityGuid == Guid.Empty) return false;

            using (var query = Factory.CreateT_SA_StoreActivity())
            {
                return query.IsExist(m => m.MerchantGuid == CurrentManage.MerchantGuid && m.StoreActivityGuid == activityGuid);
            }
        }

        private static Result CheckActivity(T_SA_StoreActivity activity, T_SA_StoreCoupons coupons)
        {
            if (activity == null) return new Result(false, "活动不能为空！");

            if (coupons == null) return new Result(false, "优惠券信息不能为空！");

            if (string.IsNullOrEmpty(activity.ActivityName)) return new Result(false, "活动名称不能为空！");

            if (activity.StartDate == null) return new Result(false, "活动开始时间不能为空！");

            if (activity.EndDate == null) return new Result(false, "活动结束时间不能为空！");

            if (activity.EndDate < activity.StartDate) return new Result(false, "活动结束时间不能小于开始时间！");

            if (coupons.Amount == null) return new Result(false, "面额不能为空！");

            if (coupons.Amount <= 0) return new Result(false, "面额必须大于0");

            if (coupons.EachNum == null) return new Result(false, "每人限领不能为空！");

            if (coupons.EachNum <= 0) return new Result(false, "每人限额必须大于0");

            if (coupons.TotalNum == null) return new Result(false, "发放总数量不能为空！");

            if (coupons.TotalNum <= 0) return new Result(false, "发放总数量必须大于0");

            if (coupons.ServiceConditions == null) return new Result(false, "请选择使用条件！");

            if (coupons.ServiceConditions < 1 || coupons.ServiceConditions > 2) return new Result(false, "使用条件选择无效！");

            if (coupons.ServiceConditions == 2 && coupons.ServiceConditionsMoney == null) return new Result(false, "使用条件金额不能为空！");

            if (coupons.ServiceConditions == 2 && coupons.ServiceConditionsMoney <= 0) return new Result(false, "使用条件金额必须大于0！");

            if (coupons.ValidityType == null) return new Result(false, "请选择有效期！");

            if (coupons.ValidityType < 1 || coupons.ValidityType > 2) return new Result(false, "有效期选择无效！");

            if (coupons.ValidityType == 1 && coupons.ValidityDays == null) return new Result(false, "有效天数不能为空！");

            if (coupons.ValidityType == 1 && coupons.ValidityDays <= 0) return new Result(false, "有效天数必须大于0！");

            if (coupons.ValidityType == 2 && coupons.ValidityStartDate == null) return new Result(false, "有效开始时间不能为空！");

            if (coupons.ValidityType == 2 && coupons.ValidityEndDate == null) return new Result(false, "有效结束时间不能为空！");

            if (coupons.ValidityType == 2 && coupons.ValidityEndDate < coupons.ValidityStartDate) return new Result(false, "有效结束时间不能小于于有效开始时间！");

            return new Result(true);
        }

        #endregion

        #region 逻辑处理

        /// <summary>
        /// 关闭活动
        /// </summary>        
        public static Result CloseActivity(Guid activityGuid)
        {
            var activity = GetActivity(activityGuid);

            if (activity == null) return new Result(false, "活动不存在！");

            if (activity.State == DictionaryConst.ActivityState.Closed) return new Result(false, "活动已关闭，不需要重新关闭！");

            using (var query = Factory.CreateT_SA_StoreActivity())
            {
                query.Update(m => new object[]{
                    m.State == DictionaryConst.ActivityState.Closed,                   
                }, v => v.StoreActivityGuid == activityGuid);
            }
            return new Result(true);
        }

        /// <summary>
        /// 当前状态
        /// </summary>
        public static int CurrentState(int state, DateTime startDate, DateTime endDate)
        {
            if (state == DictionaryConst.ActivityState.Closed) return state;

            if (state != DictionaryConst.ActivityState.Normal) return DictionaryConst.ActivityState.Unknown;

            if (DateTime.Now < startDate) return DictionaryConst.ActivityState.NotBeginning;

            if (DateTime.Now > endDate) return DictionaryConst.ActivityState.End;

            return DictionaryConst.ActivityState.Show;
        }

        /// <summary>
        /// 当前状态
        /// </summary>
        public static int CurrentState(T_SA_StoreActivity activity)
        {
            if (activity == null) return DictionaryConst.ActivityState.Unknown;

            return CurrentState(activity.State.Value, activity.StartDate.Value, activity.EndDate.Value);
        }

        #endregion
    }
}
