package com.xjrsoft.module.system.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.toolkit.MPJWrappers;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.model.result.R;
import com.xjrsoft.common.page.ConventPage;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.module.system.dto.AddDatasourceDto;
import com.xjrsoft.module.system.dto.DatasourcePageDto;
import com.xjrsoft.module.system.dto.GetDataPageDto;
import com.xjrsoft.module.system.dto.UpdateDatasourceDto;
import com.xjrsoft.module.system.entity.Databaselink;
import com.xjrsoft.module.system.entity.Datasource;
import com.xjrsoft.module.system.service.IDatasourceService;
import com.xjrsoft.module.system.vo.DatasourceListVo;
import com.xjrsoft.module.system.vo.DatasourcePageVo;
import com.xjrsoft.module.system.vo.DatasourceVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;

/**
 * <p>
 * 数据源表 前端控制器
 * </p>
 *
 * @author tzx
 * @since 2022-03-08
 */
@RestController
@RequestMapping(GlobalConstant.SYSTEM_MODULE_PREFIX + "/datasource")
@Api(value = GlobalConstant.SYSTEM_MODULE_PREFIX + "/datasource", tags = "数据源")
@AllArgsConstructor
public class DatasourceController {
    private final IDatasourceService datasourceService;

    @GetMapping(value = "/list")
    @ApiOperation(value = "数据源列表（不分页）")
    public R list() {
        List<Datasource> list = datasourceService.list(Wrappers.lambdaQuery(Datasource.class)
                .select(Datasource.class, x -> VoToColumnUtil.fieldsToColumns(DatasourceListVo.class).contains(x.getProperty())));
        List<DatasourceListVo> datasourceListVos = BeanUtil.copyToList(list, DatasourceListVo.class);
        return R.ok(datasourceListVos);
    }

    @GetMapping(value = "/page")
    @ApiOperation(value = "数据源列表（分页）")
    public R page(@Valid DatasourcePageDto dto) {

        //因为多表关联 会有多个表都使用了id字段，  所以必须专门指定主表的Id
        IPage<DatasourcePageVo> page = datasourceService.selectJoinListPage(ConventPage.getPage(dto), DatasourcePageVo.class,
                MPJWrappers.<Datasource>lambdaJoin()
                        .like(StrUtil.isNotBlank(dto.getKeyword()), Datasource::getName, dto.getKeyword())
                        .or()
                        .like(StrUtil.isNotBlank(dto.getKeyword()), Datasource::getCode, dto.getKeyword())
                        .disableSubLogicDel()
                        .select(Datasource::getId)
                        .select(Datasource.class, x -> VoToColumnUtil.fieldsToColumns(DatasourcePageVo.class).contains(x.getProperty()))
                        .selectAs(Databaselink::getDbName, DatasourcePageVo::getDbName)
                        .leftJoin(Databaselink.class, Databaselink::getId, Datasource::getDatabaselinkId));

        PageOutput<DatasourcePageVo> pageOutput = ConventPage.getPageOutput(page);

        return R.ok(pageOutput);
    }

    @GetMapping(value = "/info")
    @ApiOperation(value = "根据id查询数据源信息")
    public R get(Long id) {
        Datasource datasource = datasourceService.getById(id);
        if (datasource == null) {
            R.error("找不到此数据源！");
        }
        return R.ok(BeanUtil.toBean(datasource, DatasourceVo.class));
    }

    @PostMapping
    @ApiOperation(value = "新增数据源")
    public R add(@Valid @RequestBody AddDatasourceDto dto) {
        long count = datasourceService.count(Wrappers.<Datasource>query().lambda().eq(Datasource::getName, dto.getName()).or().eq(Datasource::getCode, dto.getCode()));
        if (count > 0) {
            return R.error("数据源已经存在！");
        }
        Datasource datasource = BeanUtil.toBean(dto, Datasource.class);

        return R.ok(datasourceService.save(datasource));
    }

    @PutMapping
    @ApiOperation(value = "修改数据源")
    public R update(@Valid @RequestBody UpdateDatasourceDto dto) {
        long count = datasourceService.count(Wrappers.<Datasource>query().lambda()
                .eq(Datasource::getCode, dto.getCode())
                .ne(Datasource::getId, dto.getId()));

        if (count > 0) {
            return R.error("数据源编码已经存在！");
        }

        Datasource datasource = BeanUtil.toBean(dto, Datasource.class);

        return R.ok(datasourceService.updateById(datasource));
    }

    @DeleteMapping
    @ApiOperation(value = "批量删除数据源")
    public R delete(@Valid @RequestBody List<Long> ids) {
        return R.ok(datasourceService.removeByIds(ids));
    }

    @GetMapping("/column")
    @ApiOperation(value = "根据id获取sql所返回列")
    private R getColumns(@RequestParam Long id) {
        return R.ok(datasourceService.getColumns(id));
    }

    @GetMapping("/data")
    @ApiOperation(value = "根据id获取sql返回值 （不分页）")
    private R getData(@RequestParam Long id) {
        return R.ok(datasourceService.getData(id));
    }

    @GetMapping("/data/page")
    @ApiOperation(value = "根据id获取sql返回值 (分页)")
    private R getDataPage(@Valid GetDataPageDto dto) {
        return R.ok(datasourceService.getDataPage(dto));
    }
}
