package com.iformall.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.iformall.common.ErrorCode;
import com.iformall.common.IdWorker;
import com.iformall.domain.po.*;
import com.iformall.domain.po.msg.SmartAppMsg;
import com.iformall.enums.*;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.WxCUserMapper;
import com.iformall.mapper.WxCouponMapper;
import com.iformall.mapper.WxOrderMapper;
import com.iformall.mapper.WxOrderPressMapper;
import com.iformall.mq.MqBaseProducer;
import com.iformall.service.WxMsgLimitService;
import com.iformall.service.WxOrderPressService;
import com.iformall.utils.DateUtils;
import com.iformall.utils.PressUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

@Service
public class WxOrderPressServiceImpl implements WxOrderPressService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
    WxOrderPressMapper wxOrderPressMapper;

	@Autowired
    WxOrderMapper wxOrderMapper;

    @Autowired
    WxCouponMapper wxCouponMapper;

	@Autowired
    WxCUserMapper userMapper;

    @Autowired
    WxMsgLimitService wxMsgLimitService;

    @Autowired
    MqBaseProducer mqBaseProducer;


    @Override
    public PageInfo<WxOrderPress> listAsPage(WxOrderPress record, Integer pageIndex, Integer pageSize) {
        return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxOrderPressMapper.findList(record));
    }

    @Override
    public WxOrderPress getById(Long id) {
        return wxOrderPressMapper.selectById(id);
    }

    @Override
    public void saveOrUpdate(WxOrderPress record) {
        if (record.getId() == null) {
            //record.setId(UUID.randomUUID().toString().replaceAll("-", ""));
            final IdWorker idWorker = IdWorker.get();
        	record.setId(idWorker.nextId());
            wxOrderPressMapper.insert(record);
        } else {
            wxOrderPressMapper.updateById(record);
        }
    }

    @Override
    public void deleteById(Long id) {
        wxOrderPressMapper.deleteById(id);
    }


    @Override
    public void pressCouponJoin(WxOrder order, WxCoupon coupon, Long cUserId) {
        final IdWorker idWorker = IdWorker.get();
        Date curDate = new Date();
        // 检查此人是否已参与砍价
        WxOrderPress orderPressQ = new WxOrderPress();
        orderPressQ.setTenantId(order.getTenantId());
        orderPressQ.setOrderId(order.getId());
        orderPressQ.setUserId(cUserId);
        QueryWrapper<WxOrderPress> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(orderPressQ);
        int count = wxOrderPressMapper.selectCount(queryWrapper);
        if(count >= 1) {
            logger.error("用户已参与砍价: " + cUserId);
            throw new MallinkException(ErrorCode.COUPON_PRESS_IS_EXIST);
        }

        // 添加 wx_order_press
        int total = coupon.getPrice() - coupon.getSalePrice();
        int left_total = order.getPressCurrentValue();
        WxOrderPress orderPress = new WxOrderPress();
        orderPress.setId(idWorker.nextId());
        orderPress.setTenantId(order.getTenantId());
        orderPress.setCouponId(order.getProductId());
        orderPress.setOrderId(order.getId());
        orderPress.setUserId(cUserId);
        orderPress.setCreateDate(curDate);
        orderPress.setFirst(EnumOrderPressType.NORMAL.getCode());
        orderPress.setPressValue(PressUtils.stateLessPressValue(total, left_total, coupon.getPressLimitNum(), order.getPressCurrentNum()));

        try {
            // 保存订单
            wxOrderPressMapper.insert(orderPress);
        } catch (RuntimeException e) {
            logger.error("保存砍价记录Error：" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL);
        }

        // 更新砍价信息
        Integer index = order.getPressCurrentNum() + 1;
        WxOrder orderUpdatePress = new WxOrder();
        orderUpdatePress.setId(order.getId());
        orderUpdatePress.setPressCurrentNum(index);
        orderUpdatePress.setPressCurrentValue(left_total - orderPress.getPressValue());
        if(index.equals(coupon.getPressLimitNum())) {
            orderUpdatePress.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PRESS_COMPLETE.getCode());
            orderUpdatePress.setPayment(coupon.getSalePrice());
        } else {
            orderUpdatePress.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PRESSING.getCode());
        }
        orderUpdatePress.setUpdateDate(new Date());
        try {
            // 保存订单
            wxOrderMapper.updateById(orderUpdatePress);
        } catch (RuntimeException e) {
            logger.error("更新订单Error：" + e.getMessage());
            throw new MallinkException(ErrorCode.DB_FAIL);
        }
        // 发送砍价成功消息
        if(index.equals(coupon.getPressLimitNum())) {
            sendPressComplateMsg(orderUpdatePress);
        }
    }

    @Override
    public int pressCouponStatus(WxOrder order, Long cUserId) {
        // 检查此人是否已参与砍价
        WxOrderPress orderPressQ = new WxOrderPress();
        orderPressQ.setTenantId(order.getTenantId());
        orderPressQ.setOrderId(order.getId());
        orderPressQ.setUserId(cUserId);
        QueryWrapper<WxOrderPress> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(orderPressQ);
        int count = wxOrderPressMapper.selectCount(queryWrapper);
        if(count >= 1) {
            logger.info("用户已参与砍价: " + cUserId);
            return EnumOrderPressStatus.HAD_JOIN.getCode();
        }
        return EnumOrderPressStatus.NOT_JOIN.getCode();
    }

    /**
     * 微信模板消息
     *
     * @param
     */
    private void sendPressComplateMsg(WxOrder orderUpdatePress) {
        // 1. get order info
        WxOrder order = wxOrderMapper.selectById(orderUpdatePress.getId());
        if (order == null) {
            logger.error("找不到订单信息");
            throw new MallinkException(ErrorCode.ORDER_IS_NOT_FIND);
        }
        // 2. get coupon info
        WxCoupon coupon = wxCouponMapper.selectById(order.getProductId());
        if (order == null) {
            logger.error("找不到券信息");
            throw new MallinkException(ErrorCode.COUPON_IS_EMPTY);
        }
        // 3. get user info
        WxCUser user = userMapper.selectById(order.getCUserId());
        if (user == null) {
            logger.error("找不到C端用户");
            throw new MallinkException(ErrorCode.USER_IS_EMPTY);
        }

        String gotopage = "pages/index/index?type=mb";

        // 小程序 消息
        String formId = null;
        Date curDate = new Date();
        Date dateAfter7Day = DateUtils.getHourTimeAfter(7, order.getCreateDate());
        if(StringUtils.isNotBlank(order.getFormId()) && curDate.before(dateAfter7Day)
                && !order.getFormId().equalsIgnoreCase("undefined")) {
            formId = order.getFormId();
        }
        int formType = EnumMsgLimitType.WEAPP_FORMID.getCode();

        if(StringUtils.isBlank(formId)) {
            logger.error("无可用formId, 不能发小程序模板消息");
            return;
        }

        // 9. 微信小程序-模板消息
        /**
         * 检查 小程序模板消息是否超限
         */
        WxMsgLimit msgLimit = new WxMsgLimit();
        msgLimit.setTenantId(user.getTenantId());
        msgLimit.setType(formType);
        msgLimit.setLimitId(formId);
        if(wxMsgLimitService.checkIsLimit(msgLimit)) {
            // 已达到限制条件，不发消息了
            logger.error("已达到限制条件，不发小程序模板消息了: " + user.getId());
            return;
        }
        // mq发送小程序消息 - 核销成功消息
        doPressSuccessMsg(coupon, user, formId, gotopage);
    }

    private void doPressSuccessMsg(WxCoupon coupon, WxCUser user, String formId, String gotopage) {
        SmartAppMsg smartAppMsg;
        /**
         * 砍价成功消息
         * 商品名称 {{keyword1.DATA}}
         * 商品原价 {{keyword2.DATA}}
         * 付款剩余时间 {{keyword3.DATA}}
         * 支付截止时间 {{keyword4.DATA}}
         * 支付金额 {{keyword5.DATA}}
         * 温馨提示 {{keyword6.DATA}}
         */
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) +1);// 让日期加1h
        System.out.println(calendar.get(Calendar.DATE));// 加1之后的日期Top
        System.out.println();
        smartAppMsg = new SmartAppMsg();
        smartAppMsg.setMsgType(EnumMsgRecordType.SMART_APP.getCode());
        smartAppMsg.setAppId(user.getAppId());
        smartAppMsg.setTenantId(user.getTenantId());
        smartAppMsg.setTemplateType(EnumTemplateType.PRESS_SUCCESS.getCode());
        smartAppMsg.setGotopage(gotopage);
        smartAppMsg.setTo(user.getOpenId());
        smartAppMsg.setFormId(formId);
        smartAppMsg.setDataList(Lists.newArrayList(
                coupon.getTitle(),
                coupon.getPriceStr(),
                "1小时",
                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime()),
                coupon.getSalePriceStr(),
                user.getNickName()
        ));

        try {
            mqBaseProducer.sendMessage(smartAppMsg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
        } catch (Exception e) {
            logger.error("砍价成功通知发送失败: " + e.getMessage());
            throw new MallinkException(ErrorCode.TEMPLATE_SEND_FAILED);
        }
    }
    
    
    
    
    
}
