package com.liquidnet.service.consumer.base.receiver;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.type.TypeReference;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.HttpUtil;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.consumer.base.service.IBaseDao;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.stream.MapRecord;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.stream.StreamListener;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.Map;

@Slf4j
public abstract class AbstractXlsRedisReceiver implements StreamListener<String, MapRecord<String, String, String>> {
    @Autowired
    private IBaseDao baseDao;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Value("${liquidnet.service.goblin.url}")
    private String goblinUrl;

    private static final String SQL_INSERT_GOODS_BUY_ROSTER_LOG = "INSERT INTO goblin_goods_buy_roster_log (sku_id,buy_roster,buy_roster_type,parsing_result,created_at)VALUES(?,?,?,?,?)";

    @Override
    public void onMessage(MapRecord<String, String, String> message) {
        String redisStreamKey = this.getRedisStreamKey();
        log.debug("CONSUMER MSG[streamKey:{},messageId:{},stream:{},body:{}]", redisStreamKey, message.getId(), message.getStream(), message.getValue());
        boolean result = this.consumerMessageHandler(message.getValue());
        log.info("XLS MESSAGE CONSUMER MSG RESULT:{} ==> [{}]MESSAGE_ID:{}", result, redisStreamKey, message.getId());

        try {
            stringRedisTemplate.opsForStream().acknowledge(getRedisStreamGroup(), message);
        } catch (Exception e) {
            log.error("#CONSUMER MSG EX_ACK ==> [{}]RESULT:{},MESSAGE:{}", redisStreamKey, result, message.getValue(), e);
        }
        try {
            stringRedisTemplate.opsForStream().delete(redisStreamKey, message.getId());
        } catch (Exception e) {
            log.error("#CONSUMER MSG EX_DEL ==> [{}]RESULT:{},MESSAGE:{}", redisStreamKey, result, message.getValue(), e);
        }
    }

    private boolean consumerMessageHandler(Map<String, String> message) {
        LinkedList<Object[]> objs = CollectionUtil.linkedListObjectArr();
        String xlsPath = null, skuId = null;
        String oXlsPath = null;
        Integer type = null;
        boolean aBoolean = false;
        try {
            String[] path = message.get("message").split(",");
            if (path.length == 0) {
                xlsPath = "";
            } else {
                xlsPath = path[0];
            }
            if (path.length > 1) {
                oXlsPath = path[1];
            }
            String finalSkuId = (skuId = message.get("skuId"));
            String listId;
            listId = message.getOrDefault("listId", "");
            Integer finalType = (type = Integer.parseInt(message.get("type")));
            if (finalType.equals(1) || finalType.equals(2)) {
                MultiValueMap<String, String> params = new LinkedMultiValueMap();
                params.add("finalSkuId", finalSkuId);
                params.add("finalType", finalType.toString());
                params.add("xlsPath", xlsPath);
                MultiValueMap<String, String> headers = CollectionUtil.linkedMultiValueMapStringString();
                headers.add("Accept", "application/json;charset=UTF-8");
                String returnData = HttpUtil.post(goblinUrl + "/goblin/inner/consumerType12", params, headers);
                ResponseDto<Boolean> rsp = JsonUtils.fromJson(returnData, new TypeReference<ResponseDto<Boolean>>() {});

                objs.add(new Object[]{skuId, xlsPath, type, 1, LocalDateTime.now()});
                aBoolean = baseDao.batchSql(SQL_INSERT_GOODS_BUY_ROSTER_LOG, objs);
            } else if (finalType.equals(3) || finalType.equals(4)) {
                MultiValueMap<String, String> params = new LinkedMultiValueMap();
                params.add("finalSkuId", finalSkuId);
                params.add("finalType", finalType.toString());
                params.add("xlsPath", xlsPath);
                params.add("oXlsPath", oXlsPath);
                params.add("listId", listId);
                MultiValueMap<String, String> headers = CollectionUtil.linkedMultiValueMapStringString();
                headers.add("Accept", "application/json;charset=UTF-8");
                String returnData = HttpUtil.post(goblinUrl + "/goblin/inner/consumerType34", params, headers);
                ResponseDto<Boolean> rsp = JsonUtils.fromJson(returnData, new TypeReference<ResponseDto<Boolean>>() {});

                aBoolean = true;
            }
        } catch (Exception e) {
            log.error("CONSUMER MSG EX_HANDLE ==> [{}]:{}", this.getRedisStreamKey(), message, e);
            try {
                if (type.equals(1) || type.equals(2)) {
                    objs.add(new Object[]{skuId, xlsPath, type, 2, LocalDateTime.now()});
                    aBoolean = baseDao.batchSql(SQL_INSERT_GOODS_BUY_ROSTER_LOG, objs);
                }
            } catch (Exception ignored) {
            }
        }
        return aBoolean;
    }

    protected abstract String getRedisStreamKey();

    protected abstract String getRedisStreamGroup();
}