package org.dromara.auth.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.auth.domain.bo.UserBo4Sys;
import org.dromara.auth.domain.vo.LoginVo;
import org.dromara.auth.service.IAuthStrategy;
import org.dromara.auth.service.SxzwfwLoginService;
import org.dromara.auth.service.SysLoginService;
import org.dromara.common.core.constant.CacheConstants;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.constant.UserConstants;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.redis.utils.CacheUtils;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.resource.api.RemoteMessageService;
import org.dromara.system.api.*;
import org.dromara.system.api.domain.vo.RemoteClientVo;
import org.dromara.system.api.model.LoginUser;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.rmi.server.ServerCloneException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@RequiredArgsConstructor
public class SxzwfwLoginServiceImpl implements SxzwfwLoginService {


    private final SysLoginService sysLoginService;
    private final ScheduledExecutorService scheduledExecutorService;

    @DubboReference
    private final RemoteClientService remoteClientService;
    @DubboReference(stub = "true")
    private final RemoteMessageService remoteMessageService;


    @Value("${justauth.type.sxzwfw.c-app-id}")
    private String cAppId;

    @Value("${justauth.type.sxzwfw.c-app-pwd}")
    private String cAppPwd;

    @Value("${justauth.type.sxzwfw.goto}")
    private String gotoUrl;

    @Value("${justauth.type.sxzwfw.server.server-url}")
    private String serverUrl;

    @Value("${justauth.type.sxzwfw.login.server-url}")
    private String loginServerUrl;


    @Value("${justauth.type.sxzwfw.user.legal-person-url}")
    private String legalPersonUrl;

    @Value("${wjb-client-id}")
    private String wjbClientId;
    @Value("${justauth.type.sxzwfw.user.natural-person-url}")
    private String naturalPersonUrl;


    @Override
    public LoginVo sxzwfwUserInfo(String gotoUrl, String clientId, String accessLink, Integer acctType, String tenantId) throws ServerCloneException {
        Map<String, String> headerMap = getSwzwfwHanderMap(accessLink);
        String body = HttpUtil.createGet(serverUrl).addHeaders(headerMap).form(new HashMap<>()).execute().body();
        log.info("令牌置换获取到 token：{}", body);
        //解析token
        Map<String, String> tokenMap = JsonUtils.parseObject(body, Map.class);
        if (CollectionUtil.isEmpty(tokenMap)) {
            return null;
        }
        if (!tokenMap.containsKey("C-API-Status")) {
            log.error("token 验证状态错误");
            return null;
        }
        String cApiStatus = tokenMap.get("C-API-Status");
        if (StringUtils.isEmpty(cApiStatus) || !cApiStatus.equals("00")) {
            log.info("token 验证状态无效{}", cApiStatus);
            return null;
        }
        if (!tokenMap.containsKey("C-Response-Body")) {
            log.info("无效token");
        }
        String token = tokenMap.get("C-Response-Body");
        headerMap.put("C-Dynamic-Password-Foruser", token);
        String resultUserInfo = HttpUtil.createPost(legalPersonUrl).addHeaders(headerMap).form(new HashMap<>()).execute().body();
        log.info("远程调用获取userInfo返回{}", resultUserInfo);
        JSONObject userInfoJson = JSONObject.parseObject(resultUserInfo);
        JSONObject responseBody = userInfoJson.getJSONObject("C-Response-Body");
        String userInfoStr = responseBody.getString("userInfo");
        UserBo4Sys userBo4Sys = JSONObject.parseObject(userInfoStr, UserBo4Sys.class);
        //查询用户
        userBo4Sys.setNickName(userBo4Sys.getUserName());
        userBo4Sys.setUserName(userBo4Sys.getCertNo());
        userBo4Sys.setPhonenumber(userBo4Sys.getContactMobile());
        if (StringUtils.isEmpty(tenantId) && !StringUtils.isEmpty(gotoUrl)) {
            int startIndex = gotoUrl.lastIndexOf('/'); // 找到最后一个空格的索引
            int endIndex = gotoUrl.length() - 1; // 字符串的最后一个字符的索引
            String lastSegment = gotoUrl.substring(startIndex + 1, endIndex + 1); // 截取最后一段
            userBo4Sys.setTenantIdKey(lastSegment);
            log.info("gotoUrl后缀截取{} ", lastSegment);
        }
        log.info("userInfoStr返回{}", userBo4Sys);
        userBo4Sys.setTenantId(tenantId);
        sysLoginService.register(userBo4Sys);
        if (!StringUtils.isBlank(gotoUrl) && "null".equals(gotoUrl)) {
            Object cacheObject = CacheUtils.get(GlobalConstants.SXZWFW_LOGIN_OUT_KEY + userBo4Sys.getUserName(), GlobalConstants.SXZWFW_LOGIN_OUT_KEY + userBo4Sys.getUserName());
            if (!ObjectUtil.isEmpty(cacheObject)) {
                userBo4Sys.setTenantId(cacheObject.toString());
                CacheUtils.clear(GlobalConstants.SXZWFW_LOGIN_OUT_KEY + userBo4Sys.getUserName());

            }
        }
        log.info("统一认证登陆，用户信息{}",userBo4Sys);
        LoginVo loginVo = sxzwfwUserInfo(userBo4Sys);
        RedisUtils.setCacheObject(CacheConstants.SXZWFW_TOKEN_KEY + userBo4Sys.getUserName(), token);
        return loginVo;

    }

