package com.qmth.teachcloud.cas.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qmth.boot.tools.signature.SignatureEntity;
import com.qmth.boot.tools.signature.SignatureType;
import com.qmth.teachcloud.cas.util.xjtu.Constants;
import com.qmth.teachcloud.exchange.common.bean.dto.syssetting.SimpleObject;
import com.qmth.teachcloud.exchange.common.bean.params.OpenParams;
import com.qmth.teachcloud.exchange.common.bean.params.RedirectParams;
import com.qmth.teachcloud.exchange.common.contant.SystemConstant;
import com.qmth.teachcloud.exchange.common.entity.BasicSchool;
import com.qmth.teachcloud.exchange.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.exchange.common.service.AuthInfoService;
import com.qmth.teachcloud.exchange.common.service.CommonCacheService;
import com.qmth.teachcloud.exchange.common.util.HttpUtil;
import com.qmth.teachcloud.exchange.common.util.JacksonUtil;
import com.qmth.teachcloud.exchange.common.util.Result;
import com.qmth.teachcloud.exchange.common.util.ServletUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * @Description: 西交大cas工具类
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2023/6/12
 */
@Component
public class XjtuCasUtil {
    private static final Logger log = LoggerFactory.getLogger(XjtuCasUtil.class);
//    private String teachcloudLoginUrl = null, logoutUrl = null, returnUrl = null;
//    private static final String LOGIN_BEFORE_XJU_LOGIC_API = "/api/admin/print/open/login_before_xju_logic";//西交大登录之前逻辑
//    private static final String ACCESS_TOKEN_URL = "http://org.xjtu.edu.cn/openplatform/oauth/getAccessToken";
//    private static final String USER_INFO_URL = "http://org.xjtu.edu.cn/openplatform/oauth/open/getUserInfo";
//    private static final String LOGOUT_URL = "http://org.xjtu.edu.cn/openplatform/oauth/logout";

    @Resource
    AuthInfoService authInfoService;

    @Resource
    CommonCacheService commonCacheService;

