package io.gisbi.visualization.server;

import io.gisbi.api.commons.BaseRspModel;
import io.gisbi.api.visualization.VisualizationLinkageApi;
import io.gisbi.api.visualization.dto.LinkageInfoDTO;
import io.gisbi.api.visualization.dto.VisualizationLinkageDTO;
import io.gisbi.api.visualization.request.VisualizationLinkageRequest;
import io.gisbi.api.visualization.vo.VisualizationLinkageFieldVO;
import io.gisbi.auth.DeLinkPermit;
import io.gisbi.chart.dao.auto.entity.CoreChartView;
import io.gisbi.chart.dao.auto.mapper.CoreChartViewMapper;
import io.gisbi.utils.BeanUtils;
import io.gisbi.utils.IDUtils;
import io.gisbi.visualization.dao.auto.entity.VisualizationLinkage;
import io.gisbi.visualization.dao.auto.entity.VisualizationLinkageField;
import io.gisbi.visualization.dao.auto.mapper.DataVisualizationInfoMapper;
import io.gisbi.visualization.dao.auto.mapper.VisualizationLinkageFieldMapper;
import io.gisbi.visualization.dao.auto.mapper.VisualizationLinkageMapper;
import io.gisbi.visualization.dao.ext.mapper.ExtVisualizationLinkageMapper;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author bi-coder
 * @date : 2023/7/13
 */
@RestController
@RequestMapping("linkage")
public class VisualizationLinkageService implements VisualizationLinkageApi {

    @Resource
    private ExtVisualizationLinkageMapper extVisualizationLinkageMapper;

    @Resource
    private VisualizationLinkageFieldMapper visualizationLinkageFieldMapper;

    @Resource
    private VisualizationLinkageMapper visualizationLinkageMapper;

    @Resource
    private DataVisualizationInfoMapper dataVisualizationInfoMapper;

    @Resource
    private CoreChartViewMapper coreChartViewMapper;

    @Override
    public Map<String, VisualizationLinkageDTO> getViewLinkageGather(VisualizationLinkageRequest request) {
        if (CollectionUtils.isNotEmpty(request.getTargetViewIds())) {
            List<VisualizationLinkageDTO> linkageDTOList = extVisualizationLinkageMapper.getViewLinkageGather(request.getDvId(), request.getSourceViewId(), request.getTargetViewIds());
            return linkageDTOList.stream().collect(Collectors.toMap(targetViewId ->String.valueOf(targetViewId), PanelViewLinkageDTO -> PanelViewLinkageDTO));
        }
        return new HashMap<>();
    }

    @Override
    public List<VisualizationLinkageDTO> getViewLinkageGatherArray(VisualizationLinkageRequest request) {
        return extVisualizationLinkageMapper.getViewLinkageGather(request.getDvId(), request.getSourceViewId(), request.getTargetViewIds());
    }

    @Override
    @Transactional
    public BaseRspModel saveLinkage(VisualizationLinkageRequest request) {
        Long updateTime = System.currentTimeMillis();
        List<VisualizationLinkageDTO> linkageInfo =  request.getLinkageInfo();
        Long sourceViewId = request.getSourceViewId();
        Long dvId = request.getDvId();

        Assert.notNull(sourceViewId, "source View ID can not be null");
        Assert.notNull(dvId, "dvId can not be null");

        // 清理原有关系
        extVisualizationLinkageMapper.deleteViewLinkageField(dvId, sourceViewId);
        extVisualizationLinkageMapper.deleteViewLinkage(dvId, sourceViewId);

        //重新建立关系
        for (VisualizationLinkageDTO linkageDTO:linkageInfo) {
            //去掉source view 的信息
            if(sourceViewId.equals(linkageDTO.getTargetViewId())){
                continue;
            }
            List<VisualizationLinkageFieldVO> linkageFields = linkageDTO.getLinkageFields();
            Long linkageId = IDUtils.snowID();
            VisualizationLinkage linkage = new VisualizationLinkage();
            linkage.setId(linkageId);
            linkage.setDvId(dvId);
            linkage.setSourceViewId(sourceViewId);
            linkage.setTargetViewId(linkageDTO.getTargetViewId());
            linkage.setUpdatePeople("");
            linkage.setUpdateTime(updateTime);
            linkage.setLinkageActive(linkageDTO.getLinkageActive());
            visualizationLinkageMapper.insert(linkage);
            if (CollectionUtils.isNotEmpty(linkageFields) && linkageDTO.getLinkageActive()) {
                linkageFields.forEach(linkageField -> {
                    linkageField.setId(IDUtils.snowID());
                    linkageField.setLinkageId(linkageId);
                    linkageField.setUpdateTime(updateTime);
                    VisualizationLinkageField fieldInsert = new VisualizationLinkageField();
                    visualizationLinkageFieldMapper.insert(BeanUtils.copyBean(fieldInsert,linkageField));
                });
            }
        }
        return new BaseRspModel();
    }

    @DeLinkPermit
    @Override
    public Map<String, List<String>> getVisualizationAllLinkageInfo(Long dvId) {
        List<LinkageInfoDTO> info = extVisualizationLinkageMapper.getPanelAllLinkageInfo(dvId);
        return Optional.ofNullable(info).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(LinkageInfoDTO::getSourceInfo, LinkageInfoDTO::getTargetInfoList));
    }

    @Override
    public Map updateLinkageActive(VisualizationLinkageRequest request) {
        CoreChartView coreChartView = new CoreChartView();
        coreChartView.setId(request.getSourceViewId());
        coreChartView.setLinkageActive(request.getActiveStatus());
        coreChartViewMapper.updateById(coreChartView);
        return getVisualizationAllLinkageInfo(request.getDvId());
    }

    @Override
    public void removeLinkage(VisualizationLinkageRequest request) {
        // 清理原有关系
        extVisualizationLinkageMapper.deleteViewLinkageField(request.getDvId(), request.getSourceViewId());
        extVisualizationLinkageMapper.deleteViewLinkage(request.getDvId(), request.getSourceViewId());
    }
}
