package com.ruoyi.member.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.base.domain.BaseCard;
import com.ruoyi.base.service.IBaseCardService;
import com.ruoyi.base.vo.BaseCardVO;
import com.ruoyi.common.config.DlRightsConfig;
import com.ruoyi.common.core.domain.DlBaseEntity;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.constant.DictConstants;
import com.ruoyi.member.domain.MemberCard;
import com.ruoyi.member.domain.MemberOrder;
import com.ruoyi.member.domain.MemberRights;
import com.ruoyi.member.mapper.MemberCardMapper;
import com.ruoyi.member.mapper.MemberRightsMapper;
import com.ruoyi.member.service.IMemberCardService;
import com.ruoyi.member.service.IMemberFootprintService;
import com.ruoyi.member.service.IMemberRightsService;
import com.ruoyi.member.vo.MemberRightsVO;
import com.ruoyi.member.vo.ViewRightsVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 会员开卡记录Service业务层处理
 *
 * @author pqz
 * @date 2025-03-17
 */
@Service
public class MemberCardServiceImpl extends ServiceImpl<MemberCardMapper, MemberCard> implements IMemberCardService {
    @Autowired
    private MemberCardMapper memberCardMapper;
    @Resource
    private IBaseCardService baseCardService;
    @Autowired
    private IMemberRightsService rightsService;
    @Autowired
    private MemberRightsMapper memberRightsMapper;
    @Resource
    private IMemberFootprintService footprintService;


    /**
     * 通过用户id查询会员开卡记录
     *
     * @param userId 用户id
     * @return java.util.List<com.ruoyi.member.domain.MemberCard>
     * @author PQZ
     * @date 14:24 2025/3/21
     **/
    @Override
    public List<MemberCard> listByUserId(Long userId, String userType) {
        //查询列表
        LambdaUpdateWrapper<MemberCard> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper
                .eq(DlBaseEntity::getDelFlag, 0)
                .eq(MemberCard::getUserId, userId)
                .eq(MemberCard::getUserType, userType)
                .orderByDesc(DlBaseEntity::getCreateTime);
        return list(lambdaUpdateWrapper);
    }

    /**
     * 会员开卡处理
     *
     * @param userId   用户id
     * @param userType 用户类型
     * @param cardId   卡id
     * @param cycle    时间
     * @param orderId  订单id
     * @author PQZ
     * @date 18:06 2025/3/31
     **/
    @Override
    public void dealMemberCard(Long userId, String userType, String cardId, String cycle, String orderId) {
        /*1、数据初始化*/
        //查询会员卡
        BaseCardVO card = baseCardService.queryByCardId(cardId);
        //查询当前时间是否存在有效会员卡
        List<MemberCard> cardList = checkMemberCard(cardId, userId);

        /*2、计算到期时间*/
        Date startTime;
        Date endTime;
        if (cardList.isEmpty()) {
            //计算到期时间
            startTime = new Date();
            endTime = getEndTime(startTime, cycle);
            //新增时需要处理会员权益
            rightsService.dealRights(userId, userType, card.getRights());
        } else {
            startTime = cardList.get(0).getEndDate();
            endTime = getEndTime(startTime, cycle);
        }

        /*3、保存会员开卡记录*/
        //初始化会员开通记录
        MemberCard memberCard = new MemberCard();
        memberCard.setUserId(userId);
        memberCard.setUserType(userType);
        memberCard.setCardId(cardId);
        memberCard.setOrderId(orderId);
        memberCard.setCardName(card.getCardName());
        memberCard.setStartDate(startTime);
        memberCard.setEndDate(endTime);
        save(memberCard);
    }

    /**
     * 查询会员卡开卡记录
     *
     * @param cardId 卡id
     * @param userId 用户id
     * @return java.util.List<com.ruoyi.member.domain.MemberCard>
     * @author PQZ
     * @date 16:09 2025/3/27
     **/
    private List<MemberCard> checkMemberCard(String cardId, Long userId) {
        Date time = new Date();
        LambdaQueryWrapper<MemberCard> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper
                .eq(MemberCard::getCardId, cardId)
                .eq(MemberCard::getUserId, userId)
                .eq(DlBaseEntity::getDelFlag, 0)
                .lt(MemberCard::getStartDate, time)
                .ge(MemberCard::getEndDate, time);
        return list(lambdaQueryWrapper);
    }