    /**
     * 西交大登录逻辑
     *
     * @param schoolCode
     * @param code
     * @param state
     * @param userType
     * @param employeeNo
     * @param returnUrl
     * @return
     * @throws IOException
     */
    public RedirectParams authentication(String schoolCode,
                                         String code,
                                         String state,
                                         String userType,
                                         String employeeNo,
                                         String returnUrl) throws IOException {
        if ((Objects.isNull(code) || Objects.equals(code, ""))
                || (Objects.isNull(employeeNo) || Objects.equals(employeeNo, ""))) {
            throw ExceptionResultEnum.ERROR.exception("请先通过学校地址登录");
        }
        authInfoService.appHasExpired(schoolCode);

        BasicSchool basicSchool = commonCacheService.schoolCache(schoolCode);
        Objects.requireNonNull(basicSchool, "学校信息不存在");

        Map<String, SimpleObject> mapSetting = commonCacheService.getSysSetting(basicSchool.getId());
        String teachcloudLoginUrl = null;
        if (!CollectionUtils.isEmpty(mapSetting)) {
            log.info("mapSetting1 value:{}", JSONObject.toJSONString(mapSetting));
            SimpleObject simpleObject = mapSetting.get(SystemConstant.TEACH_CLOUD_PRINT);
            Objects.requireNonNull(simpleObject, "未配置知学知考地址");
            log.info("simpleObject1 value:{}", JSONObject.toJSONString(simpleObject));
            String teachCloudPrint = simpleObject.getValue();
            if (Objects.nonNull(teachCloudPrint) && !Objects.equals(teachCloudPrint.trim(), "")) {
                teachcloudLoginUrl = teachCloudPrint.replace("/login", SystemConstant.CAS_VUE_LOGIN_PATH);
            }
            simpleObject = mapSetting.get(SystemConstant.CAS_ADDRESS);
            Objects.requireNonNull(simpleObject, "未配置单点登录地址");
            String casAddress = simpleObject.getValue();
            if (Objects.nonNull(casAddress) && !Objects.equals(casAddress.trim(), "")) {
                if (casAddress.lastIndexOf("/") == casAddress.length() - 1) {
                    casAddress = casAddress.substring(0, casAddress.lastIndexOf("/"));
                }
                String logoutUri = Constants.SSO_LOGOUT_URI;
                logoutUri = logoutUri.replace(SystemConstant.SCHOOL_CODE, schoolCode);
                returnUrl = casAddress + logoutUri;
            }
        }

        //2022-12-06加入登录之前逻辑
        if (Objects.isNull(teachcloudLoginUrl) || Objects.equals(teachcloudLoginUrl, "")) {
            throw ExceptionResultEnum.PARAMS_ERROR.exception("知学登录跳转地址不存在");
        }
        int index = teachcloudLoginUrl.lastIndexOf(SystemConstant.PATH_SUBSTR);
        String hostUrl = teachcloudLoginUrl.substring(0, index);
        if (hostUrl.contains(SystemConstant.PATH_MATCH)) {
            hostUrl = hostUrl.replace(SystemConstant.PATH_MATCH, schoolCode);
        }

        Long timestamp = System.currentTimeMillis();
        String signature = SignatureEntity.build(SignatureType.SECRET, SystemConstant.METHOD, Constants.LOGIN_BEFORE_XJU_LOGIC_API, timestamp, basicSchool.getAccessKey(), basicSchool.getAccessSecret());

        String callResult = HttpUtil.postJson(hostUrl + Constants.LOGIN_BEFORE_XJU_LOGIC_API, JacksonUtil.parseJson(employeeNo), signature, timestamp);
//        String schoolCodeParam = null;
        if (!StringUtils.isBlank(callResult)) {
            log.info("callbackResult:{}", JacksonUtil.parseJson(callResult));
            Result result = JSON.parseObject(callResult, Result.class);
            if (result.getCode() == HttpStatus.OK.value()) {
                Object data = result.getData();
                List<Map> sysuserList = JSONObject.parseArray(JSON.toJSONString(data), Map.class);
                if (CollectionUtils.isEmpty(sysuserList)) {
                    throw ExceptionResultEnum.ERROR.exception("未查到此用户");
                }
            } else {
                throw ExceptionResultEnum.ERROR.exception("调用知学知考西交大登录前查找账号接口失败");
            }
        }

        Map<String, Object> accessTokenParams = new LinkedHashMap<>();
        accessTokenParams.put("code", code);
        String accessTokenResult = HttpUtil.post(Constants.ACCESS_TOKEN_URL, accessTokenParams, null);
        String accessToken = null, gsessionId = null;

        //获取accessToken
        if (Objects.nonNull(accessTokenResult)) {
            log.info("accessTokenResult:{}", JacksonUtil.parseJson(accessTokenResult));
            JSONObject jsonObject = JSONObject.parseObject(accessTokenResult);
            JSONObject object = jsonObject.getJSONObject("data");
            String message = jsonObject.getString("message");
            if (Objects.nonNull(object) && Objects.nonNull(message) && Objects.equals(message, "成功")) {
                accessToken = object.getString("accessToken");
                gsessionId = object.getString("gsessionId");
            } else {
                throw ExceptionResultEnum.ERROR.exception(message);
            }
        }

        OpenParams openParams = null;
        //获取用户信息
        if (Objects.nonNull(accessToken)) {
            String userInfoResult = HttpUtil.post(Constants.USER_INFO_URL, null, accessToken);
            if (Objects.nonNull(userInfoResult)) {
                log.info("userInfoResult:{}", JacksonUtil.parseJson(userInfoResult));
                openParams = new OpenParams();
//                openParams.setResult(JacksonUtil.parseJson(userInfoResult));
                JSONObject jsonObject = JSONObject.parseObject(userInfoResult);
                JSONObject object = jsonObject.getJSONObject("data");
                String message = jsonObject.getString("message");
                JSONArray userTypeJsonArray = object.getJSONArray("userTypes");
                JSONArray deptInfoJsonArray = object.getJSONArray("deptInfos");
                if (Objects.nonNull(object) && Objects.nonNull(message) && Objects.equals(message, "成功")) {
                    openParams.setOrgName(object.getString("orgName"));
                    if (Objects.nonNull(userTypeJsonArray) && userTypeJsonArray.size() > 0) {
                        JSONObject userTypeJsonObject = userTypeJsonArray.getJSONObject(0);
                        openParams.setName(userTypeJsonObject.getString("memberName"));
                        Integer userTypeRole = userTypeJsonObject.getInteger("userType");
                        if (Objects.nonNull(userTypeRole) && userTypeRole.intValue() == 1) {
                            openParams.setRoleName("学生");
                        } else if (Objects.nonNull(userTypeRole) && userTypeRole.intValue() == 2) {
                            openParams.setRoleName("教职工");
                        }
                    }
                    if (Objects.nonNull(deptInfoJsonArray) && deptInfoJsonArray.size() > 0) {
                        JSONObject deptInfoJsonArrayJsonObject = deptInfoJsonArray.getJSONObject(0);
                        openParams.setDeptName(deptInfoJsonArrayJsonObject.getString("deptName"));
                    }
                } else {
                    throw ExceptionResultEnum.ERROR.exception(message);
                }
            }
        }

        //登出
        if (Objects.nonNull(gsessionId)) {
            StringJoiner stringJoiner = new StringJoiner("");
            stringJoiner.add(returnUrl).add(SystemConstant.GET_UNKNOWN).add("gSessionId")
                    .add(SystemConstant.GET_EQUAL).add(gsessionId);
            returnUrl = stringJoiner.toString();
        } else {
            throw ExceptionResultEnum.ERROR.exception("gSessionId为空");
        }
        return new RedirectParams(employeeNo, schoolCode, returnUrl, openParams);
    }

