package com.ym.mec.biz.service.impl;

import com.ym.mec.biz.dal.dao.SysCouponDao;
import com.ym.mec.biz.dal.entity.SysCoupon;
import com.ym.mec.biz.dal.enums.MessageTypeEnum;
import com.ym.mec.biz.dal.page.SysCouponQueryInfo;
import com.ym.mec.biz.service.SysCouponService;
import com.ym.mec.biz.service.SysMessageService;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.common.tenant.TenantContextHolder;
import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
import com.ym.mec.util.collection.MapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
public class SysCouponServiceImpl extends BaseServiceImpl<Integer, SysCoupon> implements SysCouponService {

    @Autowired
    private SysCouponDao sysCouponDao;
    @Autowired
    private SysMessageService sysMessageService;

    @Override
    public BaseDAO<Integer, SysCoupon> getDAO() {
        return sysCouponDao;
    }

    @Override
    public PageInfo<SysCoupon> queryPage(SysCouponQueryInfo queryInfo) {
        PageInfo<SysCoupon> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
        Map<String, Object> params = new HashMap<String, Object>();
        MapUtil.populateMap(params, queryInfo);

        List<SysCoupon> dataList = new ArrayList<>();
        int count = this.findCount(params);
        if (count > 0) {
            pageInfo.setTotal(count);
            params.put("offset", pageInfo.getOffset());
            dataList = this.getDAO().queryPage(params);
        }
        pageInfo.setRows(dataList);
        return pageInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public void updateCoupon(SysCoupon sysCoupon) {
        SysCoupon oldCoupon = sysCouponDao.lockCoupon(sysCoupon.getId());
        if (Objects.isNull(oldCoupon)) {
            throw new BizException("优惠券信息不存在");
        }
        //如果已经有人领取，则只能修改库存总量与预警值
        if (oldCoupon.getConsumeNum() > 0) {
            if (oldCoupon.getStatus() == 0) {
                oldCoupon.setStockCount(sysCoupon.getStockCount());
                oldCoupon.setWarningStockNum(sysCoupon.getWarningStockNum());
            }
            if (oldCoupon.getStockCount() == -1) {
                oldCoupon.setWarningStockNum(-1);
            }
            oldCoupon.setStatus(sysCoupon.getStatus());
            if (oldCoupon.getStockCount() - oldCoupon.getConsumeNum() > oldCoupon.getWarningStockNum()) {
                oldCoupon.setWarningStatus(0);
            }
            oldCoupon.setUseCondition(sysCoupon.getUseCondition());
            sysCouponDao.update(oldCoupon);
        } else {
            switch (sysCoupon.getType()) {
                case DISCOUNT:
                    if (Objects.isNull(sysCoupon.getFaceValue())) {
                        throw new BizException("请指定折扣比例");
                    }
                    sysCoupon.setFullAmount(null);
                    break;
                case FULL_REDUCTION:
                    if (Objects.isNull(sysCoupon.getFaceValue())) {
                        throw new BizException("请指定优惠金额");
                    }
                    if (Objects.isNull(sysCoupon.getFullAmount())) {
                        throw new BizException("请指定达标金额");
                    }
                    break;
                default:
                    throw new BizException("请指定优惠券类型");
            }
            switch (sysCoupon.getEffectiveType()) {
                case DAYS:
                    if (Objects.isNull(sysCoupon.getDeadline())) {
                        throw new BizException("请指定有效天数");
                    }
                    sysCoupon.setEffectiveStartTime(null);
                    sysCoupon.setEffectiveExpireTime(null);
                    break;
                case TIME_BUCKET:
                    if (Objects.isNull(sysCoupon.getEffectiveStartTime()) || Objects.isNull(sysCoupon.getEffectiveExpireTime())) {
                        throw new BizException("请指定有效时间段");
                    }
                    sysCoupon.setDeadline(null);
                    break;
                default:
                    throw new BizException("请指定有效期类型");
            }
            if (sysCoupon.getStockCount() == -1) {
                sysCoupon.setWarningStockNum(-1);
            }
            sysCoupon.setTenantId(TenantContextHolder.getTenantId());
            sysCouponDao.update(sysCoupon);
        }
    }

    @Async
    @Override
    public void stockWarning(Integer couponId, String couponName) {
        Map<Integer, String> teacherPhoneMap = new HashMap<>();
        teacherPhoneMap.put(2112251, "13618651329");
        sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.YIMEI, MessageTypeEnum.COUPON_STOCK_WARNING,
                teacherPhoneMap, null, 0, null, null,
                couponName);
    }

    /**
     * 新增优惠券
     *
     * @param sysCoupon
     */
    public long add(SysCoupon sysCoupon) {
        sysCoupon.setStatus(0);
        sysCoupon.setConsumeNum(0);
        sysCoupon.setWarningStatus(0);
        sysCoupon.setTenantId(TenantContextHolder.getTenantId());
        if (Objects.isNull(sysCoupon.getType())) {
            throw new BizException("请指定优惠券类型");
        }

        switch (sysCoupon.getType()) {
            case DISCOUNT:
                if (Objects.isNull(sysCoupon.getFaceValue())) {
                    throw new BizException("请指定折扣比例");
                }
                break;
            case FULL_REDUCTION:
                if (Objects.isNull(sysCoupon.getFaceValue())) {
                    throw new BizException("请指定优惠金额");
                }
                if (Objects.isNull(sysCoupon.getFullAmount())) {
                    throw new BizException("请指定达标金额");
                }
                if (sysCoupon.getFaceValue().compareTo(sysCoupon.getFullAmount()) > 0) {
                    throw new BizException("优惠的金额不能超过优惠券满减额度");
                }
                break;
            default:
                throw new BizException("请指定优惠券类型");
        }
        switch (sysCoupon.getEffectiveType()) {
            case DAYS:
                if (Objects.isNull(sysCoupon.getDeadline())) {
                    throw new BizException("请指定有效天数");
                }
                break;
            case TIME_BUCKET:
                if (Objects.isNull(sysCoupon.getEffectiveStartTime()) || Objects.isNull(sysCoupon.getEffectiveExpireTime())) {
                    throw new BizException("请指定有效时间段");
                }
                break;
            default:
                throw new BizException("请指定有效期类型");
        }
        return sysCouponDao.insert(sysCoupon);
    }

}
