package com.ruoyi.web.service;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.mxjb.domain.MultipleWayData;
import com.ruoyi.mxjb.domain.MxjbMultipleWayAsset;
import com.ruoyi.mxjb.domain.MxjbMultipleWayCond;
import com.ruoyi.mxjb.domain.MxjbMultipleWayForm;
import com.ruoyi.mxjb.mapper.MxjbMultipleWayAssetMapper;
import com.ruoyi.mxjb.mapper.MxjbMultipleWayCondMapper;
import com.ruoyi.mxjb.mapper.MxjbMultipleWayFormMapper;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.web.domain.MultipleWayReportDto;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class MultipleWayService {
    private final MxjbMultipleWayFormMapper mxjbMultipleWayFormMapper;
    private final MxjbMultipleWayAssetMapper mxjbMultipleWayAssetMapper;
    private final MxjbMultipleWayCondMapper mxjbMultipleWayCondMapper;
    private final ISysDictDataService sysDictDataService;
    private final ISysConfigService sysConfigService;

    Map<String, List<MxjbMultipleWayCond>> dcsMap = Maps.newHashMap();
    Map<String, List<String>> dictTypeMap = Maps.newHashMap(); // 配置列表或字典列表
    Map<String, Map<String, String>> dictTypeValueMap = Maps.newHashMap(); // 字典值转换(默认是label，暂不用转换)

    public MultipleWayService(MxjbMultipleWayFormMapper mxjbMultipleWayFormMapper, MxjbMultipleWayAssetMapper mxjbMultipleWayAssetMapper, MxjbMultipleWayCondMapper mxjbMultipleWayCondMapper, ISysDictDataService sysDictDataService, ISysConfigService sysConfigService) {
        this.mxjbMultipleWayFormMapper = mxjbMultipleWayFormMapper;
        this.mxjbMultipleWayAssetMapper = mxjbMultipleWayAssetMapper;
        this.mxjbMultipleWayCondMapper = mxjbMultipleWayCondMapper;
        this.sysDictDataService = sysDictDataService;
        this.sysConfigService = sysConfigService;
        refresh();
    }

    public AjaxResult submitMultipleWayForm(MultipleWayData.MultipleWayForm form) {
        refresh();
        MultipleWayDecider decider = new MultipleWayDecider(form, dcsMap, dictTypeMap, dictTypeValueMap);
        List<MultipleWayData.MultipleWayConclusion> conclusionList = decider.determine();
        MxjbMultipleWayForm f = new MxjbMultipleWayForm();
        f.setUserId(SecurityUtils.getLoginUser().getUserId());
        f.setCreatedTime(new Date());
        f.setName(SecurityUtils.getLoginUser().getUsername() + new SimpleDateFormat("yyyyMMssHHmmss").format(f.getCreatedTime()));
        f.setContent(new MultipleWayData(form, null));
        f.setConclusion(new MultipleWayData(null, conclusionList));
        if (null != form.getFormId()) {
            f.setFormId(form.getFormId());
            mxjbMultipleWayFormMapper.updateMxjbMultipleWayForm(f);
        } else {
            mxjbMultipleWayFormMapper.insertMxjbMultipleWayForm(f);
        }
        return AjaxResult.success("保存成功!", f.getFormId());
    }

    public MxjbMultipleWayForm getMxjbMultipleWayForm(Long formId) {
        return mxjbMultipleWayFormMapper.selectMxjbMultipleWayFormByFormId(formId);
    }

    public MultipleWayReportDto getMultipleWayConclusions(Long formId) {
         return getMultipleWayConclusions(mxjbMultipleWayFormMapper.selectMxjbMultipleWayFormByFormId(formId));
    }

    public MultipleWayReportDto getMultipleWayConclusions(MxjbMultipleWayForm form) {
        MultipleWayData conclusionData = form.getConclusion();
        List<MultipleWayData.MultipleWayConclusion> validList = Lists.newArrayList();
        List<MultipleWayData.MultipleWayConclusion> invalidList = Lists.newArrayList();

        if (null != conclusionData && CollectionUtils.isNotEmpty(conclusionData.getConclusionList())) {
            for(MultipleWayData.MultipleWayConclusion mac : conclusionData.getConclusionList()) {
                if (mac.getValid()) {
                    validList.add(mac);
                } else {
                    invalidList.add(mac);
                }
            }
        }
        MultipleWayReportDto report = new MultipleWayReportDto();
        report.setCreatedTime(form.getCreatedTime());
        report.setContent(form.getContent().getForm());
        report.setValidList(validList);
        report.setInvalidList(invalidList);
        return report;
    }

    public List<MxjbMultipleWayForm> getMultipleWayHistories(Integer pageNum, Integer pageSize) {
        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
        MxjbMultipleWayForm formCond = new MxjbMultipleWayForm();
        formCond.setUserId(userId);
        List<MxjbMultipleWayForm> formList = mxjbMultipleWayFormMapper.selectMxjbMultipleWayFormSimpleList(formCond);
        return formList;
    }

    public int deleteMultipleWayHistories(Long[] ids) {
        return mxjbMultipleWayFormMapper.deleteMxjbMultipleWayFormByFormIds(ids);
    }

    private void refresh() {
        Map<Integer, MxjbMultipleWayAsset> tmpAssetMap = mxjbMultipleWayAssetMapper.selectMxjbMultipleWayAssetList(new MxjbMultipleWayAsset()).stream().collect(
                Collectors.toMap(MxjbMultipleWayAsset::getId, Function.identity()));

        Map<String, List<MxjbMultipleWayCond>> tmpDirectionCondsMap = Maps.newHashMap();
        Set<String> dictTypeList = Sets.newHashSet();
        Set<String> dictTypeValueList = Sets.newHashSet();
        Set<String> confTypeList = Sets.newHashSet();
        for (MxjbMultipleWayCond c : mxjbMultipleWayCondMapper.selectMxjbMultipleWayCondList(new MxjbMultipleWayCond())) {
            List<MxjbMultipleWayCond> condList = tmpDirectionCondsMap.get(c.getDirection());
            if(null == condList) {
                condList = Lists.newArrayList();
                tmpDirectionCondsMap.put(c.getDirection(), condList);
            }
            MxjbMultipleWayAsset a = tmpAssetMap.get(c.getCondId());
            c.setAsset(a);
            condList.add(c);
            if ("字典列表".equals(a.getOptionType())) {
                dictTypeList.add(MultipleWayDecider.getOptionValue(c, a));
            } else if ("配置".equals(a.getOptionType())) {
                confTypeList.add(MultipleWayDecider.getOptionValue(c, a));
            } else if ("字典值".equals(a.getOptionType())) {
                dictTypeValueList.add(a.getOptionValues());
            }
        }
        Map<String, List<String>> tmpDictTypeMap = Maps.newHashMap();
        Map<String, Map<String, String>> tmpDictTypeValueMap = Maps.newHashMap();
        for (String type : dictTypeList) {
            List<String> values = sysDictDataService.selectDictDataByType(type).stream().map(t -> t.getDictValue()).collect(Collectors.toList());
            tmpDictTypeMap.put(type, values);
        }
        for(String conf : confTypeList) {
            if (StringUtils.isNotBlank(conf)) {
                String confValue = sysConfigService.selectConfigByKey(conf);
                tmpDictTypeMap.put(conf, StringUtils.isNotBlank(confValue) ? Arrays.asList(confValue.split(",")) : Lists.newArrayList());
            }
        }
        for (String type : dictTypeValueList) {
            Map<String, String> valuesMap = sysDictDataService.selectDictDataByType(type).stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
            tmpDictTypeValueMap.put(type, valuesMap);
        }
        dcsMap = tmpDirectionCondsMap;
        dictTypeMap = tmpDictTypeMap;
        dictTypeValueMap = tmpDictTypeValueMap;
    }
}