    /**
     * 西交大注销逻辑
     *
     * @param schoolCode
     * @param gSessionId
     * @throws IOException
     */
    public void logout(String schoolCode,
                       String gSessionId) throws IOException {
        if (Objects.isNull(gSessionId) || Objects.equals(gSessionId, "")) {
            throw ExceptionResultEnum.PARAMS_ERROR.exception("sessionId为空");
        }
        authInfoService.appHasExpired(schoolCode);
        BasicSchool basicSchool = commonCacheService.schoolCache(schoolCode);
        Objects.requireNonNull(basicSchool, "学校信息不存在");
        HttpServletResponse response = ServletUtil.getResponse();
        Map<String, Object> logoutParams = new LinkedHashMap<>();
        logoutParams.put("gSessionId", gSessionId);
        String logoutResult = HttpUtil.post(Constants.CAS_LOGOUT_URL, logoutParams, null);
        if (Objects.nonNull(logoutResult)) {
            log.info("logoutResult:{}", JacksonUtil.parseJson(logoutResult));
            JSONObject jsonObject = JSONObject.parseObject(logoutResult);
            String message = jsonObject.getString("message");
            if (Objects.nonNull(message) && Objects.equals(message, "成功")) {
                Map<String, SimpleObject> mapSetting = commonCacheService.getSysSetting(basicSchool.getId());
                String returnUrl = null;
                if (!CollectionUtils.isEmpty(mapSetting)) {
                    log.info("mapSetting1 value:{}", JSONObject.toJSONString(mapSetting));
                    SimpleObject simpleObject = mapSetting.get(SystemConstant.CAS_ADDRESS);
                    Objects.requireNonNull(simpleObject, "未配置单点登录地址");
                    String casAddress = simpleObject.getValue();
                    String loginUri = null;
                    if (Objects.nonNull(casAddress) && !Objects.equals(casAddress.trim(), "")) {
                        if (casAddress.lastIndexOf("/") == casAddress.length() - 1) {
                            casAddress = casAddress.substring(0, casAddress.lastIndexOf("/"));
                        }
                        loginUri = casAddress + Constants.SSO_LOGIN_URI;
                    }
                    simpleObject = mapSetting.get(Constants.APP_ID);
                    Objects.requireNonNull(simpleObject, "未配置学校appId");
                    returnUrl = Constants.OAUTH_URL + SystemConstant.GET_UNKNOWN +
                            Constants.APP_ID + SystemConstant.GET_EQUAL + simpleObject.getValue() + SystemConstant.GET_SYMBOL +
                            Constants.REDIRECT_URI + SystemConstant.GET_EQUAL + loginUri + "&responseType=code&scope=user_info&state=1234";
                }
                response.setHeader(SystemConstant.ACCESS_CONTROL_ALLOW_ORIGIN, SystemConstant.PATH_MATCH);
                response.sendRedirect(returnUrl);
            }
        }
    }
}
