package ink.wgink.module.oauth.client.controller.api;

import ink.wgink.common.base.DefaultBaseController;
import ink.wgink.exceptions.ParamsException;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.dtos.oauth.client.OauthClientDTO;
import ink.wgink.pojo.result.ErrorResult;
import ink.wgink.pojo.result.SuccessResult;
import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.module.oauth.client.pojo.vos.OauthClientVO;
import ink.wgink.module.oauth.client.service.IOauthClientService;
import ink.wgink.util.AesUtil;
import io.swagger.annotations.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: OauthClientController
 * @Description: Oauth客户端
 * @Author: WangGeng
 * @Date: 2019/3/12 11:15 AM
 * @Version: 1.0
 **/
@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "Oauth客户端")
@RestController
@RequestMapping(ISystemConstant.API_PREFIX + "/oauthclient")
public class OauthClientController extends DefaultBaseController {

    @Autowired
    private IOauthClientService oauthClientService;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @ApiOperation(value = "Oauth客户端新增", notes = "Oauth客户端新增接口")
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @PostMapping("save")
    public SuccessResult save(@RequestBody OauthClientVO oauthClientVO) throws UnsupportedEncodingException {
        Map<String, Object> params = getParams();
        if (StringUtils.isBlank(oauthClientVO.getClientId())) {
            throw new ParamsException("clientId不能为空");
        }
        params.put("clientId", oauthClientVO.getClientId());

        if (StringUtils.isBlank(oauthClientVO.getClientSecret())) {
            throw new ParamsException("clientSecret不能为空");
        }
        if (!StringUtils.equals(oauthClientVO.getClientSecret(),
                Base64.encodeBase64String(
                        AesUtil.aesEncoder(
                                IOauthClientService.OAUTH_CLIENT_RULE, oauthClientVO.getClientId()
                        ).getBytes("UTF-8")
                ))) {
            throw new ParamsException("clientId与clientSecret不匹配");
        }
        params.put("clientSecret", passwordEncoder.encode(oauthClientVO.getClientSecret()));
        checkParams(oauthClientVO, params);

        return oauthClientService.save(params);
    }

