package com.hai.service.impl;

import com.hai.common.exception.ErrorCode;
import com.hai.common.exception.ErrorHelp;
import com.hai.common.exception.SysCode;
import com.hai.dao.HighDiscountUserRelMapper;
import com.hai.entity.*;
import com.hai.service.*;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
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.Map;

/**
 * @Auther: 胡锐
 * @Description:
 * @Date: 2021/4/4 15:12
 */
@Service("highDiscountUserRelService")
public class HighDiscountUserRelServiceImpl implements HighDiscountUserRelService {

    @Resource
    private HighDiscountUserRelMapper highDiscountUserRelMapper;

    @Resource
    private HighDiscountAgentRelService highDiscountAgentRelService;

    @Resource
    private HighAgentService highAgentService;

    @Resource
    private HighDiscountService highDiscountService;

    @Resource
    private HighDiscountAgentCodeService highDiscountAgentCodeService;

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW,isolation= Isolation.SERIALIZABLE)
    public void receiveDiscount(Long userId, Long codeId) {

        // 查询优惠券二维码
        HighDiscountAgentCode code = highDiscountAgentCodeService.getCodeById(codeId);
        if(code == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "二维码不存在");
        }
        // 状态 0：删除  1：待领取  2：待使用  3：已使用  4：已过期  5: 已分配
        if(code.getStatus() != 1 && code.getStatus() != 5) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "二维码不存在或已被领取");
        }
        code.setStatus(2);
        highDiscountAgentCodeService.updateCode(code);

        // 查询优惠券信息
        HighDiscountAgentRel rel = highDiscountAgentRelService.getRelById(code.getDiscountAgentId());
        if (rel == null || rel.getHighDiscount() == null || rel.getAgentId() == null){
            throw ErrorHelp.genException(SysCode.System, ErrorCode.NOT_FOUND_DISCOUNT, "");
        }
        rel.setStockCount(rel.getStockCount() - 1);
        highDiscountAgentRelService.updateDiscountAgentRel(rel);

        // 查询优惠券信息
        HighDiscount discount = highDiscountService.getDiscountById(rel.getDiscountId());
        if (discount == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的优惠券信息");
        }
        if (!discount.getStatus().equals(2)) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "无法领取，优惠券活动已过期");
        }
        if (discount.getReceiveNumber() > 0 && this.receiveDiscountCount(userId, discount.getId()).intValue() >= discount.getReceiveNumber().intValue()) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "优惠券已达到上线");
        }

        // 校验卡卷状态
        if (rel.getHighDiscount().getStatus() != 2) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "无法领取，优惠券已过期");
        }
