package com.diagbot.facade;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.diagbot.dto.ConceptDTO;
import com.diagbot.dto.RelationDTO;
import com.diagbot.entity.Concept;
import com.diagbot.entity.LexiconRelationship;
import com.diagbot.entity.LibraryInfo;
import com.diagbot.entity.Relation;
import com.diagbot.service.impl.RelationServiceImpl;
import com.diagbot.vo.AllRelationVo;
import com.diagbot.vo.AmendTermVo;
import com.diagbot.vo.RelationVo;
import com.diagbot.vo.TermVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

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


    /**
     *
     * 获取所有医学术语的关系
     *
     * @param allrelationVo
     * @result IPage<RelationDTO>
     */
    public IPage<RelationDTO> getAllRelations(AllRelationVo allrelationVo) {

        return getAllRelation(allrelationVo);
    }


    /**
     * 获取指定医学术语的关联关系
     *
     * @param relation
     *
     * @return List<RelationDTO>
     */
    public List<RelationDTO> getRelationInfo(RelationDTO relation) {
        List<RelationDTO> rellist = new ArrayList<>();

        rellist = getRelation(relation);

        return rellist;
    }

    /**
     *
     *
     * 获取指定医学术语的所有上级关系
     *
     * @param relationVo
     * @result List<Relation>
     */
    public List<RelationDTO> getRelations(RelationVo relationVo) {
        List<RelationDTO> relationDTOs = new ArrayList<>();
        RelationDTO relationDTO = new RelationDTO();
        int concept_id = 0;

        if (relationVo.getStart_term().length() > 0 && relationVo.getEnd_term().length() > 0) {
            QueryWrapper<LibraryInfo> query = new QueryWrapper<>();
            query.eq("name", relationVo.getStart_term());
            query.eq("type", relationVo.getStart_type());

            LibraryInfo libraryInfo = libraryInfoFacade.getOne(query);

            if (libraryInfo == null) {
                relationDTO.setMsg("术语 \"" + relationVo.getStart_term() + "\" 不存在!");
                relationDTOs.add(relationDTO);

                return relationDTOs;
            }
            concept_id = (libraryInfo == null) ? 0 : libraryInfo.getConceptId();
        }
        else if (relationVo.getStart_concept_id() > 0) {
            concept_id = relationVo.getStart_concept_id();
        }

        if (concept_id > 0) {
            List<Relation> relations = new ArrayList<>();
            relations = getList(relations, concept_id, -1);
            relationDTOs.addAll(ConvertListtoDTO(relations));
        }

        return relationDTOs;
    }



    public List<RelationDTO> ConvertListtoDTO (List<Relation> src) {
        List<RelationDTO> dest = new ArrayList<>();
        RelationDTO relationDTO;

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

            Map<String, Object> map = new HashMap<>();
            map.put("concept_id", relationDTO.getStartId());
            LibraryInfo libraryInfo = libraryInfoFacade.getLibraryInfor(map);

            relationDTO.setStartName(libraryInfo.getName());

            map.put("concept_id", relationDTO.getEndId());
            libraryInfo = libraryInfoFacade.getLibraryInfor(map);

            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.getEndId().intValue() == relation.getStartId().intValue()
                    && item.getStartId().intValue() == relation.getEndId().intValue()
                    && item.getRelationId().intValue() == relation.getRelationId().intValue()) {
                Exist = true;
            }
        }

        return Exist;
    }

    /**
     * 更新或添加医学术语关系信息
     *
     * @param amendTermVo
     * @return
     */
    public void upsertRelationInfo(AmendTermVo amendTermVo) {
        Relation relation = new Relation();
        RelationDTO relnodeDTO;
        RelationDTO relationDTO;
        List<RelationDTO> rellist;
        boolean updated = false;
        int rel_id = 0;

        if (amendTermVo.getRelations() != null && amendTermVo.getRelations().size() > 0) {
            for (int i=0; i<amendTermVo.getRelations().size(); i++) {
                updated = false;
                relnodeDTO = amendTermVo.getRelations().get(i);
                if (relnodeDTO.getStartId() > 0 && relnodeDTO.getEndId() > 0
                        && relnodeDTO.getStartId() != relnodeDTO.getEndId()) {
                    relationDTO = amendTermVo.getRelations().get(i);
                    rel_id = relationDTO.getRelationId();

                    rellist = getRelationInfo(relationDTO);

                    if (rellist.size() > 0) {
                        for (RelationDTO reldto:rellist) {
                            if (reldto.getRelationId() == rel_id) {
                                updated = true;

                                break;
                            }
                        }
                    }

                    if (!updated) {
                        BeanUtils.copyProperties(relationDTO, relation);
                        this.saveOrUpdate(relation);
                    }
                }
            }
        }
    }


    /**
     *
     * 删除指定医学术语的关系
     *
     * @param relationVo
     * @result RelationDTO
     */
    public RelationDTO removeRelations(RelationVo relationVo) {
        RelationDTO relationDTO = new RelationDTO();
        QueryWrapper<Relation> query;

        int startid = relationVo.getStart_concept_id();
        int relationid = relationVo.getRelation_id();
        int endid = relationVo.getEnd_concept_id();
        String startname = relationVo.getStart_term().trim();
        String relationname = relationVo.getRelation_name().trim();
        String endname = relationVo.getEnd_term().trim();

        if (startid > 0 && relationid > 0 && endid > 0) {
            query = new QueryWrapper<>();
            query.eq("start_id", startid);
            query.eq("relation_id", relationid);
            query.eq("end_id", endid);

            relationDTO.setMsg(String.valueOf(remove(query)));
        }
        else if (startname.length() > 0 && endname.length() > 0 && relationname.length() > 0) {
            relationDTO = getRelationbyName(relationVo);

            if (relationDTO != null) {
                int id = relationDTO.getId();
                query = new QueryWrapper<>();
                query.eq("id", id);

                relationDTO.setMsg(String.valueOf(remove(query)));
            }
            else {
                relationDTO.setMsg("此关系不存在!");
            }
        }
        else {
            relationDTO.setMsg("此关系不存在!");
        }

        return relationDTO;
    }


    /**
     * 清空医学术语关系表
     *
     */
    public void deleteRelation() {
        truncateRelation();
    }


}