    /**
     * 获取会员结束时间
     *
     * @param date 当前时间
     * @param type 类型（01:1个月；02:1季度；03:1年）
     * @return java.util.Date
     * @author PQZ
     * @date 16:40 2025/3/26
     **/
    private Date getEndTime(Date date, String type) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        switch (type) {
            case "01":
                calendar.add(Calendar.MONTH, 1);
                break;
            case "02":
                calendar.add(Calendar.MONTH, 3);
                break;
            case "03":
                calendar.add(Calendar.YEAR, 1);
                break;
            case "04":
                calendar.add(Calendar.YEAR, 100);
                break;
            default:
                throw new IllegalArgumentException("无效的时间类型: " + type);
        }
        return calendar.getTime();
    }

    /**
     * 查当前会员权益列表
     *
     * @param userId   用户id
     * @param userType 用户类型
     * @author vinjor-M
     * @date 11:26 2025/3/26
     **/
    @Override
    public Map<String, Map<String, ViewRightsVO>> selectMemberRights(Long userId, String userType) {
        Map<String, Map<String, ViewRightsVO>> rtnMap = new HashMap<>();
        //当前时间
        String nowDate = DateUtil.formatDate(new Date());
        if (null == userId) {
            userId = SecurityUtils.getUserId();
        }
        List<MemberCard> cardList = memberCardMapper.selectCardIdByUserId(userId, userType, nowDate);
        if (cardList.isEmpty()) {
            //未开通任何会员卡
            rtnMap.put("tgz", new HashMap<>());
            rtnMap.put("bz", new HashMap<>());
        } else {
            //开通会员卡了，根据会员卡id，查询出所有权益
            List<MemberRights> memberRightsList = memberRightsMapper.selectUserRightsByCardIds(cardList.stream().map(MemberCard::getCardId).collect(Collectors.toList()), userId);
            //通告主权益
            Map<String, ViewRightsVO> tgzRightsMap = new HashMap<>();
            //博主权益
            Map<String, ViewRightsVO> bzRightsMap = new HashMap<>();
            memberRightsList.forEach(item -> {
                if (DictConstants.USER_TYPE_TGZ.equals(item.getUserType())) {
                    //通告主
                    this.checkRights(tgzRightsMap, item);
                } else if (DictConstants.USER_TYPE_BZ.equals(item.getUserType())) {
                    //博主
                    this.checkRights(bzRightsMap, item);
                }
            });
            rtnMap.put("tgz", tgzRightsMap);
            rtnMap.put("bz", bzRightsMap);
        }
        return rtnMap;
    }

    /**
     * 获取当日可报名次数
     *
     * @param userId   用户id
     * @param userType 类型
     * @return java.lang.Integer
     * @author PQZ
     * @date 17:27 2025/3/31
     **/
    @Override
    public Integer getCardRightsValue(Long userId, String userType,String rightsCode) {
        //查询当前用户在当前时间有无正在服役的会员卡
        List<MemberCard> memberCards = getMemberCards(userId, userType);
        if (memberCards.isEmpty()) {
            return 0;
        } else {
            return rightsService.getMemberRightsValue(memberCards.get(0).getUserId(), memberCards.get(0).getCardId(),rightsCode);
        }
    }

    /**
     * 查询当前登录用户有无正在服役的会员卡
     *
     * @param userId   用户id
     * @param userType 用户类型
     * @return java.util.List<com.ruoyi.member.domain.MemberCard>
     * @author PQZ
     * @date 14:28 2025/4/17
     **/
    private List<MemberCard> getMemberCards(Long userId, String userType) {
        //查询当前用户在当前时间有无正在服役的会员卡
        Date time = new Date();
        LambdaQueryWrapper<MemberCard> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(userType)) {
            lambdaQueryWrapper.eq(MemberCard::getUserType, userType);
        }
        lambdaQueryWrapper
                .eq(MemberCard::getUserId, userId)
                .eq(DlBaseEntity::getDelFlag, 0)
                .lt(MemberCard::getStartDate, time)
                .ge(MemberCard::getEndDate, time)
                .orderByDesc(DlBaseEntity::getCreateTime);
        return list(lambdaQueryWrapper);
    }

    /**
     * @param userId     用户id
     * @param rightsCode 权益编码
     * @param noticeId   通告id
     * @param deplete    扣的值
     * @author PQZ
     * @date 14:23 2025/4/17
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dealMemberRights(Long userId,String noticeId, String rightsCode, Integer deplete) throws Exception {
        //查询当前用户有无正在服役的通告主卡
        List<MemberCard> memberCards = getMemberCards(userId,null);
        if (memberCards.isEmpty()){
            throw new Exception("无正在服役的会员卡");
        }
        if ("unlock_notice".equals(rightsCode)) {
            if (noticeId == null){
                throw new Exception("无法识别当前通告");
            }
            //true表示有浏览记录，false表示没有浏览记录；如果当前用户在足迹表中未发现该通告。
            if (footprintService.checkFoot(noticeId,userId)){
                rightsService.dealMemberRights(userId,memberCards,rightsCode,deplete);
            }
        } else {
            rightsService.dealMemberRights(userId,memberCards,rightsCode,deplete);
        }

    }



    /**
     * @param userId     用户id
     * @param rightsCode 权益编码
     * @param noticeId   通告id
     * @param deplete    扣的值
     * @author PQZ
     * @date 14:23 2025/4/17
     **/
    @Override
    public void dealMemberRights2(Long userId,String noticeId, String rightsCode, Integer deplete) throws Exception {
        //查询当前用户有无正在服役的通告主卡
        List<MemberCard> memberCards = getMemberCards(userId,null);
        if (memberCards.isEmpty()){
            throw new Exception("无正在服役的会员卡");
        }
        if ("unlock_notice".equals(rightsCode)) {
            if (noticeId == null){
                throw new Exception("无法识别当前通告");
            }
            //true表示有浏览记录，false表示没有浏览记录；如果当前用户在足迹表中未发现该通告。
            if (footprintService.checkFoot(noticeId,userId)){
                rightsService.dealMemberRights(userId,memberCards,rightsCode,deplete);
            }
        } else {
            rightsService.dealMemberRights(userId,memberCards,rightsCode,deplete);
        }

    }
    /**
     * 查某用户某身份类型的会员卡到期时间，如果没有开通会员，那么返回null
     *
     * @param userId   用户id
     * @param userType 身份类型
     * @return java.lang.String
     * @author vinjor-M
     * @date 14:10 2025/4/25
     **/
    @Override
    public MemberCard getUserCardEndDate(Long userId, String userType) {
        List<MemberCard> memberCardList = memberCardMapper.selectMemberCardList(userId,userType,DateUtil.formatDateTime(new Date()));
        if(memberCardList.isEmpty()){
            return null;
        }
//        return DateUtil.formatDate(memberCardList.get(0).getEndDate());
        return memberCardList.get(0);
    }

    /**
     * @param memberRightsMap 会员权益map
     * @param item            这个权益
     * @author vinjor-M
     * @date 14:19 2025/3/26
     **/
    private void checkRights(Map<String, ViewRightsVO> memberRightsMap, MemberRights item) {
        ViewRightsVO newRights = new ViewRightsVO();
        BeanUtils.copyProperties(item, newRights);
        newRights.setRemaining(item.getRemaining());
        if (memberRightsMap.containsKey(item.getRightsCode())) {
            //有这个权益了
            ViewRightsVO oldRights = memberRightsMap.get(item.getRightsCode());
            if (DictConstants.RIGHTS_TYPE_NUMBER.equals(item.getRightsType()) &&
                    oldRights.getRemaining() < item.getRemaining()) {
                //权益类型是数量限制的，且新的权益剩余值比原来的大，取新的
                memberRightsMap.put(item.getRightsCode(), newRights);
            }
        } else {
            //没有这个权益，
            if(DictConstants.RIGHTS_TYPE_NUMBER.equals(item.getRightsType())){
                //数量限制的
                memberRightsMap.put(item.getRightsCode(), newRights);
            }else{
                //是否支持的
                if(1==item.getRightsValue()){
                    //支持，返回
                    memberRightsMap.put(item.getRightsCode(), newRights);
                }
            }

        }
    }
}
