package com.liangjian.dataplatform.member.controller;

import com.liangjian.dataplatform.member.entity.response.PageResult;
import com.liangjian.dataplatform.member.entity.response.ResultObject;
import com.liangjian.dataplatform.member.entity.vo.MetaRelVo;
import com.liangjian.dataplatform.member.entity.vo.datanodes.*;
import com.liangjian.dataplatform.member.entity.vo.detailvo.DetailVo;
import com.liangjian.dataplatform.member.entity.vo.detailvo.PDMDetailVo;
import com.liangjian.dataplatform.member.entity.vo.request.IdAndPrtIdParam;
import com.liangjian.dataplatform.member.entity.vo.request.IdsAndPrtIdParam;
import com.liangjian.dataplatform.member.service.IMetaCoreCUDService;
import com.liangjian.dataplatform.member.service.IMetaCoreQueryService;
import com.liangjian.dataplatform.member.util.PageTransfer;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Author: 黄子奇
 * @Date: 2019/8/27 9:16
 */

@RestController
@RequestMapping("/meta")
@Api(value = "元数据管理信息控制器", tags = "元数据管理信息控制器", description = "元数据管理信息控制器")
public class MetaCoreController {

    @Autowired
    private IMetaCoreQueryService iMetaCoreQueryService;
    @Autowired
    private IMetaCoreCUDService iMetaCoreCUDService;

    @GetMapping("/roots")
    @ApiOperation(value = "获取自动生产的虚根节点",notes = "获取自动生产的虚根节点")
    public ResultObject<List<DataNode>> getRoots() {
        List<DataNode> roots = iMetaCoreQueryService.createRootNodes();
        return ResultObject.success(roots);
    }

    @GetMapping("/children")
    @ApiOperation(value = "获取数据节点", notes = "获取该节点的子节点")
    public ResultObject<List<DataNode>> getChildren(
            @ApiParam(value = "上一级节点",required = true) @RequestParam String prtId) {

        if(prtId.equalsIgnoreCase("root")){
            return getRoots();
        }

        List<DataNode> nodes = iMetaCoreQueryService.queryByPrtId(prtId);
        return ResultObject.success(nodes);
    }

    @GetMapping("/childrenPage")
    @ApiOperation(value = "分页获取数据节点", notes = "分页获取数据节点")
    public PageResult<DataNode> getChildren(
            @ApiParam(value = "上一级节点",required = true) @RequestParam String prtId,
            @ApiParam(value = "页码",required = true) @RequestParam Integer page,
            @ApiParam(value = "每页数量",required = true) @RequestParam Integer size){

        Page<DataNode> nodes = iMetaCoreQueryService.queryByPrtId(prtId,page-1,size);
        return PageTransfer.transfer(nodes);
    }

    @GetMapping("/childrenWithType")
    @ApiOperation(value = "通过类型获取数据节点", notes = "通过类型获取数据节点的子节点")
    public ResultObject<List<DataNode>> getChildrenWithType(
            @ApiParam(value = "上一级节点",required = true) @RequestParam String prtId,
            @ApiParam(value = "类型", required = true) @RequestParam String nodeType){

        List<DataNode> nodes = iMetaCoreQueryService.queryByPrtIdAndMetaMdl(prtId,nodeType);
        return ResultObject.success(nodes);
    }

    @GetMapping("/childrenWithTypePage")
    @ApiOperation(value = "分页通过类型获取数据节点", notes = "分页通过类型获取数据节点的子节点")
    public PageResult<DataNode> getChildrenWithType(
            @ApiParam(value = "上一级节点",required = true) @RequestParam String prtId,
            @ApiParam(value = "类型", required = true) @RequestParam String nodeType,
            @ApiParam(value = "页码",required = true) @RequestParam Integer page,
            @ApiParam(value = "每页数量",required = true) @RequestParam Integer size){

        Page<DataNode> nodes = iMetaCoreQueryService.queryByPrtIdAndMetaMdl(prtId,nodeType,page-1,size);
        return PageTransfer.transfer(nodes);
    }

    @GetMapping("/detail")
    @ApiOperation(value = "获取节点的详细信息", notes = "获取节点的详细信息")
    public ResultObject<DetailVo> getDetail(@ApiParam(value = "节点Id",required = true) @RequestParam String id) {
        DetailVo detailVo = iMetaCoreQueryService.getNodeDetail(id);
        if(detailVo.getRealNode() == null) {
            return ResultObject.error("there is no detail");
        }
        return ResultObject.success(detailVo);
    }