    @ApiOperation(value = "Oauth客户端删除", notes = "Oauth客户端删除接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "Oauth客户端ID列表，用下划线分隔", paramType = "path", example = "1_2_3")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @DeleteMapping("remove/{ids}")
    public SuccessResult remove(@PathVariable("ids") String ids) {
        Map<String, Object> params = getParams();
        params.put("secretIds", ids);
        return oauthClientService.remove(params);
    }

    @ApiOperation(value = "Oauth客户端修改", notes = "Oauth客户端修改接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "clientId", value = "Oauth客户端ID", paramType = "path")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @PutMapping("update/{clientId}")
    public SuccessResult update(@PathVariable("clientId") String clientId,
                                @RequestBody OauthClientVO oauthClientVO) {
        Map<String, Object> params = getParams();
        params.put("clientId", clientId);
        checkParams(oauthClientVO, params);
        return oauthClientService.update(params);
    }

    /**
     * 校验参数
     *
     * @param oauthClientVO
     * @param params
     * @throws ParamsException
     */
    private void checkParams(OauthClientVO oauthClientVO, Map<String, Object> params) {
        if (StringUtils.isBlank(oauthClientVO.getClientName())) {
            throw new ParamsException("客户端名称不能为空");
        }
        params.put("clientName", oauthClientVO.getClientName());

        if (StringUtils.isBlank(oauthClientVO.getScope())) {
            throw new ParamsException("范围不能为空");
        }
        params.put("scope", oauthClientVO.getScope());

        if (StringUtils.isBlank(oauthClientVO.getAuthorizedGrantTypes())) {
            throw new ParamsException("授权类型不能为空");
        }
        params.put("authorizedGrantTypes", oauthClientVO.getAuthorizedGrantTypes());

        if (StringUtils.isBlank(oauthClientVO.getAuthorities())) {
            throw new ParamsException("授权不能为空");
        }
        params.put("authorities", oauthClientVO.getAuthorities());

        if (StringUtils.isBlank(oauthClientVO.getWebServerRedirectUri())) {
            throw new ParamsException("重定向链接不能为空");
        }
        params.put("webServerRedirectUri", oauthClientVO.getWebServerRedirectUri());

        if (oauthClientVO.getAccessTokenValidity() == null) {
            throw new ParamsException("访问令牌时效不能为空");
        }
        params.put("accessTokenValidity", oauthClientVO.getAccessTokenValidity());

        if (oauthClientVO.getRefreshTokenValidity() == null) {
            throw new ParamsException("刷新令牌时效不能为空");
        }
        params.put("refreshTokenValidity", oauthClientVO.getRefreshTokenValidity());

        if (StringUtils.isBlank(oauthClientVO.getAutoapprove())) {
            params.put("autoapprove", "true");
        } else {
            params.put("autoapprove", oauthClientVO.getAutoapprove());
        }

        if (StringUtils.isBlank(oauthClientVO.getEnvironment())) {
            throw new ParamsException("系统环境不能为空");
        } else {
            params.put("environment", oauthClientVO.getEnvironment());
        }

        if (StringUtils.isBlank(oauthClientVO.getSystemType())) {
            throw new ParamsException("系统类型不能为空");
        } else {
            params.put("systemType", oauthClientVO.getSystemType());
        }

        if (StringUtils.equals(oauthClientVO.getSystemType(), IOauthClientService.OAUTH_CLIENT_SYSTEM_TYPE_THIRD)) {
            if (StringUtils.isBlank(oauthClientVO.getSystemState())) {
                throw new ParamsException("系统状态不能为空");
            } else {
                params.put("systemState", oauthClientVO.getSystemState());
            }
            if (StringUtils.isBlank(oauthClientVO.getExpireTime())) {
                throw new ParamsException("系统到期时间不能为空");
            } else {
                params.put("expireTime", oauthClientVO.getExpireTime());
            }
        }
        params.put("systemSummary", oauthClientVO.getSystemSummary());
        params.put("systemIcon", oauthClientVO.getSystemIcon());
    }

    @ApiOperation(value = "easyui Oauth客户端列表", notes = "easyui Oauth客户端列表列表接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页码", paramType = "query", dataType = "int", defaultValue = "1"),
            @ApiImplicitParam(name = "rows", value = "显示数量", paramType = "query", dataType = "int", defaultValue = "20"),
            @ApiImplicitParam(name = "keywords", value = "关键字", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", dataType = "String")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @GetMapping("listpage")
    public SuccessResultList<List<OauthClientDTO>> listPage(ListPage page) {
        Map<String, Object> params = requestParams();
        page.setParams(params);
        return oauthClientService.listPage(page);
    }

    @ApiOperation(value = "Oauth客户端列表", notes = "Oauth客户端列表列表接口")
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @GetMapping("list")
    public List<OauthClientDTO> list() {
        Map<String, Object> params = requestParams();
        return oauthClientService.list(params);
    }

    @ApiOperation(value = "Oauth客户端详情", notes = "Oauth客户端详情接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "clientId", value = "Oauth客户端ID", paramType = "path")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @GetMapping("get/{clientId}")
    public OauthClientDTO get(@PathVariable("clientId") String clientId) throws UnsupportedEncodingException {
        Map<String, Object> params = requestParams();
        params.put("clientId", clientId);
        return oauthClientService.get(params);
    }

    @ApiOperation(value = "Oauth客户端绑定菜单", notes = "Oauth客户端绑定菜单接口，自动创建根节点菜单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "clientId", value = "Oauth客户端ID", paramType = "path")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @PutMapping("updatemenu/{clientId}")
    public SuccessResult updateMenu(@PathVariable("clientId") String clientId, @RequestBody Map<String, Object> params) {
        params.put("clientId", clientId);
        return oauthClientService.updateOauthClientMenu(params);
    }

    @ApiOperation(value = "Oauth客户端初始化数据", notes = "Oauth客户端初始化数据接口")
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @GetMapping("getinitclient")
    public OauthClientDTO getInitClient() throws Exception {
        Map<String, Object> params = getParams();
        return oauthClientService.getInitClient(params);
    }

    @ApiOperation(value = "清除客户端菜单", notes = "清除客户端菜单菜单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "clientId", value = "Oauth客户端ID", paramType = "path")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @PutMapping("updateclientmenuempty/{clientId}")
    public SuccessResult updateClientMenuEmpty(@PathVariable("clientId") String clientId) {
        Map<String, Object> params = getParams();
        params.put("clientId", clientId);
        return oauthClientService.updateClientMenuEmpty(params);
    }

}
