package com.hotent.auth.server.controller;

import com.hotent.auth.server.service.AuthenticationService;
import com.hotent.base.annotation.ApiGroup;
import com.hotent.base.constants.ApiGroupConsts;
import com.hotent.base.exception.CertificateException;
import com.hotent.base.feign.PortalFeignService;
import com.hotent.base.jwt.JwtAuthenticationRequest;
import com.hotent.base.jwt.JwtAuthenticationResponse;
import com.hotent.base.jwt.JwtCustomAuthenticationRequest;
import com.hotent.base.model.CommonResult;
import com.hotent.base.query.QueryFilter;
import com.hotent.base.util.AppUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.http.client.ClientProtocolException;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.Optional;

@RestController
@Api(tags = "认证接口")
@ApiGroup(group = {ApiGroupConsts.GROUP_AUTH})
public class AuthenticationRestController {

    @Resource
    AuthenticationService authenticationService;


    @RequestMapping(value = "/auth", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "登录系统", httpMethod = "POST", notes = "登录系统")
    public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtAuthenticationRequest authenticationRequest) throws Exception {
        ResponseEntity<JwtAuthenticationResponse> authenticationToken = authenticationService.createAuthenticationToken(authenticationRequest);
        return authenticationToken;
    }

    @RequestMapping(value = "/sso/auth", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "登录系统-单点登录", httpMethod = "GET", notes = "登录系统-单点登录")
    public ResponseEntity<?> ssoAuth(@RequestParam Optional<String> ticket, @RequestParam Optional<String> code, @RequestParam Optional<String> ssoMode, @RequestParam String service) throws AuthenticationException, ClientProtocolException, IOException {
        return authenticationService.ssoAuth(ticket, code, ssoMode, service);
    }

    @RequestMapping(value = "/sso/weixin", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "企业微信应用进入手机端-单点登录", httpMethod = "GET", notes = "企业微信应用进入手机端-单点登录")
    public ResponseEntity<?> ssoWeixin(@RequestParam Optional<String> code) throws AuthenticationException, ClientProtocolException, IOException {
        return authenticationService.ssoWeixin(code);
    }

    @RequestMapping(value = "/sso/weixinPublic", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "微信公众号进入手机端", httpMethod = "GET", notes = "微信公众号进入手机端")
    public ResponseEntity<?> weixinPublic(@RequestParam Optional<String> code) throws AuthenticationException, ClientProtocolException, IOException {
        return authenticationService.weixinPublic(code);
    }


    @RequestMapping(value = "/sso/dingTalk", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "钉钉进入手机端", httpMethod = "GET", notes = "微信公众号进入手机端")
    public ResponseEntity<?> dingTalk(@RequestParam Optional<String> code) throws AuthenticationException, ClientProtocolException, IOException {
        return authenticationService.dingTalk(code);
    }


    @RequestMapping(value = "/sso/miniprogram", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "小程序登陆凭证校验", httpMethod = "GET", notes = "小程序登录凭证校验")
    public CommonResult<?> miniprogram(@RequestParam Optional<String> code) throws AuthenticationException, ClientProtocolException, IOException {
        return authenticationService.miniprogram(code);
    }

    @RequestMapping(value = "/sso/scanLogin", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "企微钉钉App扫码登录PC端", httpMethod = "GET", notes = "企微钉钉App扫码登录PC端")
    public CommonResult<?> dingtalkScan(@RequestParam(value = "code", required = true) Optional<String> code,
                                        @RequestParam(value = "type", required = true) Optional<String> type) {
        return authenticationService.dingtalkScan(code, type);
    }

    /**
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/sso/info", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "单点登录配置", httpMethod = "GET", notes = "单点登录配置")
    public ResponseEntity<Map<String, Object>> isUseCas(HttpServletRequest request, HttpServletResponse response) throws IOException {
        return ResponseEntity.ok(authenticationService.isUseCas());
    }

    @RequestMapping(value = "/refresh", method = RequestMethod.GET)
    @ApiOperation(value = "刷新token", httpMethod = "GET", notes = "刷新token")
    public ResponseEntity<?> refreshAndGetAuthenticationToken(HttpServletRequest request) {
        return authenticationService.refreshAndGetAuthenticationToken(request);
    }

    @RequestMapping(value = "/signout", method = RequestMethod.GET)
    @ApiOperation(value = "退出登录", httpMethod = "GET", notes = "使token的状态失效,必须设置jwt.single和jwt.stricky均为true")
    public CommonResult<String> signout(HttpServletRequest request) {
        authenticationService.signout(request);
        return CommonResult.<String>ok().message("退出成功");
    }

    @RequestMapping(value = "/sso/productLoginQrCode", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "生成扫码登录二维码", httpMethod = "GET", notes = "生成扫码登录二维码")
    public ResponseEntity<?> productLoginQrCode(@RequestParam(value = "type", required = true) String type) throws AuthenticationException, ClientProtocolException, IOException {
        return authenticationService.productLoginQrCode(type);
    }

    @RequestMapping(value = "/sso/scanLoginOut", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "钉钉扫码回调接口", httpMethod = "GET", notes = "钉钉扫码回调接口")
    public CommonResult<?> scanLoginOutDing(@RequestParam(value = "code", required = true) String code,
                                        @RequestParam(value = "authCode", required = false) String authCode,
                                            @RequestParam(value = "state", required = false) String state) {
        return authenticationService.dingAuthByCode(code,authCode,state);
    }

    @RequestMapping(value = "/sso/queryScanLoginInfoById", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "获取扫码结果方法", httpMethod = "GET", notes = "获取扫码结果方法")
    public  CommonResult<?> queryScanLoginInfoById(@RequestParam(value = "busId", required = true) String busId) throws AuthenticationException, ClientProtocolException, IOException {
        return authenticationService.queryScanLoginInfoById(busId);
    }

    @RequestMapping(value = "/sso/forgotPwd", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "忘记密码_重新设置密码功能", httpMethod = "GET", notes = "忘记密码_重新设置密码功能")
    public CommonResult<?> forgotPwd(
            @RequestParam(value = "account", required = true) String account,
            @RequestParam(value = "mobile", required = true) String mobile,
            @RequestParam(value = "validateCode", required = true) String validateCode,
            @RequestParam(value = "newPsw", required = true) String newPsw,
            @RequestParam(value = "reNewPsw", required = true) String reNewPsw) throws AuthenticationException, IOException {
        return authenticationService.forgotPwd(account, mobile, validateCode, newPsw, reNewPsw);
    }


    @RequestMapping(value = "/sso/getDingUserByCode", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "微应用免登", httpMethod = "GET", notes = "微应用免登")
    public CommonResult<?> getDingUserByCode(@RequestParam(value = "code", required = true) String code,
                                            @RequestParam(value = "corpId", required = false) String corpId,
                                            @RequestParam(value = "appId", required = false) String appId) {
        return authenticationService.getDingUserByCode(code,corpId,appId);
    }

    @RequestMapping(value = "/sso/fingerPrintLogin", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "使用账号或者手机号协同设备id进行登录", httpMethod = "GET", notes = "使用账号或者手机号协同设备id进行登录")
    public  CommonResult<?> fingerPrintLogin(@RequestParam(value = "type", required = true) String type
            , @RequestParam(value = "loginValue", required = true) String loginValue
            , @RequestParam(value = "deviceId", required = true) String deviceId) throws AuthenticationException, ClientProtocolException, IOException {
        return authenticationService.fingerPrintLogin(type,loginValue,deviceId);
    }

    @RequestMapping(value = "/sso/getSysTemTheme", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "获取系统的风格设置", httpMethod = "GET", notes = "获取系统的风格设置")
    public  CommonResult<?> getSysTemTheme(String alias) throws AuthenticationException, ClientProtocolException, IOException {
        PortalFeignService service = AppUtil.getBean(PortalFeignService.class);
        String result=service.getPropertyByAlias(alias);
        return new CommonResult<String>(true, result);
    }

    @RequestMapping(value = "/sso/getAppByNoAuth", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "获取工作台应用", httpMethod = "GET", notes = "获取工作台应用")
    public  CommonResult<?> getAppByNoAuth() throws AuthenticationException, ClientProtocolException, IOException {
        return authenticationService.getAppByNoAuth();
    }

    @RequestMapping(value = "/sso/loadMySysAppOften", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "获取常用应用", httpMethod = "GET", notes = "获取常用应用")
    public  CommonResult<?> loadMySysAppOften() throws AuthenticationException, ClientProtocolException, IOException {
        return authenticationService.loadMySysAppOftenByNoAuth();
    }

    @RequestMapping(value = "/sso/getMyOftenFlowByNoAuth", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "获取常用应用", httpMethod = "GET", notes = "获取常用应用")
    public  CommonResult<?> getMyOftenFlowByNoAuth() throws AuthenticationException, ClientProtocolException, IOException {

        return authenticationService.getMyOftenFlowByNoAuth();
    }

    @RequestMapping(value = "/sso/messagelistNoUser", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "获取无用户的系统消息", httpMethod = "POST", notes = "获取无用户的系统消息")
    public  CommonResult<?> messagelistNoUser(@ApiParam(name="queryFilter",value="通用查询对象")@RequestBody QueryFilter queryFilter) throws AuthenticationException, ClientProtocolException, IOException {

        return authenticationService.messagelistNoUser(queryFilter);
    }


    @RequestMapping(value = "/sso/getWelcomeDage", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ApiOperation(value = "获取移动端欢迎页数据", httpMethod = "GET", notes = "获取移动端欢迎页数据")
    public  CommonResult<?> getWelcomeDage(String orgId) throws AuthenticationException, ClientProtocolException, IOException {
        return authenticationService.getWelcomeDage(orgId);
    }

}