    @GetMapping("/relChildren")
    @ApiOperation(value = "获取该节点的相关子表", notes = "获取该节点的相关子表" )
    public ResultObject<List<DataNode>> getRelChildren(@ApiParam(value = "节点Id",required = true) @RequestParam String id) {
        List<DataNode> children = iMetaCoreQueryService.getRelaChildTables(id);
        return ResultObject.success(children);
    }

    @PostMapping("/package")
    @ApiOperation(value = "新增目录", notes = "新增目录")
    public ResultObject<Object> addPackage(@ApiParam(value = "目录结构", required = true) @RequestBody MetaCorePackage corePackage){
        if(corePackage.getId() != null) {
            corePackage.setId(null);
        }

        if(iMetaCoreCUDService.saveBasePackage(corePackage)){
            return ResultObject.success("保存成功",null);
        } else {
            return ResultObject.error("保存失败");
        }
    }

    @PutMapping("/package")
    @ApiOperation(value = "更新目录", notes = "更新目录")
    public ResultObject<Object> updatePackage(@ApiParam(value = "目录结构", required = true) @RequestBody MetaCorePackage corePackage) {
        if(corePackage.getId() == null) {
            return ResultObject.error("提交的结构不满足");
        }

        if(iMetaCoreCUDService.saveBasePackage(corePackage)){
            return ResultObject.success("保存成功",null);
        } else {
            return ResultObject.error("保存失败");
        }
    }

    @PostMapping("/pdm")
    @ApiOperation(value = "新增表元数据", notes = "新增表元数据")
    public ResultObject<Object> addPdm(@ApiParam(value = "表元数据结构", required = true) @RequestBody PDM pdm) {
        if(pdm.getId() != null) {
            pdm.setId(null);
        }

        if(iMetaCoreCUDService.savePDM(pdm)){
            return ResultObject.success("保存成功",null);
        } else {
            return ResultObject.error("保存失败");
        }
    }

    @PutMapping("/pdm")
    @ApiOperation(value = "修改表元数据", notes = "修改表元数据")
    public ResultObject<Object> updatePdm(@ApiParam(value = "表元数据结构", required = true) @RequestBody PDM pdm) {
        if (pdm.getId() == null) {
            return ResultObject.error("提交的结构不满足");
        }

        if (iMetaCoreCUDService.savePDM(pdm)) {
            return ResultObject.success("保存成功", null);
        } else {
            return ResultObject.error("保存失败");
        }
    }

    @PostMapping("/column")
    @ApiOperation(value = "新增表字段", notes = "新增表子段")
    public ResultObject<Object> addColumn(@ApiParam(value = "表字段结构", required = true) @RequestBody PDMColumn pdmColumn) {
        if(pdmColumn.getId() != null) {
            pdmColumn.setId(null);
        }

        if(iMetaCoreCUDService.savePDNColumn(pdmColumn)) {
            return ResultObject.success("保存成功", null);
        } else {
            return ResultObject.error("保存失败");
        }
    }

    @PutMapping("/column")
    @ApiOperation(value = "修改表字段", notes = "修改表字段")
    public ResultObject<Object> updateColumn(@ApiParam(value = "表字段结构", required = true) @RequestBody PDMColumn pdmColumn) {
        if(pdmColumn.getId() == null) {
            return ResultObject.error("提交的结构不满足");
        }

        if(iMetaCoreCUDService.savePDNColumn(pdmColumn)) {
            return ResultObject.success("保存成功", null);
        } else {
            return ResultObject.error("保存失败");
        }
    }

    private boolean hasId(PDMDetailVo pdmDetailVo) {
        DataNode pdm = pdmDetailVo.getRealNode();
        List<PDMColumn> columns = pdmDetailVo.getColumns();
        List<MetaRelVo> rels = pdmDetailVo.getRelations();
        if(pdm.getId() != null){
            return false;
        }
        if(columns.stream().anyMatch(i -> i.getId() != null)){
            return false;
        }
        if(rels.stream().anyMatch(i -> i.getRid() != null)) {
            return false;
        }
        return true;
    }

    @PostMapping("/pdmAll")
    @ApiOperation(value = "新增表模型", notes = "新增表模型，同时包括表、字段、关系")
    public ResultObject<Object> addPdmAll(@ApiParam(value = "表模型结构", required = true) @RequestBody PDMDetailVo pdmDetailVo) {
        if(!hasId(pdmDetailVo)) {
            return ResultObject.error("提交的结构不满足");
        }

        if(iMetaCoreCUDService.savePDMByDetail(pdmDetailVo)){
            return ResultObject.success("保存成功", null);
        } else {
            return ResultObject.error("保存失败");
        }
    }

