package com.diagbot.facade;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diagbot.dto.RelationDTO;
import com.diagbot.entity.LexiconRelationship;
import com.diagbot.entity.Library;
import com.diagbot.entity.LibraryInfo;
import com.diagbot.entity.Relation;
import com.diagbot.service.impl.RelationServiceImpl;
import com.diagbot.vo.TermVo;
import net.sf.jsqlparser.expression.WindowRange;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description: 术语知识查询业务层
 * @author: Weixuan Huang
 * @time: 2019/1/16 14:17
 */
@Component
public class RelationFacade extends RelationServiceImpl {

    @Autowired
    private LibraryInfoFacade libraryInfoFacade;
    @Autowired
    private RelationshipFacade relationshipFacade;

    /**
     *
     *
     * 获取指定医学术语的所有信息
     *
     * @param termVo
     * @result List<Relation>
     */
    public List<RelationDTO> getAllRelation(TermVo termVo) {
        List<RelationDTO> relationDTOs = new ArrayList<>();

        List<Relation> relations = new ArrayList<>();
        relations = getList(relations, termVo.getConcept_id(), -1);
        relationDTOs.addAll(ConvertListtoDTO(relations));

        return relationDTOs;
    }

    public List<RelationDTO> ConvertListtoDTO (List<Relation> src) {
        List<RelationDTO> dest = new ArrayList<>();
        RelationDTO relationDTO;
        TermVo termVo = new TermVo();
//        LibraryInfo libraryInfo = null;
//        QueryWrapper<LibraryInfo> wrapper = new QueryWrapper<>();

        for (Relation relation:src) {
            relationDTO = new RelationDTO();
            BeanUtils.copyProperties(relation, relationDTO);

            termVo.setConcept_id(relationDTO.getStartId());

            LibraryInfo libraryInfo = libraryInfoFacade.getLibraryInfor(termVo);
            relationDTO.setStartName(libraryInfo.getName());

            termVo.setConcept_id(relationDTO.getEndId());

            libraryInfo = libraryInfoFacade.getLibraryInfor(termVo);
            relationDTO.setEndName(libraryInfo.getName());

            LexiconRelationship lexiconRelationship = relationshipFacade.getLexiconRelationship(relationDTO);
            relationDTO.setRelationName(lexiconRelationship.getName());

            dest.add(relationDTO);
        }

        return dest;
    }

    /**
     * 获取关系列表
     * @param relations 关系列表
     * @param con_id 起始术语id
     * @param direct -1:向上, 1:向下
     * @result List<Relation>
     */
    public List<Relation> getList(List<Relation> relations, Object con_id, int direct) {
        List<Relation> rel_list = new ArrayList<>();


        if (con_id != null && con_id instanceof Integer) {
            QueryWrapper<Relation> wrapper = new QueryWrapper<>();

            if (direct == -1) {
                wrapper.eq("start_id", con_id);
                rel_list = this.list(wrapper);
            } else if (direct == 1) {
                wrapper.eq("end_id", con_id);
                rel_list = this.list(wrapper);
            }

            for (Relation item:rel_list) {
                if (!isExist(relations, item))
                    relations.add(item);
                else {
                    System.out.println("Conflicted items:\t" + JSON.toJSONString(item));
                    return relations;
                }
            }

            if (rel_list.size() > 0) {
                for (Relation rel : rel_list) {
                    getList(relations, rel.getEndId(), direct);
                }
            }
        }

        return relations;
    }


    /**
     * 查询关系是否有循环，即新加关系的起点和终点与原有关系的终点和起点相等
     *
     * @param
     */
    public Boolean isExist(List<Relation> relations, Relation relation) {
        Boolean Exist = false;

        for (Relation item:relations) {
            if (item.getStartId().intValue() == relation.getEndId().intValue() && item.getEndId().intValue() == relation.getStartId().intValue()) {
                Exist = true;
            }
        }

        return Exist;
    }

}
