
package com.jeelowcode.core.framework.controller;

import cn.hutool.core.bean.BeanUtil;
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.entity.EnhanceJsEntity;
import com.jeelowcode.core.framework.entity.ReportEntity;
import com.jeelowcode.core.framework.entity.TabEntity;
import com.jeelowcode.core.framework.entity.TabJsEntity;
import com.jeelowcode.core.framework.params.PageReportParam;
import com.jeelowcode.core.framework.params.PageTabParam;
import com.jeelowcode.core.framework.params.TabAddOrUpdateParam;
import com.jeelowcode.core.framework.params.vo.PageVo;
import com.jeelowcode.core.framework.params.vo.ReportConfigVo;
import com.jeelowcode.core.framework.params.vo.TabDetailVo;
import com.jeelowcode.core.framework.params.vo.TabWebConfigVo;
import com.jeelowcode.core.framework.params.vo.role.DbFormRoleButtonVo;
import com.jeelowcode.core.framework.params.vo.role.DbFormRoleFieldVo;
import com.jeelowcode.core.framework.params.vo.webconfig.WebConfigRoleFieldVo;
import com.jeelowcode.core.framework.params.vo.webconfig.WebConfigVo;
import com.jeelowcode.core.framework.service.IEnhanceJsService;
import com.jeelowcode.core.framework.service.ITabService;
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;
import java.util.stream.Collectors;

@Tag(name = "低代码框架-模块组合接口")
@RestController
@AllArgsConstructor
@RequestMapping(JeeLowCodeBaseConstant.REQUEST_URL_START + "/tab")
public class TabController extends BaseController {

    private final ITabService tabService;

    private final JeeLowCodeRedisUtils redisUtils;

    private final IJeeLowCodeAdapter adapter;


    @GetMapping("/get/web-config")
    @ApiOperationSupport(order = 9)
    @Operation(tags = "表单开发",summary = "获取页面信息配置")
    public BaseWebResult getWebConfig(@RequestParam("tabId")Long tabId) {
        TabWebConfigVo vo = tabService.getWebConfig(tabId);
        return BaseWebResult.success(vo);
    }

    @PreAuthorize("@ss.hasPermission('jeelowcode:tab:create')")
    @PostMapping("/save")
    @ApiOperationSupport(order = 1)
    @Operation(tags = "模块组合",summary = "模块组合 - 保存")
    public BaseWebResult saveTab(@RequestBody TabAddOrUpdateParam param) {
        tabService.saveOrUpdateTab(param);
        return BaseWebResult.success("成功");
    }


    @PreAuthorize("@ss.hasPermission('jeelowcode:tab:update')")
    @PutMapping("/update")
    @ApiOperationSupport(order = 1)
    @Operation(tags = "模块组合",summary = "模块组合 - 保存")
    public BaseWebResult updateTab(@RequestBody TabAddOrUpdateParam param) {
        tabService.saveOrUpdateTab(param);
        return BaseWebResult.success("成功");
    }

    @PreAuthorize("@ss.hasPermission('jeelowcode:tab:delete')")
    @DeleteMapping("/delete")
    @ApiOperationSupport(order = 3)
    @Operation(tags = "模块组合",summary = "模块组合 - 删除")
    public BaseWebResult delTab(@RequestBody List<Long> tabIdList) {
        tabService.delTab(tabIdList);
        return BaseWebResult.success("成功");
    }

    @PreAuthorize("@ss.hasPermission('jeelowcode:tab:query')")
    @PostMapping("/detail")
    @ApiOperationSupport(order = 4)
    @Operation(tags = "模块组合",summary = "模块组合 - 获取详情")
    public BaseWebResult getTab(Long id) {
        TabDetailVo vo = tabService.getDetail(id);
        return BaseWebResult.success(vo);
    }

    @PreAuthorize("@ss.hasPermission('jeelowcode:tab:query')")
    @PostMapping("/page")
    @ApiOperationSupport(order = 5)
    @Operation(tags = "模块组合",summary = "模块组合 - 获取分页数据")
    public BaseWebResult getPageReportConfig(@RequestBody PageTabParam param, PageVo pageVo) {
        Page page = FuncWeb.getPage(pageVo.getPageNo(), pageVo.getPageSize());

        LambdaQueryWrapper<TabEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FuncBase.isNotEmpty(param.getId()), TabEntity::getId, param.getId());
        wrapper.eq(FuncBase.isNotEmpty(param.getModuleName()), TabEntity::getModuleName, param.getModuleName());
        wrapper.eq(FuncBase.isNotEmpty(param.getGroupModuleId()), TabEntity::getGroupModuleId, param.getGroupModuleId());
        wrapper.orderByDesc(TabEntity::getId);
        Page<TabEntity> pages = tabService.page(page, wrapper);
        return BaseWebResult.success(pages);
    }

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

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


    //返回数据加密
    @ApiEncryptAes
    @PreAuthorize("@ss.hasPermission('jeelowcode:tab:js')")
    @GetMapping("/js/detail")
    @ApiOperationSupport(order = 7)
    @Operation(tags = "Js增强",summary = "Js增强-详情")
    public BaseWebResult jsDetail(@RequestParam Long tabId,
                                  @RequestParam String type,
                                  @RequestParam String lock){
        if (FuncBase.isNotEmpty(lock) && FuncBase.equals(lock, "true")) {
            String redisKey = String.format(JeeRedisConstants.ENHANCE_TAB_JS_LOCK,tabId+":"+type);
            if (redisUtils.hasKey(redisKey)) {
                String lockMapStr = (String)redisUtils.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);
            redisUtils.set(redisKey, Func.json2Str(lockMap));//上锁
        }
        return BaseWebResult.success(tabService.getJsDetail(tabId,type));
    }

    //解密body数据
    @ApiDecryptAes
    @PreAuthorize("@ss.hasPermission('jeelowcode:tab:js')")
    @PostMapping("/js/save")
    @ApiOperationSupport(order = 8)
    @Operation(tags = "Js增强",summary = "js增强-新增")
    public BaseWebResult jsSave(@RequestBody TabJsEntity model) {
        tabService.saveJs(model);
        return BaseWebResult.success(model.getId());
    }

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

}
