package com.docus.server.collect.report.noview;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.docus.core.util.Func;
import com.docus.core.util.MapObjUtil;
import com.docus.server.archivefile.infrastructure.entity.CollectsysDictionary;
import com.docus.server.archivefile.service.IAfCollectSysDictionaryService;
import com.docus.server.collect.web.common.DocusProperties;
import com.docus.server.collect.web.common.NoViewChNewbornProperties;
import com.docus.server.collect.web.common.NoViewProperties;
import com.docus.server.collect.web.common.dto.NoViewCollectionDto;
import com.docus.server.collect.web.common.dto.NoViewConfig;
import com.docus.server.collect.web.common.dto.ViewReportTwoDto;
import com.docus.server.collect.web.enums.DisposeModeEnum;
import com.docus.server.collect.web.enums.HospitalEnum;
import com.docus.server.collect.web.enums.RedisKeyEnum;
import com.docus.server.collect.web.utils.MqQueueUtils;
import com.docus.server.collect.web.utils.RedisMq;
import com.docus.server.common.message.MqMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 无视图
 */
@Component("defNoViewJobResultImpl")
@Slf4j
public class DefNoViewJobResultImpl
    extends AbstractNoViewJobResultImpl<List<Map<String, Object>>> {

    @Resource
    private NoViewProperties noViewProperties;
    @Resource
    private NoViewChNewbornProperties noViewChNewbornProperties;
    @Resource
    private DocusProperties docusProperties;
    @Resource(name = "defRedis")
    private RedisMq redisMq;
    @Resource
    private IAfCollectSysDictionaryService collectSysDictionaryService;
    @Resource
    private AmqpTemplate amqpTemplate;
    @Resource
    MqQueueUtils mqQueueUtils;

    @Override
    public void handle(List<Map<String, Object>> results, String param) {
        super.handle(results, param);

        NoViewCollectionDto collectionDto = com.docus.core.util.json.JSON.fromJSON(param, NoViewCollectionDto.class);

        if (Func.isBlank(param)) {
            return;
        }

        List<ViewReportTwoDto> list = new ArrayList<>();
        for (Map<String, Object> map : results) {
            ViewReportTwoDto viewReportTwoDto = MapObjUtil.map2ObjectUnderlined(map, ViewReportTwoDto.class);
            viewReportTwoDto.setIspriority(collectionDto.getPriority());
            list.add(viewReportTwoDto);
        }
        try {
            GenerateQueue(list, collectionDto);
        } catch (Exception ex) {
            log.error("发送队列信息失败，错误信息：" + ex.getMessage() + "." + JSON.toJSONString(collectionDto));
        }


    }

    private void GenerateQueue(List<ViewReportTwoDto> list, NoViewCollectionDto collectionDto) {
        String syscodes = collectionDto.getSyscodes();
        List<NoViewConfig> configs = collectionDto.getNoviewconfig();
        Map<String, Object> queuemerge = collectionDto.getQueuemerge();
        List<CollectsysDictionary> collectsysDictionaries = collectSysDictionaryService.findCollectSysDictionarys();
        if (!StringUtils.isEmpty(syscodes)) {
            List<String> collectids = Arrays.asList(syscodes.split(","));
            collectsysDictionaries = collectsysDictionaries.stream().filter(t -> collectids.contains(t.getSysCode())).collect(Collectors.toList());
            if (null == collectsysDictionaries) {
                log.error("无可用采集器");
                return;
            }
        }
        for (CollectsysDictionary o : collectsysDictionaries) {
            List<ViewReportTwoDto> disposedata = chDispose(list, o.getSysCode());
            disposedata = Dispose(disposedata, o.getSysCode(), configs);
            if (null == disposedata || disposedata.size() <= 0) {
                continue;
            }
            disposedata.forEach(k -> {
                k.setCollectorId(o.getSysCode());
                if (docusProperties.getMode().equals(DisposeModeEnum.mq)) {
                    MqMessage mqMessage = new MqMessage();
                    String mqKey = String.format("topic_task_%s_queue", getQueueKey(o.getSysCode(), queuemerge));
                    mqQueueUtils.DeclareQueue(mqKey);
                    mqMessage.setMessageBody(JSON.toJSONString(k, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.WriteMapNullValue));
                    amqpTemplate.convertAndSend("", mqKey, mqMessage);
                }
                if (docusProperties.getMode().equals(DisposeModeEnum.redis)) {
                    redisMq.push(RedisKeyEnum.QUEUEREDISKEY, JSON.toJSONString(k, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.WriteMapNullValue));
                }
            });
        }
    }

    private static String getQueueKey(String sysCode, Map<String, Object> queuemerge) {
        if (Func.isNull(queuemerge)) {
            return sysCode;
        }
        for (Map.Entry<String, Object> merge : queuemerge.entrySet()) {
            if (Arrays.asList(String.valueOf(merge.getKey()).split(StrUtil.COMMA)).contains(sysCode)) {
                if (StrUtil.isBlank(String.valueOf(merge.getValue())) || "null".equals(String.valueOf(merge.getValue()))) {
                    return sysCode;
                } else {
                    return String.valueOf(merge.getValue());
                }
            }
        }
        // 合并 主键包含 sysCode，则返回对应的 QueueCode
        return sysCode;
    }

    /**
     * 澄海数据处理
     *
     * @param list
     * @param syscode
     * @return
     */
    private List<ViewReportTwoDto> chDispose(List<ViewReportTwoDto> list, String syscode) {
        List<ViewReportTwoDto> datas = new ArrayList<>();
        if (!(HospitalEnum.ch.value() == noViewProperties.getHospital() && syscode.equals(noViewChNewbornProperties.getSyscode()))) {
            return list;
        }
        datas = list.stream().filter(t -> t.getDisDeptName().equals(noViewChNewbornProperties.getDisdeptname())).collect(Collectors.toList());
        return datas;
    }

    /**
     * 指定队列，指定科室数据处理
     *
     * @param list
     * @param syscode
     * @return
     */
    private List<ViewReportTwoDto> Dispose(List<ViewReportTwoDto> list, String syscode, List<NoViewConfig> configs) {
        List<ViewReportTwoDto> datas = new ArrayList<>();
        if (null == configs || configs.size() == 0) {
            return list;
        }
        NoViewConfig config = configs.stream().filter(t -> t.getSyscode().equals(syscode)).findFirst().orElse(null);
        if (null == config) {
            return list;
        }
        datas = list.stream().filter(t -> t.getDisDeptName().equals(config.getDeptname())).collect(Collectors.toList());
        return datas;
    }
}