    @PutMapping("/pdmAll")
    @ApiOperation(value = "更新表模型", notes = "更新表模型，同时包括表、字段、关系")
    public ResultObject<Object> updatePdmAll(@ApiParam(value = "表模型结构", required = true) @RequestBody PDMDetailVo pdmDetailVo) {
        if(pdmDetailVo.getRealNode().getId() == null) {
            return ResultObject.error("提交的结构不满足");
        }

        if(iMetaCoreCUDService.savePDMByDetail(pdmDetailVo)){
            return ResultObject.success("保存成功", null);
        } else {
            return ResultObject.error("保存失败");
        }
    }

    @PostMapping("/datasource")
    @ApiOperation(value = "新增数据源（落地库）", notes = "新增数据源（落地库）")
    public ResultObject<Object> addDatasource(@ApiParam(value = "数据源结构", required = true) @RequestBody MetaDataSource metaDataSource) {
        if(metaDataSource.getId() != null) {
            metaDataSource.setId(null);
        }

        if(iMetaCoreCUDService.saveDataSource(metaDataSource)){
            return ResultObject.success("保存成功", null);
        } else {
            return ResultObject.error("保存失败");
        }
    }

    @PutMapping("/datasource")
    @ApiOperation(value = "更新数据源（落地库）", notes = "更新数据源（落地库）")
    public ResultObject<Object> updateDatasource(@ApiParam(value = "数据源结构", required = true) @RequestBody MetaDataSource metaDataSource) {
        if(metaDataSource.getId() == null) {
            return ResultObject.error("提交的结构不满足");
        }

        if(iMetaCoreCUDService.saveDataSource(metaDataSource)){
            return ResultObject.success("保存成功", null);
        } else {
            return ResultObject.error("保存失败");
        }
    }

    @PostMapping("/importPdm")
    @ApiOperation(value = "从反向工程中导入元数据",notes = "从反向工程中导入元数据")
    public ResultObject<Object> importPdm(@ApiParam(value = "选择的id，和需要导入的父级Id",required = true) @RequestBody IdAndPrtIdParam idParam) {
        if(idParam.getId() == null ||  idParam.getPrtId() == null) {
            return ResultObject.error("提交的结构不满足");
        }

        String id = idParam.getId();
        String pid = idParam.getPrtId();

        if(iMetaCoreCUDService.addPDMByReverse(id,pid)) {
            return ResultObject.success("导入成功",null);
        } else {
            return ResultObject.error("导入失败");
        }
    }

    @PostMapping("/importPdms")
    @ApiOperation(value = "从反向工程中导入元数据（多个）",notes = "从反向工程中导入元数据（多个）")
    public ResultObject<Object> importPdms(@ApiParam(value = "选择的id，和需要导入的父级Id",required = true) @RequestBody IdsAndPrtIdParam idsParam) {
        if(idsParam.getIds() == null || idsParam.getIds().isEmpty() || idsParam.getPrtId() == null) {
            return ResultObject.error("提交的结构不满足");
        }
        List<String> ids = idsParam.getIds();
        String pid = idsParam.getPrtId();

        if(iMetaCoreCUDService.addPDMByReverses(ids,pid)) {
            return ResultObject.success("导入成功",null);
        } else {
            return ResultObject.error("导入失败");
        }
    }

    @DeleteMapping("/node")
    @ApiOperation(value = "删除数据节点", notes = "删除数据节点，注意，会删除其子节点")
    public ResultObject<Object> deleteNode(@ApiParam(value = "删除节点的Id",required = true) @RequestBody String id) {
        if(iMetaCoreCUDService.deleteMeta(id)){
            return ResultObject.success("删除成功",null);
        } else {
            return ResultObject.error("删除失败");
        }
    }

    @DeleteMapping("/nodes")
    @ApiOperation(value = "批量删除数据节点", notes="批量删除数据节点，注意，会删除其子节点")
    public ResultObject<Object> deleteNode(@ApiParam(value = "删除节点的Id",required = true) @RequestBody List<String> ids) {
        if(iMetaCoreCUDService.deleteMeta(ids)) {
            return ResultObject.success("删除成功",null);
        } else {
            return ResultObject.error("删除失败");
        }
    }
}
