package cn.fateverse.query.controller;

import cn.fateverse.common.core.exception.CustomException;
import cn.fateverse.common.decrypt.annotation.Encrypt;
import cn.fateverse.common.decrypt.annotation.EncryptField;
import cn.fateverse.common.decrypt.entity.EncryptOption;
import cn.fateverse.common.excel.utils.ExcelUtil;
import cn.fateverse.query.entity.dto.DataAdapterDto;
import cn.fateverse.query.entity.query.DataAdapterQuery;
import cn.fateverse.query.entity.vo.DataAdapterVo;
import cn.fateverse.query.service.DataAdapterService;
import cn.fateverse.common.core.result.Result;
import cn.fateverse.common.core.result.page.TableDataInfo;
import cn.fateverse.common.core.utils.ObjectUtils;
import cn.fateverse.common.log.annotation.Log;
import cn.fateverse.common.log.enums.BusinessType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 数据源适配器 Controller
 *
 * @author clay
 * @date 2023-10-29
 */
@Api(value = "数据源适配器管理", tags = "数据源适配器管理")
@RestController
@RequestMapping("/query/adapter")
public class DataAdapterController {

    private final DataAdapterService dataAdapterService;

    public DataAdapterController(DataAdapterService dataAdapterService) {
        this.dataAdapterService = dataAdapterService;
    }


    @ApiOperation("获取数据源适配器列表")
    @Encrypt
    @GetMapping
    @PreAuthorize("@ss.hasPermission('query:adapter:list')")
    public Result<TableDataInfo<DataAdapterVo>> list(DataAdapterQuery query) {
        TableDataInfo<DataAdapterVo> dataInfo = dataAdapterService.searchList(query);
        return Result.ok(dataInfo);
    }

    @ApiOperation("获取校验规则option")
    @Encrypt
    @GetMapping("/option")
    public Result<List<EncryptOption>> option() {
        List<EncryptOption> options = dataAdapterService.searchOptionList();
        return Result.ok(options);
    }

    @ApiOperation("导出excel数据")
    @GetMapping("/export")
    @PreAuthorize("@ss.hasPermission('query:adapter:export')")
    public void export(DataAdapterQuery query) {
        List<DataAdapterVo> list = dataAdapterService.exportList(query);
        ExcelUtil.exportExcel(list, DataAdapterVo.class);
    }

    @ApiOperation("获取数据源适配器详细信息")
    @GetMapping("/{adapterId}")
    @PreAuthorize("@ss.hasPermission('query:adapter:info')")
    public Result<DataAdapterVo> info(@PathVariable Long adapterId) {
        ObjectUtils.checkPk(adapterId);
        DataAdapterVo dataAdapter = dataAdapterService.searchById(adapterId);
        return Result.ok(dataAdapter);
    }


    @ApiOperation("模拟执行适配器函数")
    @PostMapping("/mock/execute")
    @Log(title = "模拟执行适配器函数", businessType = BusinessType.EXECUTE_CODE)
    @PreAuthorize("@ss.hasPermission('query:adapter:execute')")
    public Result<Object> mockExecute(@RequestBody @Validated DataAdapterDto dataAdapter) {
        if (ObjectUtils.isEmpty(dataAdapter.getMockData())) {
            throw new CustomException("请先获取模拟数据");
        }
        Object result = dataAdapterService.mockExecute(dataAdapter);
        return Result.ok(result);
    }


    @ApiOperation("新增数据源适配器")
    @PostMapping
    @Log(title = "新增数据源适配器", businessType = BusinessType.INSERT)
    @PreAuthorize("@ss.hasPermission('query:adapter:add')")
    public Result<Void> add(@RequestBody @Validated DataAdapterDto dataAdapter) {
        dataAdapterService.save(dataAdapter);
        return Result.ok();
    }

    @ApiOperation("修改数据源适配器")
    @PutMapping
    @Log(title = "修改数据源适配器", businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermission('query:adapter:edit')")
    public Result<Void> edit(@RequestBody @Validated DataAdapterDto dataAdapter) {
        ObjectUtils.checkPk(dataAdapter.getAdapterId());
        dataAdapterService.edit(dataAdapter);
        return Result.ok();
    }

    @ApiOperation("删除数据源适配器")
    @DeleteMapping("/{adapterIdList}")
    @Log(title = "删除数据源适配器", businessType = BusinessType.DELETE)
    @PreAuthorize("@ss.hasPermission('query:adapter:del')")
    public Result<Void> batchDel(@PathVariable List<Long> adapterIdList) {
        ObjectUtils.checkPkList(adapterIdList);
        dataAdapterService.removeBatch(adapterIdList);
        return Result.ok();
    }

}