
package com.jeelowcode.core.framework.controller;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.jeelowcode.core.framework.config.aspect.enhance.JeeLowCodeAnnoaionAspectjSQL;
import com.jeelowcode.core.framework.config.aspect.enhance.JeeLowCodeAnnotationAspectjJAVA;
import com.jeelowcode.core.framework.entity.EnhanceJavaEntity;
import com.jeelowcode.core.framework.entity.EnhanceJsEntity;
import com.jeelowcode.core.framework.entity.EnhanceSqlEntity;
import com.jeelowcode.core.framework.params.vo.PageVo;
import com.jeelowcode.core.framework.service.IEnhanceJavaService;
import com.jeelowcode.core.framework.service.IEnhanceJsService;
import com.jeelowcode.core.framework.service.IEnhanceSqlService;
import com.jeelowcode.core.framework.utils.Func;
import com.jeelowcode.core.framework.utils.FuncWeb;
import com.jeelowcode.framework.constants.FrameErrorCodeConstants;
import com.jeelowcode.framework.global.JeeLowCodeBaseConstant;
import com.jeelowcode.framework.utils.adapter.IJeeLowCodeAdapter;
import com.jeelowcode.framework.utils.annotation.ApiDecryptAes;
import com.jeelowcode.framework.utils.annotation.ApiEncryptAes;
import com.jeelowcode.framework.utils.component.redis.JeeLowCodeRedisUtils;
import com.jeelowcode.framework.utils.constant.JeeRedisConstants;
import com.jeelowcode.framework.utils.model.global.BaseWebResult;
import com.jeelowcode.framework.utils.utils.FuncBase;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Tag(name = "低代码框架-增强接口")
@RestController
@AllArgsConstructor
@RequestMapping(JeeLowCodeBaseConstant.REQUEST_URL_START + "/enhance")
public class DbFormEnhanceController extends BaseController {

    private final IEnhanceJavaService javaService;

    private final JeeLowCodeRedisUtils jeeLowCodeRedisUtils;

    private final IEnhanceJsService enhanceJsService;

    private final IJeeLowCodeAdapter adapter;

    private final IEnhanceSqlService sqlService;

    //-------------------- java 增强相关------------------------------
    @PreAuthorize("@ss.hasPermission('jeelowcode:java')")
    @GetMapping("/java/detail")
    @ApiOperationSupport(order = 1)
    @Operation(tags = "JAVA增强",summary = "Java增强-详情")
    public BaseWebResult<EnhanceJavaEntity> javaDetail(@RequestParam Long id) {
        return BaseWebResult.success(javaService.getById(id));
    }

    @PreAuthorize("@ss.hasPermission('jeelowcode:java')")
    @PostMapping("/java/save")
    @ApiOperationSupport(order = 2)
    @Operation(tags = "JAVA增强",summary = "新增")
    public BaseWebResult javaSave(@RequestBody EnhanceJavaEntity model) {
        javaService.saveEnhanceJava(model);
        return BaseWebResult.success("成功");
    }

    @PreAuthorize("@ss.hasPermission('jeelowcode:java')")
    @PutMapping("/java/update")
    @ApiOperationSupport(order = 3)
    @Operation(tags = "JAVA增强",summary = "修改")
    public BaseWebResult javaUpdate(@RequestBody EnhanceJavaEntity model) {
        javaService.updateEnhanceJava(model);
        return BaseWebResult.success("成功");
    }

    @PreAuthorize("@ss.hasPermission('jeelowcode:java')")
    @DeleteMapping("/java/delete")
    @ApiOperationSupport(order = 4)
    @Operation(tags = "JAVA增强",summary = "删除(逻辑删除)")
    public BaseWebResult javaDel(@RequestBody List<Long> ids) {

        List<EnhanceJavaEntity> enhanceJavaEntities = javaService.listByIds(ids);
        enhanceJavaEntities.stream().forEach(entity->{
            JeeLowCodeAnnotationAspectjJAVA.deletePlugins(entity);
        });

        javaService.removeByIds(ids);

        return BaseWebResult.success("成功");
    }