    private Map<String, String> getSwzwfwHanderMap(String token) {
        HashMap<String, String> headerMap = new HashMap<>();
        headerMap.put("Content-Type", "application/json; charset=utf-8");
        headerMap.put("C-Tenancy-Id", "140000000000");
        headerMap.put("C-App-Id", cAppId);
        headerMap.put("C-App-Pwd", cAppPwd);
        headerMap.put("C-Dynamic-Password-Foruser", token);
        return headerMap;
    }

    @Override
    public String loginOut() {
        try {
            LoginUser loginUser = LoginHelper.getLoginUser();
            String token = RedisUtils.getCacheObject(CacheConstants.SXZWFW_TOKEN_KEY + loginUser.getUsername());
            Map<String, String> headerMap = getSwzwfwHanderMap(token);
            String body = HttpUtil.createPost(naturalPersonUrl).addHeaders(headerMap).form(new HashMap<>()).execute().body();
            log.error("退出登陆 响应：{}", body);
            //解析token
            Map<String, String> resultMap = JsonUtils.parseObject(body, Map.class);
            if (CollectionUtil.isEmpty(resultMap)) {
                return null;
            }
            if (!resultMap.containsKey("C-API-Status")) {
                log.error("token 验证状态错误");
                return null;
            }
            String cApiStatus = resultMap.get("C-API-Status");
            CacheUtils.put(GlobalConstants.SXZWFW_LOGIN_OUT_KEY + loginUser.getUsername(), GlobalConstants.SXZWFW_LOGIN_OUT_KEY + loginUser.getUsername(), loginUser.getTenantId());
            if (!StringUtils.isEmpty(cApiStatus) && cApiStatus.equals("00")) {
                RedisUtils.deleteObject(CacheConstants.SXZWFW_TOKEN_KEY + loginUser.getUsername());
                return loginServerUrl;
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return null;
    }

    @Override
    public String gotoSxzwfw(String gotourl) {

        String strParam = "?client_id=" + cAppId + "&utype=0&itype=1";
        if (!StringUtils.isEmpty(gotourl)) {
            strParam = strParam + "&goto=" + gotourl;
        } else {
            strParam = strParam + "&goto=" + gotoUrl;
        }
        return loginServerUrl + strParam;
    }

    private LoginVo sxzwfwUserInfo(UserBo4Sys userBo4Sys) throws ServerCloneException {


        RemoteClientVo clientVo = remoteClientService.queryByClientId(wjbClientId);

        // 查询不到 client
        if (ObjectUtil.isNull(clientVo)) {
            log.info("客户端id: {} 认证类型：{} 异常!.", wjbClientId);
            throw new ServiceException("客户端id异常" + wjbClientId);

        } else if (!UserConstants.NORMAL.equals(clientVo.getStatus())) {
            throw new ServiceException(MessageUtils.message("auth.grant.type.blocked"));
        }
        // 登录
        LoginVo loginVo = IAuthStrategy.login(JSON.toJSONString(userBo4Sys), clientVo, "wbjPassword");

        Long userId = LoginHelper.getUserId();
        scheduledExecutorService.schedule(() -> {
            remoteMessageService.publishMessage(userId, "欢迎登录专家库集约化管理平台");
        }, 3, TimeUnit.SECONDS);
        return loginVo;
    }
}
