package io.renren.modules.levelManage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.datasource.annotation.DataSource;
import io.renren.modules.levelManage.dao.LevelRelationDao;
import io.renren.modules.levelManage.entity.LevelEntity;
import io.renren.modules.levelManage.entity.LevelRelationEntity;
import io.renren.modules.levelManage.entity.LevelTableEntity;
import io.renren.modules.levelManage.service.LevelRelationService;
import io.renren.modules.levelManage.service.LevelService;
import io.renren.modules.levelManage.service.LevelTableService;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


@Service("levelRelationService")
@DataSource("heBing")
public class LevelRelationServiceImpl extends ServiceImpl<LevelRelationDao, LevelRelationEntity> implements LevelRelationService {

    @Autowired
    private LevelRelationDao levelRelationDao;
    @Autowired
    private LevelService levelService;
    @Autowired
    private LevelTableService levelTableService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<LevelRelationEntity> page = this.page(
                new Query<LevelRelationEntity>().getPage(params),
                new QueryWrapper<LevelRelationEntity>()
        );

        return new PageUtils(page);
    }

    public LevelRelationEntity selectBySon(Long tableId,Long id)
    {
        return levelRelationDao.selectBySon(tableId,id);
    }

    public List<LevelRelationEntity> selectByParent(Long tableId, Long id){
        return levelRelationDao.selectByParent(tableId,id);
    }

    public List<LevelRelationEntity> selectByParentRowAndSonTable(Long tableId, Long parentRowId)
    {
        return levelRelationDao.selectByParentRowAndSonTable(tableId,parentRowId);
    }

    /**
     * 递归地分析xml结构，并且创建层级和表格
     * @param root
     * @param parentId
     * @param levelNum
     * @throws Exception
     */
    @Transactional
    public void analysisLevel(Element root,long parentId,long levelNum) throws Exception{
        //levels=son_levels

        for(Iterator iterator = root.elementIterator(); iterator.hasNext();){
            Element level= (Element) iterator.next();
            String name =level.elementText("name");
            int hasHbaseTable= level.elementText("has_hbasetable").equals("true")?1:0;
            String tableName = level.elementText("table_name");

            LevelEntity levelEntity=new LevelEntity();
            levelEntity.setLevel(levelNum);
            levelEntity.setName(name);
            levelEntity.setHasHbasetable(hasHbaseTable);
            levelEntity.setCreateDate(new Date());
            levelEntity.setParentId(parentId);
            levelEntity.setTableName(tableName);
            levelEntity.setCreateTable(1);
            levelService.save(levelEntity);

            Element tableCol=level.element("table_messages");
            List<Map<String,String >> cols=new ArrayList<>();

            boolean hasId=false;
            boolean hasHbaseName=false;
            boolean hasLeaf=false;
            boolean hasName=false;
            boolean hasTime=false;
            boolean hasUser=false;
            for(Iterator iteratorCol=tableCol.elementIterator();iteratorCol.hasNext();){
                Element tableMessage= (Element) iteratorCol.next();
                String colEngName=tableMessage.elementText("name");
                String type=tableMessage.elementText("type");
                String colCHIName=tableMessage.elementText("cName");

                if(colEngName.equals("id"))
                    hasId=true;
                if(colCHIName.equals("hbaseTableName"))
                    hasHbaseName=true;
                if(colCHIName.equals("is_leaf"))
                    hasLeaf=true;
                if(colCHIName.equals("name"))
                    hasName=true;
                if(colCHIName.equals("create_time"))
                    hasTime=true;

                HashMap<String ,String> temp=new HashMap<>();
                temp.put("name",colEngName);
                temp.put("type",type);
                temp.put("comment",colCHIName);
                cols.add(temp);
            }
            //必须要有id,name,'create_time','create_user','is_leaf'字段
            if(!hasId){
                HashMap<String ,String> temp=new HashMap<>();
                temp.put("name","id");
                temp.put("type","bigint");
                temp.put("comment","id");
                cols.add(temp);
            }
            if(!hasName){
                HashMap<String ,String> temp=new HashMap<>();
                temp.put("name","name");
                temp.put("type","varchar(255)");
                temp.put("comment","名称");
                cols.add(temp);
            }
            if(!hasTime){
                HashMap<String ,String> temp=new HashMap<>();
                temp.put("name","create_time");
                temp.put("type","date");
                temp.put("comment","创建时间");
                cols.add(temp);
            }
            if(!hasUser){
                HashMap<String ,String> temp=new HashMap<>();
                temp.put("name","create_user");
                temp.put("type","bigint");
                temp.put("comment","创建者id");
                cols.add(temp);
            }
            if(!hasLeaf){
                HashMap<String ,String> temp=new HashMap<>();
                temp.put("name","is_leaf");
                temp.put("type","bool");
                temp.put("comment","是否为叶子节点");
                cols.add(temp);
            }
            //如果层级设计了有hbase表名，那么字段里面就需要有hbaseTableName
            if(levelEntity.getHasHbasetable()==1 && !hasHbaseName){
                HashMap<String ,String> temp=new HashMap<>();
                temp.put("name","hbaseTableName");
                temp.put("type","varchar(255)");
                temp.put("comment","hbase表名称");
                cols.add(temp);
            }

            if(levelTableService.createTable(tableName,cols)==0)
            {
                for(Map<String,String> item : cols)
                {
                    LevelTableEntity levelTable=new LevelTableEntity();
                    levelTable.setLevelId(levelEntity.getId());
                    levelTable.setCreateDate(new Date());
                    levelTable.setName(item.get("name"));
                    levelTable.setType(item.get("type"));
                    levelTable.setRemark(item.get("comment"));
                    if(!levelTableService.save(levelTable))
                    {
                        throw new Exception("表格创建成功，关联关系记录失败");
                    }
                }
            }
            else throw new Exception("创建表格失败");

            Element sonLevels= level.element("son_levels");
            if(sonLevels!=null){
                analysisLevel(sonLevels,levelEntity.getId(),levelNum+1);
            }
        }
    }

    /**
     * 用于记录xml文件中是否有重复的表名，或者和已有的表名称重复
     * @param fileName
     * @return
     */
    public boolean tableHasBuilted(String fileName){
        return false;
    }

    public boolean deleteBySonTidRids(Long id, List<Long> asList){
        HashMap<String,Object> map=new HashMap<>();
        map.put("son_table_id",id);
        for(Long rowid : asList){
            map.put("son_row_id",rowid);
            try {
                levelRelationDao.deleteByMap(map);
            }
            catch (Exception e){
                return false;
            }
        }
        return true;
    }

    public List<LevelRelationEntity> selectByParentAndSonTable(Long parentTableId, Long parentRowId,Long sonTableId){
        QueryWrapper<LevelRelationEntity> levelWrapper=new QueryWrapper<>();
        levelWrapper.eq("parent_table_id",parentTableId)
                .eq("parent_row_id",parentRowId)
                .eq("son_table_id",sonTableId);
        return levelRelationDao.selectList(levelWrapper);
    }


}