    @PreAuthorize("@ss.hasPermission('jeelowcode:java')")
    @GetMapping("/java/page")
    @ApiOperationSupport(order = 5)
    @Operation(tags = "JAVA增强",summary = "获取列表(分页)")
    public BaseWebResult javaPage(EnhanceJavaEntity entity, PageVo pageVo,String column,String order) {
        Page page = FuncWeb.getPage(pageVo.getPageNo(), pageVo.getPageSize());

        LambdaQueryWrapper<EnhanceJavaEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.setEntity(entity);
        if(Func.isNotEmpty(column)){
            if(Func.equals(order.toUpperCase(),"ASC")){
                wrapper.orderByAsc(EnhanceJavaEntity::getButtonCode);
            }else{
                wrapper.orderByDesc(EnhanceJavaEntity::getButtonCode);
            }
        }else{//默认按id排序
            wrapper.orderByDesc(EnhanceJavaEntity::getId);
        }
        IPage<EnhanceJavaEntity> pages = javaService.page(page, wrapper);
        return BaseWebResult.success(pages);
    }

    //-------------------- js 增强相关------------------------------
    @PreAuthorize("@ss.hasPermission('jeelowcode:web')")
    @PostMapping("/js/unlock/{dbformId}")
    @ApiOperationSupport(order = 1)
    @Operation(tags = "Js增强",summary = "Js增强-解锁")
    public BaseWebResult unlock(@PathVariable("dbformId") Long dbformId, @RequestParam String type) {

        String redisKey = String.format(JeeRedisConstants.ENHANCE_JS_LOCK,dbformId+":"+type);
        if (jeeLowCodeRedisUtils.hasKey(redisKey)) {
            jeeLowCodeRedisUtils.del(redisKey);
        }
        return BaseWebResult.success("成功");
    }


    //返回数据加密
    @ApiEncryptAes
    @PreAuthorize("@ss.hasPermission('jeelowcode:web')")
    @GetMapping("/js/detail")
    @ApiOperationSupport(order = 1)
    @Operation(tags = "Js增强",summary = "Js增强-详情")
    public BaseWebResult jsDetail(@RequestParam Long dbformId,
                                  @RequestParam String type,
                                  @RequestParam String lock){
        if (FuncBase.isNotEmpty(lock) && FuncBase.equals(lock, "true")) {
            String redisKey = String.format(JeeRedisConstants.ENHANCE_JS_LOCK,dbformId+":"+type);
            if (jeeLowCodeRedisUtils.hasKey(redisKey)) {
                String lockMapStr = (String)jeeLowCodeRedisUtils.get(redisKey);
                Map lockMap = Func.json2Bean(lockMapStr, Map.class);
                //返回锁定信息
                return BaseWebResult.error(FrameErrorCodeConstants.FRAME_ENHANCE_ERROR,lockMap);
            }

            String userName = adapter.getOnlineUserName();

            String timeStr = DateUtil.now();
            //存储锁定信息
            Map<String,Object> lockMap=new HashMap<>();
            lockMap.put("userName",userName);
            lockMap.put("timeStr",timeStr);
            jeeLowCodeRedisUtils.set(redisKey, Func.json2Str(lockMap));//上锁
        }
        return BaseWebResult.success(enhanceJsService.getDbFormEnhanceJsDetail(dbformId,type));
    }

    //解密body数据
    @ApiDecryptAes
    @PreAuthorize("@ss.hasPermission('jeelowcode:web')")
    @PostMapping("/js/save")
    @ApiOperationSupport(order = 2)
    @Operation(tags = "Js增强",summary = "js增强-新增")
    public BaseWebResult save(@RequestBody EnhanceJsEntity model) {
        enhanceJsService.saveEnhanceJs(model);
        return BaseWebResult.success(model.getId());
    }

