package com.qmth.teachcloud.report.api;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qmth.boot.api.annotation.Aac;
import com.qmth.boot.api.annotation.BOOL;
import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.teachcloud.common.SignatureEntityTest;
import com.qmth.teachcloud.common.bean.dto.UserAuthenticationDto;
import com.qmth.teachcloud.common.bean.result.LoginResult;
import com.qmth.teachcloud.common.cache.ThirdUserAuthCacheUtil;
import com.qmth.teachcloud.common.config.DictionaryConfig;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicSchool;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.AppSourceEnum;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.service.CommonCacheService;
import com.qmth.teachcloud.common.service.SysUserService;
import com.qmth.teachcloud.common.service.TeachcloudCommonService;
import com.qmth.teachcloud.common.util.JacksonUtil;
import com.qmth.teachcloud.common.util.Result;
import com.qmth.teachcloud.common.util.ResultUtil;
import com.qmth.teachcloud.report.business.service.ReportCommonService;
import com.qmth.teachcloud.report.business.utils.EncrypAES;
import io.swagger.annotations.*;
import org.apache.commons.lang3.StringUtils;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.text.MessageFormat;
import java.util.Map;
import java.util.Objects;

@Api(tags = "武大开放接口层apiController")
@RestController
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/${prefix.url.reportWuda}")
public class WudaOpenApiController {
    private final static Logger log = LoggerFactory.getLogger(WudaOpenApiController.class);

    @Resource
    DictionaryConfig dictionaryConfig;

    @Resource
    CommonCacheService commonCacheService;

    @Resource
    SysUserService sysUserService;

    @Resource
    TeachcloudCommonService teachcloudCommonService;

    @Resource
    ReportCommonService reportCommonService;

    @ApiOperation(value = "cas鉴权接口")
    @RequestMapping(value = "/authentication", method = RequestMethod.GET)
    @ApiResponses({@ApiResponse(code = 200, message = "返回消息", response = Result.class)})
    @Aac(auth = BOOL.FALSE)
    public void authentication(HttpServletRequest request, HttpServletResponse response) throws IOException {
        log.info("student request.getRemoteUser():{}", JacksonUtil.parseJson(request.getRemoteUser()));
        String uid = request.getRemoteUser();
        if (Objects.isNull(uid)) {
            throw ExceptionResultEnum.NOT_LOGIN.exception();
        }
        // 测试用代码 --- 开始 ---
        Principal principal = request.getUserPrincipal();
        String cn = "";
        if (principal != null && principal instanceof AttributePrincipal) {
            AttributePrincipal aPrincipal = (AttributePrincipal) principal;
            //获取用户信息中公开的Attributes部分
            Map<String, Object> map = aPrincipal.getAttributes();
            // 获取姓名,可以根据属性名称获取其他属性
            cn = (String) map.get("cn");
            log.info("test-stu-map:{}", JSON.toJSONString(map));
            log.info("test-stu-cn:{}", cn);
        }
        BasicSchool basicSchool = commonCacheService.schoolCache(SystemConstant.SCHOOL_CODE);
        String testUrl = dictionaryConfig.sysDomain().getReportUrl() + basicSchool.getId() + "/" + uid + "/" + cn;
        log.info("test-stu-testUrl:{}", testUrl);
        String encoderUid = EncrypAES.encrypt(uid);
        log.info("test-encoderUid:{}", encoderUid);
        response.sendRedirect(dictionaryConfig.sysDomain().getReportUrl() + basicSchool.getId() + "/" + encoderUid);
    }

    @ApiOperation(value = "cas用户鉴权退出接口")
    @RequestMapping(value = "/user/authentication/logout", method = RequestMethod.GET)
    @ApiResponses({@ApiResponse(code = 200, message = "返回消息", response = Result.class)})
    @Aac(auth = BOOL.FALSE)
    public void authenticationLogout() throws IOException {
        reportCommonService.whuLogout();
    }

