using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Service;
using Hncore.Pass.Sells.Domain;
using Hncore.Pass.Sells.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static Hncore.Pass.Sells.Domain.Enums;
using Hncore.Infrastructure.Extension;
namespace Hncore.Pass.Sells.Service
{
    public class CouponService : ServiceBase<CouponEntity>, IFindService
    {
        CourseContext m_DbContext;
        CouponUserOrginService m_CouponUserOrginService;       
        public CouponService(CouponUserOrginService m_CouponUserOrginService          
            , CourseContext dbContext
            , IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
        {
            m_DbContext = dbContext;
            this.m_CouponUserOrginService = m_CouponUserOrginService;          
        }

        public async Task<bool> Give(int couponId, string fromUser, int toUser, int count, CouponOriginType originType= CouponOriginType.Admin, string remark = "系统赠送", string toUserRef="暂无")
        {
            var orginCoupon = new CouponUserOrginEntity()
            {
                CouponCount = count,
                CouponId = couponId,
                Remark = originType.GetEnumDisplayName(),
                From = fromUser,
                ToUser = toUser,
                OriginType= originType,
                ToUserRef= toUserRef
            };
            var coupon = await this.GetById(couponId);
            if (coupon == null || coupon.Disabled == 1)
                return false;
            using (var tran = await m_DbContext.Database.BeginTransactionAsync())
            {
                try
                {
                    if (coupon.DateRule == ECouponDateRule.BeginCurrent)
                    {
                        orginCoupon.StartTime = DateTime.Now;
                        orginCoupon.EndTime = DateTime.Now.AddDays(coupon.ValidDay);
                    }
                    else if (coupon.DateRule == ECouponDateRule.BeginMorrow)
                    {
                        orginCoupon.StartTime = DateTime.Now.AddDays(1);
                        orginCoupon.EndTime = DateTime.Now.AddDays(coupon.ValidDay + 1);
                    }
                    else
                    {
                        orginCoupon.StartTime = coupon.StartDate;
                        orginCoupon.EndTime = coupon.EndDate;
                    }

                    await m_CouponUserOrginService.Add(orginCoupon);
                    coupon.GrantCount++;
                    await this.Update(coupon);
                    tran.Commit();
                }
                catch (Exception ex)
                {
                    LogHelper.Error("Give", ex);
                    tran.Rollback();
                    return false;
                }

            }
            return true;
        }


        public async Task<List<UserCouponModel>> GetUserCoupon(int userId)
        {
            var oroginCoupons = m_CouponUserOrginService.Query(m => m.ToUser == userId && m.Status == CouponStatus.Origin && DateTime.Now <= m.EndTime);

            var hasCoupon = from orgin in oroginCoupons
                            join coupon in this.Query(true) on orgin.CouponId equals coupon.Id
                            select new UserCouponModel { Count = 1, UserId = orgin.ToUser.Value, Coupon = coupon, Orgin = orgin };

            return await hasCoupon.ToListAsync();
        }

        public async Task<bool> Use(int couponId, string orderNo, int userId, int count)
        {
            var userOrginCoupons = await GetUserAvailableCoupon(userId);

            var oneCoupon = userOrginCoupons.OrderBy(m => m.ValidDays).FirstOrDefault();
            if (oneCoupon == null)
                return false;
            oneCoupon.Orgin.Status = CouponStatus.Used;
            await m_CouponUserOrginService.Update(oneCoupon.Orgin);
            return true;
        }

        public async Task<List<UserCouponModel>> GetUserAvailableCoupon(int userId)
        {    
            var oroginCoupons=m_CouponUserOrginService.Query(m =>m.ToUser==userId&& m.Status == CouponStatus.Origin && m.ToUser == userId && DateTime.Now > m.StartTime && DateTime.Now <= m.EndTime);

            var hasCoupon = from orgin in oroginCoupons
                            join coupon in this.Query(true) on orgin.CouponId equals coupon.Id
                            select new UserCouponModel { Count =1,UserId=orgin.ToUser.Value, Coupon = coupon, Orgin = orgin };

            return await hasCoupon.ToListAsync();
        }

        public async Task<UserCouponModel> GetOneUserAvailableCoupon(int userId,int couponId)
        {
            var oroginCoupons = m_CouponUserOrginService.Query(m => m.ToUser == userId && m.Status == CouponStatus.Origin && m.ToUser == userId && DateTime.Now > m.StartTime && DateTime.Now <= m.EndTime);

            oroginCoupons=oroginCoupons.Where(m => m.CouponId == couponId);
            var hasCoupon = from orgin in oroginCoupons
                            join coupon in this.Query(true) on orgin.CouponId equals coupon.Id
                            select new UserCouponModel { Count = 1, UserId = orgin.ToUser.Value, Coupon = coupon, Orgin = orgin };

            return await hasCoupon.FirstOrDefaultAsync();
        }



        public async Task<bool> TaoBaoGive(int userId, int couponId,string taobao)
        {
            return await this.Give(couponId, "", userId, 1, CouponOriginType.TaoBao,"系统赠送",taobao);
        }

        public async Task<bool> Freeze(int originId)
        {
            var entity = await m_CouponUserOrginService.GetById(originId);
            entity.Status = CouponStatus.Disabled;
            await m_CouponUserOrginService.Update(entity);
            return true;
        }
    }
}