/*        if (rel.getStockCount() <= 0) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.DISCOUNT_STOCK_COUNT_ERROR, "");
        }

        // 校验是否重复领取
        HighDiscountUserRelExample example = new HighDiscountUserRelExample();
        example.createCriteria().andUserIdEqualTo(userId).andDiscountIdEqualTo(rel.getDiscountId()).andStatusEqualTo(1);
        if (highDiscountUserRelMapper.selectByExample(example).size() > 0) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "重复领取卡券,请使用后再进行领取");
        }*/

        HighDiscountUserRel userRel = new HighDiscountUserRel();
        userRel.setDiscountId(rel.getDiscountId());
        userRel.setAgentId(rel.getAgentId());
        userRel.setUserId(userId);
        userRel.setStatus(1);   // 状态  0:已过期  1：未使用  2：已使用
        userRel.setCreateTime(new Date());
        userRel.setDiscountAgentCodeId(code.getId());
        // 计算使用有效期
        Calendar userEndTime = Calendar.getInstance();
        userEndTime.setTime(new Date());
        userEndTime.set(Calendar.HOUR_OF_DAY, 23);
        userEndTime.set(Calendar.MINUTE, 59);
        userEndTime.set(Calendar.SECOND, 59);
        userEndTime.add(Calendar.DATE, rel.getHighDiscount().getEffectiveDay());

        if (userEndTime.getTime().compareTo(rel.getHighDiscount().getSalesEndTime()) == 1) {
            userRel.setUseEndTime(rel.getHighDiscount().getSalesEndTime());
        } else {
            userRel.setUseEndTime(userEndTime.getTime());
        }
        highDiscountUserRelMapper.insert(userRel);

    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW,isolation= Isolation.SERIALIZABLE)
    public void receive(Long userId, Long discountAgentId) {
        // 查询优惠券与代理商关系
        HighDiscountAgentRel discountAgentRel = highDiscountAgentRelService.getRelById(discountAgentId);
        if (discountAgentRel == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知优惠券");
        }
        // 查询优惠券信息
        HighDiscount discount = discountAgentRel.getHighDiscount();
        if (discount == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知优惠券");
        }
        if (!discount.getStatus().equals(2)) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "无法领取，优惠券活动已过期");
        }
        if (discount.getReceiveNumber() > 0 && this.receiveDiscountCount(userId, discount.getId()) >= discount.getReceiveNumber()) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "领取数量已达到上线");
        }
        // 查询可分配的优惠券code
        List<HighDiscountAgentCode> discountAgentCodeList = highDiscountAgentCodeService.getDiscountCodeByStatus(discountAgentRel.getId(), 1);
        if (discountAgentCodeList.size() == 0) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "优惠券已无库存");
        }
        HighDiscountAgentCode code = discountAgentCodeList.get(0);
        code.setStatus(2);
        highDiscountAgentCodeService.updateCode(code);

        // 查询优惠券信息
        discountAgentRel.setStockCount(discountAgentRel.getStockCount() - 1);
        highDiscountAgentRelService.updateDiscountAgentRel(discountAgentRel);

        HighDiscountUserRel userRel = new HighDiscountUserRel();
        userRel.setDiscountId(discountAgentRel.getDiscountId());
        userRel.setAgentId(discountAgentRel.getAgentId());
        userRel.setUserId(userId);
        userRel.setStatus(1);   // 状态  0:已过期  1：未使用  2：已使用
        userRel.setCreateTime(new Date());
        userRel.setDiscountAgentCodeId(code.getId());
        // 计算使用有效期
        Calendar userEndTime = Calendar.getInstance();
        userEndTime.setTime(new Date());
        userEndTime.set(Calendar.HOUR_OF_DAY, 23);
        userEndTime.set(Calendar.MINUTE, 59);
        userEndTime.set(Calendar.SECOND, 59);
        userEndTime.add(Calendar.DATE, discountAgentRel.getHighDiscount().getEffectiveDay());

        if (userEndTime.getTime().compareTo(discountAgentRel.getHighDiscount().getSalesEndTime()) == 1) {
            userRel.setUseEndTime(discountAgentRel.getHighDiscount().getSalesEndTime());
        } else {
            userRel.setUseEndTime(userEndTime.getTime());
        }
        highDiscountUserRelMapper.insert(userRel);
    }

    @Override
    public void updateDiscountUserRel(HighDiscountUserRel highDiscountUserRel) {
        highDiscountUserRelMapper.updateByPrimaryKey(highDiscountUserRel);
    }

    @Override
    public HighDiscountUserRel getRelByUserDiscount(Long userId, Long discountId) {
        HighDiscountUserRelExample example = new HighDiscountUserRelExample();
        example.createCriteria().andUserIdEqualTo(userId).andDiscountIdEqualTo(discountId);
        List<HighDiscountUserRel> list = highDiscountUserRelMapper.selectByExample(example);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public HighDiscountUserRel getRelByDiscount(Long discountId) {
        HighDiscountUserRelExample example = new HighDiscountUserRelExample();
        example.createCriteria().andDiscountAgentCodeIdEqualTo(discountId);
        List<HighDiscountUserRel> list = highDiscountUserRelMapper.selectByExample(example);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public HighDiscountUserRel getRelById(Long id) {
        HighDiscountUserRel rel = highDiscountUserRelMapper.selectByPrimaryKey(id);
        if(rel != null) {
            rel.setHighDiscount(highDiscountService.getDiscountById(rel.getDiscountId()));
            rel.setHighAgent(highAgentService.findByAgentMsgId(rel.getAgentId()));
        }
        return rel;
    }

    @Override
    public List<HighDiscountUserRel> getDiscountList(Map<String, Object> map) {
        HighDiscountUserRelExample example = new HighDiscountUserRelExample();
        HighDiscountUserRelExample.Criteria criteria = example.createCriteria();

        if (MapUtils.getLong(map, "userId") != null) {
            criteria.andUserIdEqualTo(MapUtils.getLong(map, "userId"));
        }

        if (MapUtils.getInteger(map, "status") != null) {
            criteria.andStatusEqualTo(MapUtils.getInteger(map, "status"));
        }

        example.setOrderByClause("create_time desc");
        List<HighDiscountUserRel> list = highDiscountUserRelMapper.selectByExample(example);
        for (HighDiscountUserRel rel : list) {
            rel.setHighDiscount(highDiscountService.getDiscountById(rel.getDiscountId()));
            rel.setHighAgent(highAgentService.findByAgentMsgId(rel.getAgentId()));
        }
        return list;
    }

    @Override
    public List<HighDiscountUserRel> getExpiredDiscount() {
        HighDiscountUserRelExample example = new HighDiscountUserRelExample();
        example.createCriteria().andStatusEqualTo(1).andUseEndTimeLessThanOrEqualTo(new Date());
        return highDiscountUserRelMapper.selectByExample(example);
    }

    @Override
    public Integer receiveDiscountCount(Long userId, Long discountId) {
        return highDiscountUserRelMapper.receiveDiscountCount(userId, discountId);
    }
}