    @ApiOperation(value = "cas用户鉴权接口")
    @RequestMapping(value = "/user/authentication", method = RequestMethod.GET)
    @ApiResponses({@ApiResponse(code = 200, message = "返回消息", response = Result.class)})
    @Aac(auth = BOOL.FALSE)
    public void userAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException {
        log.info("user request.getRemoteUser():{}", JacksonUtil.parseJson(request.getRemoteUser()));
        String uid = request.getRemoteUser();
        if (Objects.isNull(uid)) {
            throw ExceptionResultEnum.NOT_LOGIN.exception();
        }
        // 测试用代码 --- 开始 ---
        Principal principal = request.getUserPrincipal();
        String cn = "";
        if (principal != null && principal instanceof AttributePrincipal) {
            AttributePrincipal aPrincipal = (AttributePrincipal) principal;
            //获取用户信息中公开的Attributes部分
            Map<String, Object> map = aPrincipal.getAttributes();
            // 获取姓名,可以根据属性名称获取其他属性
            cn = (String) map.get("cn");
            log.info("test-tea-map:{}", JSON.toJSONString(map));
            log.info("test-tea-cn:{}", cn);
        }
        // 测试结束
        UserAuthenticationDto userAuthenticationDto = new UserAuthenticationDto(uid, SystemConstant.getUuid());
        ThirdUserAuthCacheUtil.setAuthCode(userAuthenticationDto);
        String pattern = "{0}{1}{2}";
        String code = URLEncoder.encode(MessageFormat.format(pattern, userAuthenticationDto.getUid(), SignatureEntityTest.FIELD_JOINER, SignatureEntityTest.encrypt(userAuthenticationDto.getCode())), SystemConstant.CHARSET_NAME);
        // 测试开始
        String testPattern = "{0}{1}{2}{3}";
        String testCode = URLEncoder.encode(MessageFormat.format(testPattern, userAuthenticationDto.getUid() + "/" + cn, SignatureEntityTest.FIELD_JOINER, SignatureEntityTest.encrypt(userAuthenticationDto.getCode())), SystemConstant.CHARSET_NAME);
        log.info("test-tea-code:{}", testCode);
        log.info("test-tea-url:{}", dictionaryConfig.sysDomain().getLoginAuthenUrl() + testCode);
        // 测试结束
        log.info("code:{}", code);
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.sendRedirect(dictionaryConfig.sysDomain().getLoginAuthenUrl() + code + "/" + AppSourceEnum.WHU_THIRD);
    }

//    @ApiOperation(value = "cas用户鉴权测试接口")
//    @RequestMapping(value = "/user/authentication/test", method = RequestMethod.GET)
//    @ApiResponses({@ApiResponse(code = 200, message = "返回消息", response = Result.class)})
//    @Aac(auth = BOOL.FALSE)
//    public void userAuthenticationTest(HttpServletRequest request, HttpServletResponse response) throws IOException {
//        String uid = "yz1";
//        UserAuthenticationDto userAuthenticationDto = new UserAuthenticationDto(uid, SystemConstant.getUuid());
//        WhuUserAuthCacheUtil.setAuthCode(userAuthenticationDto);
//        String pattern = "{0}{1}{2}";
//        String code = URLEncoder.encode(MessageFormat.format(pattern, userAuthenticationDto.getUid(), SignatureEntityTest.FIELD_JOINER, SignatureEntityTest.encrypt(userAuthenticationDto.getCode())), SystemConstant.CHARSET_NAME);
//        log.info("code:{}", code);
//        response.setHeader("Access-Control-Allow-Origin", "*");
//        response.sendRedirect(dictionaryConfig.sysDomain().getLoginAuthenUrl() + code);
//    }

    @ApiOperation(value = "cas用户临时授权登录接口")
    @RequestMapping(value = "/user/authentication/login", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回消息", response = LoginResult.class)})
    @Aac(auth = BOOL.FALSE)
    public Result login(@ApiParam(value = "授权码信息", required = true) @RequestParam String code) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        String[] values = StringUtils.split(URLDecoder.decode(code, SystemConstant.CHARSET_NAME), SignatureEntityTest.FIELD_JOINER);
        if (Objects.isNull(values) || values.length != 2) {
            throw ExceptionResultEnum.ERROR.exception("临时授权码出错，请重新获取");
        }
        log.info("values:{}", JacksonUtil.parseJson(values));
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(SysUser::getLoginName, values[0]);
        SysUser sysUser = sysUserService.getOne(wrapper);
        //用户不存在
        if (Objects.isNull(sysUser)) {
            throw ExceptionResultEnum.USER_NO_DATA.exception();
        }
        //停用
        if (!sysUser.getEnable()) {
            throw ExceptionResultEnum.USER_ENABLE.exception();
        }

        String userAuthCode = ThirdUserAuthCacheUtil.getAuthCode(values[0]);
        if (Objects.isNull(userAuthCode) || !Objects.equals(values[1], URLDecoder.decode(SignatureEntityTest.encrypt(userAuthCode), SystemConstant.CHARSET_NAME))) {
            throw ExceptionResultEnum.ERROR.exception("临时授权码已过期");
        }
        LoginResult loginResult = teachcloudCommonService.login(sysUser.getPassword(), sysUser, AppSourceEnum.WHU_THIRD);
        ThirdUserAuthCacheUtil.deleteAuthCode(values[0]);
        return ResultUtil.ok(loginResult);
    }

//    @ApiOperation(value = "cas鉴权接口")
//    @RequestMapping(value = "/authentication/{studentCode}", method = RequestMethod.GET)
//    @ApiResponses({@ApiResponse(code = 200, message = "返回消息", response = Result.class)})
//    @Aac(auth = BOOL.FALSE)
//    public void authenticationStudentCode(HttpServletRequest request, HttpServletResponse response, @PathVariable String studentCode
//    ) throws IOException {
//        BasicSchool basicSchool = cacheService.schoolCache(SystemConstant.SCHOOL_CODE);
//        response.setHeader("Access-Control-Allow-Origin", "*");
//        response.sendRedirect(dictionaryConfig.sysDomain().getReportUrl() + basicSchool.getId() + "/" + studentCode);
//    }
}
