package com.yc.ship.module.marketing.dal.mysql.coupon;

import cn.hutool.core.date.DateUtil;
import com.yc.ship.framework.common.enums.CommonStatusEnum;
import com.yc.ship.framework.common.pojo.PageResult;
import com.yc.ship.framework.mybatis.core.mapper.BaseMapperX;
import com.yc.ship.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.yc.ship.module.marketing.controller.admin.coupon.vo.CouponPageReqVO;
import com.yc.ship.module.marketing.dal.dataobject.coupon.CouponDO;
import com.yc.ship.module.marketing.enums.coupon.CouponAuditStateEnum;
import com.yc.ship.module.marketing.enums.coupon.CouponDeliverUserGroupType;
import com.yc.ship.module.marketing.enums.coupon.CouponUseChannelEnum;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.List;
import java.util.Objects;

/**
 * 优惠券 Mapper
 *
 * @author lfy
 */
@Mapper
public interface CouponMapper extends BaseMapperX<CouponDO> {

    default PageResult<CouponDO> selectPage(CouponPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<CouponDO>()
                .likeIfPresent(CouponDO::getName, reqVO.getName())
                .eqIfPresent(CouponDO::getType, reqVO.getType())
                .eqIfPresent(CouponDO::getUseChannel, reqVO.getUseChannel())
                .eqIfPresent(CouponDO::getUseAfter, reqVO.getUseAfter())
                .eqIfPresent(CouponDO::getAuditState, reqVO.getAuditState())
                .eqIfPresent(CouponDO::getState, reqVO.getState())
                .eqIfPresent(CouponDO::getDescription, reqVO.getDescription())
                .betweenIfPresent(CouponDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(CouponDO::getId));
    }

    /**
     * 获取可以领取的优惠券列表
     * @param groupId
     * @param isNewUser
     * @return
     */
    default List<CouponDO> selectCanReceiveCouponList(Long groupId, Boolean isNewUser) {
        return selectList(new LambdaQueryWrapperX<CouponDO>()
                .eq(CouponDO::getAuditState, CouponAuditStateEnum.AUDIT_PASS.getType())
                .eq(CouponDO::getState, CommonStatusEnum.ENABLE.getStatus())
                .eq(CouponDO::getUseChannel, CouponUseChannelEnum.ONLINE.getType())
                .le(CouponDO::getDeliverStart, DateUtil.now())
                .ge(CouponDO::getDeliverEnd, DateUtil.now())
                .and(i ->
                        i.eq(CouponDO::getDeliverUserGroupType, CouponDeliverUserGroupType.ALL.getType())
                                .or(isNewUser,j -> j.eq(CouponDO::getDeliverUserGroupType, CouponDeliverUserGroupType.NEW_USER.getType()))
                                .or(!Objects.isNull(groupId),k -> k.eq(CouponDO::getDeliverUserGroupType, CouponDeliverUserGroupType.SOME_USER.getType()).like(CouponDO::getDeliverUserGroup, groupId))
                )
        );
    }

    @Select("select t2.id coupon_code_id, t1.*,t2.create_time get_time from coupon t1 left join coupon_code t2 on t1.id = t2.coupon_id  where t1.deleted = 0 and t2.deleted = 0 and t2.member_id = #{memberId} and t1.audit_state = 1 and t1.state = 0 and t2.state = 0 and ((t1.effective_type =1 and t1.effective_start <= now() and t1.effective_end >= now()) or (t1.effective_type = 2 and DATE_ADD(t2.create_time,INTERVAL t1.effective_time MINUTE) >= now())) order by t2.create_time desc")
    List<CouponDO> selectReceivedCouponList(Long memberId);

    /**
     * 获取可以使用的优惠券
     * @param memberId
     * @return
     */
    @Select("SELECT t2.id coupon_code_id,t3.relation_child_id, t1.*,t2.create_time get_time,t3.type relation_type,t3.relation_id,t3.relation_sku_id FROM coupon t1 LEFT JOIN coupon_code t2 ON t1.id = t2.coupon_id LEFT JOIN coupon_product t3 ON t1.id = t3.coupon_id WHERE t2.member_id = #{memberId} AND t2.state = 0 AND t1.audit_state = 1 AND t1.state = 0 AND t2.deleted = 0 AND t1.deleted = 0 AND t3.deleted = 0 AND ((t1.effective_type = 1 and t1.effective_start <= #{travelDate} and t1.effective_end >= #{travelDate}) or (t1.effective_type = 2 and DATE_ADD(t2.create_time,INTERVAL t1.effective_time MINUTE) <= #{travelDate})) order by t2.create_time desc")
    List<CouponDO> selectCanUseCouponList(@Param("memberId") Long memberId, @Param("travelDate") String travelDate);

    /**
     * 获取我的未使用优惠券列表
     * @param loginUserId
     * @return
     */
    @Select("select t2.id coupon_code_id, t1.*,t2.create_time get_time from coupon t1 left join coupon_code t2 on t1.id = t2.coupon_id  where t1.deleted = 0 and t2.deleted = 0 and t2.member_id = #{memberId} and t1.audit_state = 1 and t1.state = 0 and t2.state = 0 and ((t1.effective_type =1 and t1.effective_end >= now()) or (t1.effective_type = 2 and DATE_ADD(t2.create_time,INTERVAL t1.effective_time MINUTE) >= now())) order by t2.create_time desc")
    List<CouponDO> selectMyUnUseCouponList(Long loginUserId);
    /**
     * 获取我的已使用优惠券列表
     * @param loginUserId
     * @return
     */
    @Select("select t2.id coupon_code_id, t1.*,t2.create_time get_time from coupon t1 left join coupon_code t2 on t1.id = t2.coupon_id  where t1.deleted = 0 and t2.deleted = 0 and t2.member_id = #{memberId} and t2.state = 1 order by t2.create_time desc")
    List<CouponDO> selectMyUsedCouponList(Long loginUserId);

    /**
     * 获取我的已过期优惠券列表
     * @param loginUserId
     * @return
     */
    @Select("select t2.id coupon_code_id, t1.*,t2.create_time get_time from coupon t1 left join coupon_code t2 on t1.id = t2.coupon_id  where t1.deleted = 0 and t2.deleted = 0 and t2.member_id = #{memberId} and t1.audit_state = 1 and t1.state = 0 and t2.state = 0 and ((t1.effective_type =1 and t1.effective_end < now()) or (t1.effective_type = 2 and DATE_ADD(t2.create_time,INTERVAL t1.effective_time MINUTE) < now())) order by t2.create_time desc")
    List<CouponDO> selectMyExpiredCouponList(Long loginUserId);

    /**
     * 根据优惠券码ID获取优惠券
     * @param couponCodeId
     * @return
     */
    @Select("select t2.id coupon_code_id, t1.*,t2.create_time get_time from coupon t1 right join coupon_code t2 on t1.id = t2.coupon_id  where t2.id = #{couponCodeId}")
    CouponDO selectByCouponCodeId(Long couponCodeId);
}