package com.ms.biz.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ms.biz.consts.DoudianMsgConst;
import com.ms.biz.consts.StatusConst;
import com.ms.dal.entity.*;
import com.ms.biz.service.DoudianMsgService;
import com.ms.dal.mapper.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 *
 */
@Slf4j
@Service
public class DoudianMsgServiceImpl implements DoudianMsgService{

    @Autowired
    private DoudianMsgMapper doudianMsgMapper;

    @Autowired
    private DoudianMsgParseQueueMapper doudianMsgParseQueueMapper;

    @Autowired
    private DdTradeMsgMapper ddTradeMsgMapper;

    @Autowired
    private DoudianTradeMsgBufferMapper doudianTradeMsgBufferMapper;

    @Autowired
    private DdAftersaleMsgMapper ddAftersaleMsgMapper;

    @Autowired
    private DoudianAftersaleMsgBufferMapper doudianAftersaleMsgBufferMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public int deleteByPrimaryKey(Long id) {
        return doudianMsgMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(DoudianMsg record) {
        return doudianMsgMapper.insert(record);
    }

    @Override
    public int insertSelective(DoudianMsg record) {
        return doudianMsgMapper.insertSelective(record);
    }

    @Override
    public DoudianMsg selectByPrimaryKey(Long id) {
        return doudianMsgMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(DoudianMsg record) {
        return doudianMsgMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(DoudianMsg record) {
        return doudianMsgMapper.updateByPrimaryKey(record);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addDoudianMsg(String msgBody) {
        DoudianMsg doudianMsgData = new DoudianMsg();
        doudianMsgData.setMsgBody(msgBody);
        doudianMsgData.setStatus(StatusConst.wait);
        doudianMsgData.setGmtCreate(new Date());
        doudianMsgData.setGmtModified(new Date());
        doudianMsgMapper.insertSelective(doudianMsgData);

        DoudianMsgParseQueue doudianMsgParseQueueData = new DoudianMsgParseQueue();
        doudianMsgParseQueueData.setDoudianMsgId(doudianMsgData.getDoudianMsgId());
        doudianMsgParseQueueData.setLocked(0L);
        doudianMsgParseQueueData.setGmtCreate(new Date());
        doudianMsgParseQueueData.setGmtModified(new Date());
        doudianMsgParseQueueMapper.insertSelective(doudianMsgParseQueueData);

        redisTemplate.opsForList().leftPush("doudian_msg_parse_queue", String.valueOf(doudianMsgParseQueueData.getDoudianMsgParseQueueId()));

        return true;
    }

    @Override
    public DoudianMsgParseQueue lockDoudianMsgParseQueue() {
        String queueRedisKey = "doudian_msg_parse_queue";
        String queueId = redisTemplate.opsForList().rightPop(queueRedisKey);
        if (StringUtils.isEmpty(queueId)) {
            return null;
        }

        DoudianMsgParseQueue row = doudianMsgParseQueueMapper.selectUnlockRowByQueueId(Long.valueOf(queueId));

        if (row == null) {
            return null;
        }

        DoudianMsgParseQueue updateData = new DoudianMsgParseQueue();
        updateData.setDoudianMsgParseQueueId(row.getDoudianMsgParseQueueId());
        row.setLocked(1L);
        row.setGmtLastHeartbeat(new Date());
        row.setGmtLocked(new Date());
        row.setGmtModified(new Date());
        int affRow = doudianMsgParseQueueMapper.updateByPrimaryKeySelective(row);
        if (affRow == 1) {
            return row;
        }

        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean processDoudianMsgParseQueue(Long doudianMsgId) {
        if (doudianMsgId == null) {
            return false;
        }
        DoudianMsg doudianMsgInfo = doudianMsgMapper.selectByPrimaryKey(doudianMsgId);
        if (doudianMsgInfo == null) {
            return false;
        }
        List<String> msgList = JSON.parseArray(doudianMsgInfo.getMsgBody(), String.class);
        List<String> shopIds = new ArrayList<>();
        for (String msg : msgList) {
            JSONObject msgItem = JSONObject.parseObject(msg);
            JSONObject currentMsgData = JSONObject.parseObject(msgItem.getString("data"));
            if (currentMsgData.containsKey("shop_id")) {
                shopIds.add(currentMsgData.get("shop_id").toString());
            } else {
                log.info(String.format("timer doudian_msg shop_id_empty doudianMsgId{%s} msgBody: %s", doudianMsgId, doudianMsgInfo.getMsgBody()));
            }
        }

        List<DdTradeMsg> doudianTradeMsgDatas = new ArrayList<>();
        List<DoudianTradeMsgBuffer> doudianTradeMsgBufferDatas = new ArrayList<>();
        List<DdAftersaleMsg> aftersaleMsgsDatas = new ArrayList<>();
        List<DoudianAftersaleMsgBuffer> aftersaleMsgBufferDatas = new ArrayList<>();

        for (String msg : msgList) {
            JSONObject msgItem = JSONObject.parseObject(msg);
            Map currentMsgData = JSONObject.parseObject(msgItem.getString("data"), Map.class);
            Long shopId = Long.valueOf(currentMsgData.get("shop_id").toString());

            if (DoudianMsgConst.ALL_TRADE_TAGS.contains(Integer.valueOf(msgItem.get("tag").toString()))) {
                DdTradeMsg msgObj = new DdTradeMsg();
                msgObj.setMsgId(msgItem.get("msg_id").toString());
                msgObj.setShopId(shopId);
                msgObj.setTag(Integer.valueOf(msgItem.get("tag").toString()));
                msgObj.setData(msgItem.get("data").toString());
                msgObj.setStatus(StatusConst.wait);
                msgObj.setGmtCreate(new Date());
                msgObj.setGmtModified(new Date());
                doudianTradeMsgDatas.add(msgObj);

                DoudianTradeMsgBuffer buffer = new DoudianTradeMsgBuffer();
                buffer.setMsgId(msgItem.get("msg_id").toString());
                buffer.setShopId(shopId);
                buffer.setGmtCreate(new Date());
                buffer.setGmtModified(new Date());
                doudianTradeMsgBufferDatas.add(buffer);
            }

            if (DoudianMsgConst.ALL_AFTERSALE_TAGS.contains(Integer.valueOf(msgItem.get("tag").toString()))) {
                DdAftersaleMsg msgObj = new DdAftersaleMsg();
                msgObj.setMsgId(msgItem.get("msg_id").toString());
                msgObj.setShopId(shopId);
                msgObj.setTag(Integer.valueOf(msgItem.get("tag").toString()));
                msgObj.setData(msgItem.get("data").toString());
                msgObj.setStatus(StatusConst.wait);
                msgObj.setGmtCreate(new Date());
                msgObj.setGmtModified(new Date());
                aftersaleMsgsDatas.add(msgObj);

                DoudianAftersaleMsgBuffer buffer = new DoudianAftersaleMsgBuffer();
                buffer.setMsgId(msgItem.get("msg_id").toString());
                buffer.setShopId(shopId);
                buffer.setGmtCreate(new Date());
                buffer.setGmtModified(new Date());
                aftersaleMsgBufferDatas.add(buffer);
            }
        }
        // 插入分好类的数据
        for (DdTradeMsg item : doudianTradeMsgDatas) {
            ddTradeMsgMapper.insertSelective(item);
        }
        for (DoudianTradeMsgBuffer item : doudianTradeMsgBufferDatas) {
            doudianTradeMsgBufferMapper.insertSelective(item);
        }
        for (DdAftersaleMsg item : aftersaleMsgsDatas) {
            ddAftersaleMsgMapper.insertSelective(item);
        }
        for (DoudianAftersaleMsgBuffer item : aftersaleMsgBufferDatas) {
            doudianAftersaleMsgBufferMapper.insertSelective(item);
        }
        DoudianMsg updateDoudianMsg = new DoudianMsg();
        updateDoudianMsg.setDoudianMsgId(doudianMsgId);
        updateDoudianMsg.setStatus(StatusConst.success);
        updateDoudianMsg.setGmtModified(new Date());
        doudianMsgMapper.updateByPrimaryKeySelective(updateDoudianMsg);

        return true;
    }

    @Override
    public void failProcessDoudianMsgParseQueue(Long doudianMsgId) {
        DoudianMsg updateDoudianMsg = new DoudianMsg();
        updateDoudianMsg.setDoudianMsgId(doudianMsgId);
        updateDoudianMsg.setStatus(StatusConst.fail);
        updateDoudianMsg.setReason("插入数据失败");
        updateDoudianMsg.setGmtModified(new Date());
        doudianMsgMapper.updateByPrimaryKeySelective(updateDoudianMsg);
    }

    @Override
    public boolean deleteDoudianMsgParseQueue(Long queueId) {
        int affRow = doudianMsgParseQueueMapper.deleteByPrimaryKey(queueId);
        return affRow > 0;
    }
}




