package com.ruoyi.web.controller.cas;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.config.CasConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.AesUtil;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.framework.interceptor.cas.CASUser;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.net.URLEncoder;

@Slf4j
@Controller
public class CASLoginController {
    @Autowired
    private CASUser casUser;
    @Autowired
    private SysLoginService loginService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ServerConfig serverConfig;

    //cas服务器认证登录地址：http://10.152.70.21:8080/cas/login
//    @Value("${cas.server-logout-url}")
//    public String casServerLoginUrl;

    //cas服务器认证登出地址：API未提供，代码中岗检系统自己做跳转使用到 cas client 没用到   http://10.152.70.21:8080/cas/logout
//    @Value("${cas.server-logout-url}")
//    public String casServerLogoutUrl;

    // 前端页面地址 服务器IP http://10.152.72.5/postcheck
    // 前端页面地址 开发机IP http://10.152.164.68/postcheck
//    @Value("${cas.webStartPage}")
//    public String webStartPage;

    @Autowired
    private CasConfig casConfig;

    /**
     * 1、前端第一次求情：服务器转发浏览器到CAS login
     * http://10.152.164.68:8180/redirectpostcheck
     *
     * @return
     */
    @RequestMapping("/redirectpostcheck")
    public String redirectpostcheck(HttpServletRequest request) {

        String serverLoginUrl = casConfig.getServerLoginUrl(); // http://10.152.70.21:8080/cas/login
//        String serverLogoutUrl = casConfig.getServerLogoutUrl();
//        String webStartPage = casConfig.getWebStartPage();
//
//        System.out.println("=============================/redirectpostcheck========================================================");
//        System.out.println("this.CAS登录地址 casServerLoginUrl = " + this.casServerLoginUrl);
//        System.out.println("this.CAS登出地址 casServerLogoutUrl = " + this.casServerLogoutUrl);
//        System.out.println("this.前端页面登录地址 webStartPage = " + this.webStartPage);
//        System.out.println();
//        System.out.println("CAS登录地址 casServerLoginUrl = " + serverLoginUrl);
//        System.out.println("CAS登出地址 casServerLogoutUrl = " + serverLogoutUrl);
//        System.out.println("前端页面登录地址 webStartPage = " + webStartPage);
//        System.out.println("=====================================================================================");


        HttpSession session = request.getSession(true);
        session.setAttribute("CASLoginUSer01", "CASLoginUSer");
        session.setMaxInactiveInterval(60 * 60 * 24);//单位是秒：24小时

        //获取服务器的访问地址 http://10.152.164.68:8180
        String serverUrl = serverConfig.getUrl() + "/postcheck";
        try {
            serverUrl = URLEncoder.encode(serverUrl, "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }

//        String webStartPage = "http://10.152.70.21:8080/cas/login?service=http%3A%2F%2F10.152.164.68%3A8180%2Fpostcheck";  //http://10.152.164.68:8180/postcheck
//        String webStartPage = "http://10.152.70.21:8080/cas/login?service=" + serverUrl;  //http://10.152.164.68:8180/postcheck
        String webStartPageFull = serverLoginUrl + "?service=" + serverUrl;  //http://10.152.164.68:8180/postcheck
        log.info("【CAS】前端来登录了，创建 session 转发到CAS登录 webStartPage :{}", webStartPageFull);
        return "redirect:" + webStartPageFull;
    }

    /**
     * 前端退出：服务端销毁Session，转发浏览器到CSA logout，回到地址是第一步的服务器地址（呈现的浏览器跳转轨迹：CAS退出、CAS登录）
     *
     * @param request
     * @return
     */
    @RequestMapping("/redirectpostcheckout") // http://10.152.164.68:8180/redirectpostcheckout
    public String redirectpostcheckout(HttpServletRequest request) {
//        String serverLoginUrl = casConfig.getServerLoginUrl();
        String serverLogoutUrl = casConfig.getServerLogoutUrl();
//        String webStartPage = casConfig.getWebStartPage();
//        System.out.println("=====================================/redirectpostcheckout================================================");
//        System.out.println("CAS登录地址 casServerLoginUrl = " + serverLoginUrl);
//        System.out.println("CAS登出地址 casServerLogoutUrl = " + serverLogoutUrl);
//        System.out.println("前端页面登录地址 webStartPage = " + webStartPage);
//        System.out.println("=====================================================================================");

        HttpSession session = request.getSession();
        session.removeAttribute("CASLoginUSer01");
        session.setMaxInactiveInterval(-1);//立即销毁
        session.invalidate();

        //获取服务器的访问地址 http://10.152.164.68:8180
        String serverUrl = serverConfig.getUrl() + "/redirectpostcheck";
        try {
            serverUrl = URLEncoder.encode(serverUrl, "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }

//        String webStartPage = "http://10.152.70.21:8080/cas/login?service=http%3A%2F%2F10.152.164.68%3A8080%2Fpostcheck"; //http://10.152.164.68:8080/postcheck
//        String webStartPage = "http://10.152.70.21:8080/cas/logout?service=http://10.152.164.68:8080/postcheck";
//        String webStartPage = "http://10.152.70.21:8080/cas/logout";
//        String webStartPage = "http://10.152.70.21:8080/cas/logout?service=http://10.152.164.68:8180/redirectpostcheck";
//        String webStartPage = "http://10.152.70.21:8080/cas/logout?service=" + serverUrl;
        String webStartPageFull = serverLogoutUrl + "?service=" + serverUrl;
        log.info("【CAS】前端来退出CAS，销毁 session ，转发 CAS退出  webStartPage : {}", webStartPageFull);
//        log.info("【CAS】前端来退出CAS了，转发请求链接到CAS退出页面 webStartPage : {}", webStartPage);
        return "redirect:" + webStartPageFull;
    }

    /**
     * 2、CAS回调：CAS将将浏览器转发到此接口，再转发到前端：前端收到请求后，下一步再获取登录用户信息
     *
     * @param request
     * @return
     */
    // http://10.152.164.68:8180/postcheck      http://10.152.164.68:8180/cas/login
    @RequestMapping("/postcheck")
    public String casLogin(HttpServletRequest request) {
        //自己的前端登录页面：http://10.152.72.5:8181/postcheck
        String webStartPage = casConfig.getWebStartPage();
//        System.out.println("==============================/postcheck=======================================================");
//        System.out.println("CAS登录地址 casServerLoginUrl = " + serverLoginUrl);
//        System.out.println("CAS登出地址 casServerLogoutUrl = " + serverLogoutUrl);
//        System.out.println("前端页面登录地址 webStartPage = " + webStartPage);
//        System.out.println("=====================================================================================");

        HttpSession session = request.getSession();
        Object sessionAttribute = session.getAttribute("CASLoginUSer01");
        log.info("【CAS】CAS回调过来了，认证完成，获取用户 session ：{}", sessionAttribute);

        if (sessionAttribute == null) {
            //获取服务器的访问地址 http://10.152.164.68:8180
            String serverUrl = serverConfig.getUrl() + "/redirectpostcheck";
            try {
                serverUrl = URLEncoder.encode(serverUrl, "utf-8");
            } catch (Exception e) {
                e.printStackTrace();
            }
//            serverUrl = "http://10.152.164.68:8180/redirectpostcheck";
            log.info("【CAS】CAS回调过来了，认证完成，获取用户 session 为空 转发再去登录一次 redirectpostcheck ：{}", serverUrl);
            return "redirect:" + serverUrl;
        }

//        log.info("【CAS】统一认证登录结束回调过来了，认证完成，开始获取登录用户。");
//        log.info("【CAS】回调过来了，认证开始了 request = {}", request);
//        log.info("【CAS】回调过来了，认证开始了 获取携带的所有参数 request.getParameterMap() : {}", request.getParameterMap());

        Long ssoUserId = casUser.getSSOUserId();
        if (ssoUserId == null) {
            throw new BaseException("单点登录失败，未获取到正确的用户信息，请稍后重启！");
        }
        String ssoUserIdStr = AesUtil.aesEncrypt(ssoUserId.toString(), AesUtil.aesKey);//加密
//        log.info("【CAS】CAS回调过来了，认证完成，将用户ID进行加密处理，ssoUserIdStr = {}", ssoUserIdStr);

//        String webStartPage = "http://10.152.164.68/postcheck?username=" + ssoUserIdStr;
        String webStartPageFull = webStartPage + "?username=" + ssoUserIdStr;
        log.info("【CAS】CAS回调过来了，认证完成，将用户ID进行加密处理， 将页面转发到前端地址：{}", webStartPageFull);
        return "redirect:" + webStartPageFull;

//        return "forward:http://10.152.161.23/postcheck";
//        return "redirect:https://www.baidu.com/";
//        return "redirect:index2.html";
//        return "forward:/casLogin.jsp";
//        return "redirect:/casLogin.jsp";
    }


    /**
     * 3、浏览器把用户ID的加密串传过来，此方法生成Token后返回前端
     * CAS回调后将请求转发到前端页面
     *
     * @param loginBody 登录信息
     * @return 结果
     */
//    @RequestMapping("/postcheck/login")
//    @ResponseBody
    public AjaxResult casLogin(@RequestBody LoginBody loginBody, HttpServletRequest request) {
//        String serverLoginUrl = casConfig.getServerLoginUrl();
//        String serverLogoutUrl = casConfig.getServerLogoutUrl();
//        String webStartPage = casConfig.getWebStartPage();
//        System.out.println("=====================================/postcheck/login================================================");
//        System.out.println("CAS登录地址 casServerLoginUrl = " + serverLoginUrl);
//        System.out.println("CAS登出地址 casServerLogoutUrl = " + serverLogoutUrl);
//        System.out.println("前端页面登录地址 webStartPage = " + webStartPage);
//        System.out.println("=====================================================================================");

        System.out.println();
        log.info("【CAS】前端从CAS登录后，过来登录岗检系统。loginBody ：{}", JSON.toJSONString(loginBody));
        System.out.println();
        AjaxResult ajax = AjaxResult.success();


        //TODO 临时：测试CAS登录时从后台获取用户信息
//        if ("CasAdmin".equalsIgnoreCase(loginBody.getUsername()) || StringUtils.isBlank(loginBody.getUsername())) {
//        if (StringUtils.isBlank(loginBody.getUsername())) {
//        Long ssoUserId = casUser.getSSOUserId();
//        log.info("【CAS】前端来登录了，获取登录用户：{}", ssoUserId);
//        if (ssoUserId == null) {
        String code = loginBody.getCode();
//        log.info("【CAS】前端来登录了，解密前loginBody.code：{}", code);
        String userIdStr = AesUtil.aesDecrypt(code, AesUtil.aesKey);//解密
//        log.info("【CAS】前端来登录了，解密后loginBody.code：{}", ssoUserIdStr);
        long ssoUserId = Long.parseLong(userIdStr);

//
//        HttpSession session = request.getSession(true);
//        session.setAttribute("CASLoginUSer01", code);
//        session.setMaxInactiveInterval(60 * 60 * 24);//单位是秒：24小时

//            HttpSession session = request.getSession();
//            log.info("【CAS】前端来登录了，获取 session：{}", session);
//            Object cAsuserId123456 = session.getAttribute("CAsuserId123456");
//            log.info("【CAS】前端来登录了，获取 session.cAsuserId123456：{}", cAsuserId123456);
//            long parseLong = Long.parseLong(cAsuserId123456.toString());
//            log.info("【CAS】前端来登录了，获取 session.Long.parseLong(cAsuserId123456.toString())：{}", parseLong);
//            ssoUserId = parseLong;
//            ajax = AjaxResult.error("统一认证失败，未获取到用户登录信息，请稍后重试！");
//            return ajax;
//        ssoUserId = 6l;
//        }

        SysUser sysUser = sysUserService.selectUserById(ssoUserId);
        String casUserPback = sysUser.getCasUserPback();
        casUserPback = AesUtil.aesDecrypt(casUserPback, AesUtil.aesKey);//解密

        // 生成令牌
        String token = loginService.login(sysUser.getUserName(), casUserPback, null, null, false);
        ajax.put(Constants.TOKEN, token);
        log.info("【CAS】前端来登录了，返回登录用户：{}", JSON.toJSONString(ajax));
        return ajax;
    }
}
