package com.liangjian.dataplatform.member.controller;

import com.liangjian.dataplatform.member.constant.DatabaseUrls;
import com.liangjian.dataplatform.member.entity.pojo.DataBaseInfo;
import com.liangjian.dataplatform.member.entity.response.ResultObject;
import com.liangjian.dataplatform.member.entity.vo.datanodes.MetaDataSource;
import com.liangjian.dataplatform.member.entity.vo.detailvo.DataSourceDetailVo;
import com.liangjian.dataplatform.member.entity.vo.detailvo.DetailVo;
import com.liangjian.dataplatform.member.entity.vo.request.BirdGirdRequest;
import com.liangjian.dataplatform.member.entity.vo.response.BirdGirdTableResponse;
import com.liangjian.dataplatform.member.service.IBirdGirdService;
import com.liangjian.dataplatform.member.service.IMetaCoreQueryService;
import com.liangjian.dataplatform.member.service.ISqlEntityService;
import com.liangjian.dataplatform.member.util.SimpleSqlUtil;
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.web.bind.annotation.*;

import java.util.*;

/**
 * @Author: 黄子奇
 * @Date: 2019/10/23
 */
@RestController
@RequestMapping("/birdgird")
@Api(value = "动态BirdGird的控制器", tags = "动态BirdGird的控制器", description = "动态BirdGird的控制器")
public class BirdGirdController {

    @Autowired
    private IMetaCoreQueryService iMetaCoreQueryService;
    @Autowired
    private ISqlEntityService iSqlEntityService;
    @Autowired
    private IBirdGirdService iBirdGirdService;

    @PostMapping("/readSql")
    @ApiOperation(value="动态birdgird的通过sql读")
    public BirdGirdTableResponse readSql(@ApiParam(value="数据源id", required = true) @RequestParam String dsId,
                                         @ApiParam(value="Sql配置Id", required = true) @RequestParam String sqlId,
                                         @ApiParam(value="请求结构",required = true) @RequestBody BirdGirdRequest birdGirdRequest) {
        return iBirdGirdService.readSql(dsId,sqlId,birdGirdRequest);
    }

    @PostMapping("/read")
    @ApiOperation(value="动态birdgird的读")
    public BirdGirdTableResponse read(@ApiParam(value="数据源id", required = true) @RequestParam String dsId,
                                      @ApiParam(value="数据表名称", required = true) @RequestParam String tableName,
                                      @ApiParam(value="请求结构",required = true) @RequestBody BirdGirdRequest birdGirdRequest) {
        DetailVo detailVo = iMetaCoreQueryService.getNodeDetail(dsId);
        if(!(detailVo instanceof DataSourceDetailVo)) {
            throw new RuntimeException("dsId 对应的不是数据源的节点");
        }
        MetaDataSource dataSource = (MetaDataSource) detailVo.getRealNode();
        DataBaseInfo dataBaseInfo = dataSource.getEntry();
        String host = dataBaseInfo.getHost() + ":" + dataBaseInfo.getPort();
        String url = DatabaseUrls.getByType(dataSource.getType())
                .getUrl(host,dataBaseInfo.getServerName());

        String sqlBone = "SELECT * FROM %s WHERE 1=1 %s ";
        String whereClause = birdGirdRequest.filtersToSql();
        String sql = String.format(sqlBone, tableName, whereClause);
        try {
            Map<String,Object> result = SimpleSqlUtil.getDataFromDatabaseWrapper(url,dataBaseInfo.getUser(),dataBaseInfo.getPwd(), sql, false,
                    birdGirdRequest.getPageIndex(), birdGirdRequest.getPageSize());
            BirdGirdTableResponse response = BirdGirdTableResponse.fromSqlResultMap(result);
            return response;
        } catch (Exception ex) {
            ex.printStackTrace();
            BirdGirdTableResponse response = new BirdGirdTableResponse();
            response.setItems(Collections.emptyList());
            response.setTotalCount(0L);
            return response;
        }
    }

    @PostMapping("/add")
    @ApiOperation(value="动态birdgird的添加")
    public ResultObject<Object> add(@ApiParam(value="数据源id", required = true) @RequestParam String dsId,
                                    @ApiParam(value="数据表名称", required = true) @RequestParam String tableName,
                                    @ApiParam(value="请求结构",required = true) @RequestBody Map<String,String> requestBody) {
        DetailVo detailVo = iMetaCoreQueryService.getNodeDetail(dsId);
        if(!(detailVo instanceof DataSourceDetailVo)) {
            throw new RuntimeException("dsId 对应的不是数据源的节点");
        }
        MetaDataSource dataSource = (MetaDataSource) detailVo.getRealNode();
        DataBaseInfo dataBaseInfo = dataSource.getEntry();
        String host = dataBaseInfo.getHost() + ":" + dataBaseInfo.getPort();
        String url = DatabaseUrls.getByType(dataSource.getType())
                .getUrl(host,dataBaseInfo.getServerName());

        String sqlBone = "INSERT INTO %s(%s) VALUES(%s)";
        List<String> intos = new ArrayList<>();
        List<String> values = new ArrayList<>();
        List<Object> pvalues = new ArrayList<>();
        for (Map.Entry<String, String> entry : requestBody.entrySet()) {
            intos.add(entry.getKey());
//            values.add(entry.getValue());
            values.add("?");
            pvalues.add(entry.getValue());
        }
        String into = intos.stream().reduce((i,j) -> i+","+j).orElse("");
        String value = values.stream().reduce((i,j) -> i+","+j).orElse("");
        if(into.isEmpty() || value.isEmpty()) {
            return ResultObject.error("新增错误");
        }
        String sql = String.format(sqlBone,tableName, into, value);
        try {
            boolean result = SimpleSqlUtil.execute(url,dataBaseInfo.getUser(),dataBaseInfo.getPwd(),sql, pvalues,false);
            return ResultObject.success("添加成功", null);
        } catch (Exception ex) {
            ex.printStackTrace();
            return ResultObject.error("新增错误");
        }
    }