    //解密body数据
    @ApiDecryptAes
    @PreAuthorize("@ss.hasPermission('jeelowcode:web')")
    @PutMapping("/js/update")
    @ApiOperationSupport(order = 3)
    @Operation(tags = "Js增强",summary = "js增强-修改")
    public BaseWebResult update(@RequestBody EnhanceJsEntity model) {
        enhanceJsService.updateEnhanceJs(model);
        return BaseWebResult.success(model.getId());
    }

    //-------------------- sql 增强相关------------------------------

    @PreAuthorize("@ss.hasPermission('jeelowcode:sql')")
    @GetMapping("/sql/detail")
    @ApiOperationSupport(order = 1)
    @Operation(tags = "Sql增强",summary = "详情")
    public BaseWebResult<EnhanceSqlEntity> sqlDetail(@RequestParam Long id){
        return BaseWebResult.success(sqlService.getById(id));
    }

    @PreAuthorize("@ss.hasPermission('jeelowcode:sql')")
    @PostMapping("/sql/save")
    @ApiOperationSupport(order = 2)
    @Operation(tags = "Sql增强",summary = "新增")
    public BaseWebResult sqlSave(@RequestBody EnhanceSqlEntity model) {
        sqlService.saveEnhanceSql(model);
        return BaseWebResult.success("成功");
    }

    @PreAuthorize("@ss.hasPermission('jeelowcode:sql')")
    @PutMapping("/sql/update")
    @ApiOperationSupport(order = 3)
    @Operation(tags = "Sql增强",summary = "修改")
    public BaseWebResult sqlUpdate(@RequestBody EnhanceSqlEntity model) {
        sqlService.updateEnhanceSql(model);
        return BaseWebResult.success("成功");
    }

    @PreAuthorize("@ss.hasPermission('jeelowcode:sql')")
    @DeleteMapping("/sql/delete")
    @ApiOperationSupport(order = 3)
    @Operation(tags = "Sql增强",summary = "删除(逻辑删除)")
    public BaseWebResult sqlDel(@RequestBody List<Long> ids) {
        List<EnhanceSqlEntity> enhanceSqlEntities = sqlService.listByIds(ids);
        enhanceSqlEntities.stream().forEach(
                e ->{
                    JeeLowCodeAnnoaionAspectjSQL.removePlugin(e);
                }
        );
        sqlService.removeByIds(ids);
        return BaseWebResult.success("成功");
    }

    @PreAuthorize("@ss.hasPermission('jeelowcode:sql')")
    @GetMapping("/sql/list")
    @ApiOperationSupport(order = 3)
    @Operation(tags = "Sql增强",summary = "获取列表")
    public BaseWebResult sqlList(EnhanceSqlEntity entity) {
        LambdaQueryWrapper<EnhanceSqlEntity> wrapper=new LambdaQueryWrapper<>();
        wrapper.setEntity(entity);
        wrapper.orderByDesc(EnhanceSqlEntity::getId);
        List<EnhanceSqlEntity> dataList = sqlService.list(wrapper);
        return BaseWebResult.success(dataList);
    }

    @PreAuthorize("@ss.hasPermission('jeelowcode:sql')")
    @GetMapping("/sql/page")
    @ApiOperationSupport(order = 3)
    @Operation(tags = "Sql增强",summary = "获取列表(分页)")
    public BaseWebResult sqlPage(EnhanceSqlEntity entity, PageVo pageVo,String column,String order) {
        Page page = FuncWeb.getPage(pageVo.getPageNo(), pageVo.getPageSize());

        LambdaQueryWrapper<EnhanceSqlEntity> wrapper=new LambdaQueryWrapper<>();
        wrapper.setEntity(entity);
        if(Func.isNotEmpty(column)){
            if(Func.equals(order.toUpperCase(),"ASC")){
                wrapper.orderByAsc(EnhanceSqlEntity::getButtonCode);
            }else{
                wrapper.orderByDesc(EnhanceSqlEntity::getButtonCode);
            }
        }else{//默认按id排序
            wrapper.orderByDesc(EnhanceSqlEntity::getId);
        }
        IPage<EnhanceSqlEntity> pages = sqlService.page(page, wrapper);
        return BaseWebResult.success(pages);
    }

}