    @PostMapping("/edit")
    @ApiOperation(value="动态birdgird的更新")
    public ResultObject<Object> add(@ApiParam(value="数据源id", required = true) @RequestParam String dsId,
                                    @ApiParam(value="数据表名称", required = true) @RequestParam String tableName,
                                    @ApiParam(value="表主键字段", required = true) @RequestParam String pkColumn,
                                    @ApiParam(value="请求结构",required = true) @RequestBody Map<String,String> requestBody) {
        DetailVo detailVo = iMetaCoreQueryService.getNodeDetail(dsId);
        if(!(detailVo instanceof DataSourceDetailVo)) {
            throw new RuntimeException("dsId 对应的不是数据源的节点");
        }
        MetaDataSource dataSource = (MetaDataSource) detailVo.getRealNode();
        DataBaseInfo dataBaseInfo = dataSource.getEntry();
        String host = dataBaseInfo.getHost() + ":" + dataBaseInfo.getPort();
        String url = DatabaseUrls.getByType(dataSource.getType())
                .getUrl(host,dataBaseInfo.getServerName());

        String sqlBone = "UPDATE %s SET %s WHERE %s";
        List<String> setClause = new ArrayList<>();
        List<Object> pvalues = new ArrayList<>();
        String whereClause = ""; //如果找不到主键就有问题
        for (Map.Entry<String, String> entry : requestBody.entrySet()) {
            if(entry.getKey().equals(pkColumn)) {
                //处理主键
                whereClause = entry.getValue();
                continue;
            }
            String unit = entry.getKey() + " = ?";
            setClause.add(unit);
            pvalues.add(entry.getValue());
        }
        pvalues.add(whereClause);

        String set = setClause.stream().reduce((i,j) -> i+","+j).orElse("");
        String where = pkColumn + " = ?";
        if(set.isEmpty() || whereClause.isEmpty()) {
            return ResultObject.error("编辑时的字段、条件错误");
        }
        String sql = String.format(sqlBone, tableName, set, where);
        try {
            boolean result = SimpleSqlUtil.execute(url,dataBaseInfo.getUser(),dataBaseInfo.getPwd(),sql, pvalues,false);
            return ResultObject.success("更新成功", null);
        } catch (Exception ex) {
            ex.printStackTrace();
            return ResultObject.error("更新失败");
        }
    }

    @PostMapping("/delete")
    @ApiOperation(value="动态birdgird的删除", notes = "注意，这里的上传上来的字段birdgird配置里的第一个字段，所以需要把主键字段配置第一个")
    public ResultObject<Object> add(@ApiParam(value="数据源id", required = true) @RequestParam String dsId,
                                    @ApiParam(value="数据表名称", required = true) @RequestParam String tableName,
                                    @ApiParam(value="表主键字段", required = true) @RequestParam String pkColumn,
                                    @ApiParam(value="删除的数据id", required = true) @RequestParam String id) {
        DetailVo detailVo = iMetaCoreQueryService.getNodeDetail(dsId);
        if(!(detailVo instanceof DataSourceDetailVo)) {
            throw new RuntimeException("dsId 对应的不是数据源的节点");
        }
        MetaDataSource dataSource = (MetaDataSource) detailVo.getRealNode();
        DataBaseInfo dataBaseInfo = dataSource.getEntry();
        String host = dataBaseInfo.getHost() + ":" + dataBaseInfo.getPort();
        String url = DatabaseUrls.getByType(dataSource.getType())
                .getUrl(host,dataBaseInfo.getServerName());

        String sqlBone = "DELETE FROM %s WHERE %s";
        String whereClause = pkColumn + " = ?";
        String sql = String.format(sqlBone, tableName, whereClause);
        List<Object> pvalues = Collections.singletonList(id);
        try {
            boolean result = SimpleSqlUtil.execute(url,dataBaseInfo.getUser(),dataBaseInfo.getPwd(),sql, pvalues,false);
            return ResultObject.success("更新成功", null);
        } catch (Exception ex) {
            ex.printStackTrace();
            return ResultObject.error("更新失败");
        }
    }
}
