package com.sobot.common.login;

import android.content.Context;

import com.sobot.common.login.callback.SobotResultBlock;
import com.sobot.common.login.callback.SobotResultCode;
import com.sobot.common.login.db.FunctionManager;
import com.sobot.common.login.db.HostManager;
import com.sobot.common.login.db.ServiceInfoManager;
import com.sobot.common.login.model.HostModel;
import com.sobot.common.login.model.OnlineUserEntity;
import com.sobot.common.login.model.ServiceFunctionVoModel;
import com.sobot.common.login.model.SobotCallBaseCode;
import com.sobot.common.login.model.SobotServiceInfoModel;
import com.sobot.common.login.model.TokenModel;
import com.sobot.common.login.permission.SobotPermissionApi;
import com.sobot.common.login.permission.SobotPermissionManager;
import com.sobot.gson.SobotGsonUtil;
import com.sobot.network.apiUtils.SobotBaseCode;
import com.sobot.network.apiUtils.SobotHttpUtils;
import com.sobot.network.http.HttpBaseUtils;
import com.sobot.utils.SobotLogUtils;
import com.sobot.utils.SobotMD5Util;
import com.sobot.utils.SobotSharedPreferencesUtil;
import com.sobot.utils.SobotStringUtils;

import org.json.JSONArray;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * app 登录合并类
 */
public class SobotLoginTools {

    //内部类单例
    private SobotLoginTools() {
    }

    public static SobotLoginTools getInstance() {
        return SobotLoginToolsHolder.instance;
    }

    private static class SobotLoginToolsHolder {
        private static final SobotLoginTools instance = new SobotLoginTools();
    }


    private SobotServiceInfoModel mServiceInfoModel;

    public SobotServiceInfoModel getServiceInfo() {
        if (mServiceInfoModel == null) {
            mServiceInfoModel = ServiceInfoManager.getInstance().getInfo();
        }
        return mServiceInfoModel;
    }

    private List<ServiceFunctionVoModel> functionVoModelList;

    //获取权限列表
    public List<ServiceFunctionVoModel> getServiceFunctionVoModel() {
        if (functionVoModelList == null && FunctionManager.getInstance().getFunctionVos() != null) {
            functionVoModelList = FunctionManager.getInstance().getFunctionVos();
        }
        if (functionVoModelList == null) {
            functionVoModelList = new ArrayList<>();
        }
        return functionVoModelList;
    }

    public void setServiceInfo(SobotServiceInfoModel newServiceInfo) {
        ServiceInfoManager.getInstance().deleteAll();
        mServiceInfoModel = newServiceInfo;
        if (mServiceInfoModel != null) {
            ServiceInfoManager.getInstance().insert(mServiceInfoModel);
        } else {
            ServiceInfoManager.getInstance().deleteAll();
        }
    }


    private HostModel mHostModel;

    //获取域名
    public HostModel getHostModel() {
        if (mHostModel == null) {
            mHostModel = HostManager.getInstance().getHost();
        }
        return mHostModel;
    }

    public void setHostModel(HostModel newHostModel) {
        HostManager.getInstance().deleteAll();
        if (newHostModel != null) {
            if ((newHostModel.getHost().contains("api-c"))  && (!newHostModel.getHost().contains("api-c.sobot.com/text") && !newHostModel.getHost().contains("api-c.soboten.com/text"))) {
                if (!newHostModel.getHost().endsWith("/")) {
                    newHostModel.setHost(newHostModel.getHost() + "/text/");
                } else {
                    newHostModel.setHost(newHostModel.getHost() + "text/");
                }
            }
        }
        mHostModel = newHostModel;
        if (mHostModel != null) {
            HostManager.getInstance().insert(mHostModel);
        } else {
            HostManager.getInstance().deleteAll();
        }
    }


    //呼叫 v6 获取 accessToken
    public String getAccessToken() {
        if (getServiceInfo() != null) {
            return SobotStringUtils.checkStringIsNull(getServiceInfo().getAccess_token());
        }
        return "";
    }

    //呼叫 v6 获取 accessToken
    public String getTempId() {
        if (getServiceInfo() != null) {
            return SobotStringUtils.checkStringIsNull(getServiceInfo().getTempId());
        }
        return "";
    }

    //呼叫 v6 获取 accessToken
    public String getToken() {
        if (getServiceInfo() != null) {
            return SobotStringUtils.checkStringIsNull(getServiceInfo().getToken());
        }
        return "";
    }

    // 检查token是否过期 12个小时  返回true 有效； false 过期
    public boolean checkExpiresToken() {
        if (getServiceInfo() != null) {
            long difference = System.currentTimeMillis() - getServiceInfo().getLogin_time();
            if (getServiceInfo().getLogin_time() > 0 && (difference > 12 * 60 * 60 * 1000)) {
                SobotLogUtils.d("上次登录距离当前的时间:" + difference + "ms,已经超过12小时，token已经过期");
                return false;
            }
        }
        return true;
    }

    public boolean isLogin() {
        //登录客户对象不为空，token 不为空，token 没过期 才判定已经登录成功，其它情况都是没登录
        if (getServiceInfo() != null && !SobotStringUtils.isEmpty(getServiceInfo().getToken()) && checkExpiresToken()) {
            return true;
        } else {
            return false;
        }
    }

    //判断是否已经登录
    public boolean isLogin(String loginAccount) {
        //登录客户对象不为空，登录账号和登录对象里边账号一样，token 不为空，token 没过期 才判定已经登录成功，其它情况都是没登录
        if (getServiceInfo() != null && !SobotStringUtils.isEmpty(loginAccount) && loginAccount.equals(getServiceInfo().getLoginAccount()) && !SobotStringUtils.isEmpty(getServiceInfo().getToken()) && checkExpiresToken()) {
            return true;
        } else {
            return false;
        }
    }

    //清除登录token
    public void clearLoginToken() {
        SobotServiceInfoModel tempUserEntity = getServiceInfo();
        if (tempUserEntity != null) {
            tempUserEntity.setAccess_token("");
            tempUserEntity.setToken("");
            setServiceInfo(tempUserEntity);
        }
    }

    //清除登录信息,不清除域名
    public void clearLoginInfo() {
        clearLoginInfo(false);
    }

    /**
     * 清除登录信息
     *
     * @param isClearHost 是否清理域名
     */
    public void clearLoginInfo(boolean isClearHost) {
        ServiceInfoManager.getInstance().deleteAll();
        mServiceInfoModel = null;
        if (isClearHost) {
            HostManager.getInstance().deleteAll();
        }
    }

    /**
     * 执行登录操作
     * 1、通过账号密码登录获取token;2、根据token获取客服角色权限等信息；3、如果是呼叫V6或者电销，先获取AccessToken；4、再根据客服app或者客服SDK登录同时又买了在线产品判断是否执行在线操作逻辑
     *
     * @param cancelTag
     * @param mContext
     * @param isAppOrOnlineLogin 客服app或者客服SDK登录传true 工单或呼叫Sdk 传false
     * @param host
     * @param openApiHost
     * @param loginAcount        登录账号
     * @param loginPwd           登录密码
     * @param factorVerifyCode    开启双认证后，邮箱验证码
     * @param paramsMap          单独执行在线登录逻辑 参数
     * @param resultBlock
     */
    public void doLogin(final Object cancelTag, final Context mContext, final boolean isAppOrOnlineLogin, final String host, final String openApiHost, final String loginAcount, final String loginPwd,String factorVerifyCode, final Map<String, Object> paramsMap, final SobotResultBlock resultBlock) {
        if (SobotStringUtils.isEmpty(host)) {
            SobotLogUtils.i("host 域名不能为空");
            if (resultBlock != null) {
                resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "域名不能为空", getServiceInfo());
            }
            return;
        }
        if (isLogin(loginAcount)) {
            SobotLogUtils.i("已经登录成功,不用重新登录");
            if (resultBlock != null) {
                resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "已经登录成功", getServiceInfo());
            }
            return;
        }
        Map<String, String> headerMap = new HashMap<>();
        headerMap.put("from", "2");
        Map<String, Object> params = new HashMap<>();
        params.put("version", paramsMap.get("version"));
        params.put("loginUser", loginAcount);
        params.put("loginPwd", loginPwd);
        if(SobotStringUtils.isNoEmpty(factorVerifyCode)) {
            params.put("factorVerifyCode", factorVerifyCode);
        }
        SobotHttpUtils.doPost(cancelTag, host + "/basic-login/serviceAppLogin/4", 8000, params, headerMap, new HttpBaseUtils.StringCallBack() {
            @Override
            public void onResponse(String response) {
                SobotCallBaseCode result = SobotGsonUtil.jsonToBean(response, SobotCallBaseCode.class);
                if (result != null && !SobotStringUtils.isEmpty(result.getRetCode()) && "000000".equals(result.getRetCode()) && !SobotStringUtils.isEmpty(result.getItem())) {
                    final long login_time = System.currentTimeMillis();
                    final String token = (String) result.getItem();
                    getuserEntityInfo(cancelTag, mContext, host, token, "", new SobotResultBlock() {
                        @Override
                        public void resultBolok(SobotResultCode code, String msg, Object obj) {
                            if (code == SobotResultCode.CODE_SUCCEEDED) {
                                SobotServiceInfoModel serviceInfoModel = (SobotServiceInfoModel) obj;
                                if (serviceInfoModel != null) {
                                    serviceInfoModel.setLogin_time(login_time);
                                    serviceInfoModel.setToken(token);
                                    serviceInfoModel.setLoginAccount(loginAcount);
                                    serviceInfoModel.setLoginPwd(loginPwd);
                                    if ((serviceInfoModel.getCallV6Flag() == 1 || SobotPermissionManager.isHasNewPermission(SobotPermissionManager.SCC))) {
                                        //如果是v6呼叫
                                        String tempHost = openApiHost;
                                        if (tempHost.contains("/text")) {
                                            tempHost = tempHost.replace("/text", "");
                                        }
                                        final SobotServiceInfoModel tempServiceInfoModel = serviceInfoModel;
                                        doAccessToken(cancelTag, tempHost, serviceInfoModel.getToken(), new SobotResultBlock() {
                                            @Override
                                            public void resultBolok(SobotResultCode code, String msg, Object obj) {
                                                if (code == SobotResultCode.CODE_SUCCEEDED) {
                                                    SobotServiceInfoModel tempUserEntity = tempServiceInfoModel;
                                                    if (obj != null && obj instanceof String && SobotStringUtils.isNoEmpty((String) obj)) {
                                                        String accessToken = (String) obj;
                                                        tempUserEntity.setAccess_token(accessToken);
                                                        //判断是否有对话功能
                                                        if (SobotPermissionManager.checkPermission(SobotPermissionApi.USER_PERMISSION_TYPE_TALK) && isAppOrOnlineLogin) {
                                                            getAdminStatus(cancelTag, mContext, host, paramsMap, tempUserEntity, resultBlock);
                                                        } else {
                                                            setServiceInfo(tempUserEntity);
                                                            SobotSharedPreferencesUtil.getInstance(mContext).put(SobotLoginConstant.SOBOT_LOGIN_USER_INFO, tempUserEntity);
                                                            if (resultBlock != null) {
                                                                resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", tempUserEntity);
                                                            }
                                                        }
                                                    } else {
                                                        SobotLogUtils.i("accessToken获取失败");
                                                        if (resultBlock != null) {
                                                            resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", tempServiceInfoModel);
                                                        }
                                                    }
                                                } else {
                                                    SobotLogUtils.i("accessToken获取失败");
                                                    if (resultBlock != null) {
                                                        resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", tempServiceInfoModel);
                                                    }
                                                }
                                            }
                                        });
                                    } else {
                                        //判断是否有对话功能
                                        if (SobotPermissionManager.checkPermission(SobotPermissionApi.USER_PERMISSION_TYPE_TALK) && isAppOrOnlineLogin) {
                                            getAdminStatus(cancelTag, mContext, host, paramsMap, serviceInfoModel, resultBlock);
                                        } else {
                                            setServiceInfo(serviceInfoModel);
                                            SobotSharedPreferencesUtil.getInstance(mContext).put(SobotLoginConstant.SOBOT_LOGIN_USER_INFO, serviceInfoModel);
                                            if (resultBlock != null) {
                                                resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", serviceInfoModel);
                                            }
                                        }
                                    }
                                } else {
                                    if (resultBlock != null) {
                                        resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "登录失败", null);
                                    }

                                }
                            } else {
                                if (resultBlock != null) {
                                    resultBlock.resultBolok(SobotResultCode.CODE_FAILED, SobotStringUtils.isNoEmpty(msg) ? msg : "登录失败", "");
                                }
                            }
                        }
                    });
                } else {
                    if (resultBlock != null) {
                        resultBlock.resultBolok(SobotResultCode.CODE_FAILED, (result != null && SobotStringUtils.isNoEmpty(result.getRetMsg())) ? result.getRetMsg() : "登录失败", result.getRetCode());
                    }
                }
            }

            @Override
            public void onError(Exception e, String msg, int responseCode) {
                if (resultBlock != null) {
                    resultBlock.resultBolok(SobotResultCode.CODE_FAILED, msg, responseCode);
                }
            }

            @Override
            public void inProgress(int progress) {

            }
        });
    }

    /**
     * 执行登录操作
     * 1、通过账号密码登录获取token;2、根据token获取客服角色权限等信息；3、如果是呼叫V6或者电销，先获取AccessToken；4、再根据客服app或者客服SDK登录同时又买了在线产品判断是否执行在线操作逻辑
     *
     * @param cancelTag
     * @param mContext
     * @param isAppOrOnlineLogin true 客服app或者客服SDK登录,如果有在线产品，再单独执行在线登录逻辑
     * @param host
     * @param openApiHost
     * @param loginAcount        登录账号
     * @param appkey             客户开通时生成，可以找智齿售后同时获取
     * @param appId              客户开通时生成，可以找智齿售后同时获取
     * @param paramsMap          单独执行在线登录逻辑 参数
     * @param resultBlock
     */
    public void loginWithAppkey(final Object cancelTag, final Context mContext, final boolean isAppOrOnlineLogin, final String host, final String openApiHost, final String loginAcount, String appkey, String appId, final Map<String, Object> paramsMap, final SobotResultBlock resultBlock) {
        if (SobotStringUtils.isEmpty(host)) {
            SobotLogUtils.i("host 域名不能为空");
            if (resultBlock != null) {
                resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "域名不能为空", getServiceInfo());
            }
            return;
        }
        if (isLogin(loginAcount)) {
            SobotLogUtils.i("已经登录成功,不用重新登录");
            if (resultBlock != null) {
                resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "已经登录成功", getServiceInfo());
            }
            return;
        }
        Map<String, Object> tokebMap = new HashMap<>();
        String nowMills = System.currentTimeMillis() + "";
        tokebMap.put("appid", appId);
        tokebMap.put("create_time", nowMills);
        tokebMap.put("sign", SobotMD5Util.encode(appId + nowMills + appkey));
        Map<String, String> headerMap = new HashMap<>();
        headerMap.put("from", "2");
        //获取 公司token
        SobotHttpUtils.doGet(cancelTag, openApiHost.replace("/text", "") + "/api/get_token", 8000, tokebMap, headerMap, new HttpBaseUtils.StringCallBack() {
            @Override
            public void onResponse(String response) {
                TokenModel result = SobotGsonUtil.jsonToBean(response, TokenModel.class);
                if (result != null && !SobotStringUtils.isEmpty(result.getRet_code()) && "000000".equals(result.getRet_code()) && result.getItem() != null && SobotStringUtils.isNoEmpty(result.getItem().getToken())) {
                    String ctoken = result.getItem().getToken();
                    Map<String, String> headerMap = new HashMap<>();
                    headerMap.put("token", ctoken);
                    headerMap.put("from", "2");
                    Map<String, Object> params = new HashMap<>();
                    params.put("agent_email", loginAcount);
                    //获取 个人座席token
                    SobotHttpUtils.doPostByJsonString(cancelTag, openApiHost.replace("/text", "") + "/api/public/sso/5/login", params, headerMap, new HttpBaseUtils.StringCallBack() {
                        @Override
                        public void onResponse(String response) {
                            SobotCallBaseCode result = SobotGsonUtil.jsonToBean(response, SobotCallBaseCode.class);
                            if (result != null && !SobotStringUtils.isEmpty(result.getRetCode()) && "000000".equals(result.getRetCode()) && !SobotStringUtils.isEmpty(result.getItem())) {
                                final long login_time = System.currentTimeMillis();
                                final String token = (String) result.getItem();
                                getuserEntityInfo(cancelTag, mContext, host, token, "", new SobotResultBlock() {
                                    @Override
                                    public void resultBolok(SobotResultCode code, String msg, Object obj) {
                                        if (code == SobotResultCode.CODE_SUCCEEDED) {
                                            SobotServiceInfoModel serviceInfoModel = (SobotServiceInfoModel) obj;
                                            if (serviceInfoModel != null) {
                                                serviceInfoModel.setLogin_time(login_time);
                                                serviceInfoModel.setToken(token);
                                                serviceInfoModel.setLoginAccount(loginAcount);
                                                if ((serviceInfoModel.getCallV6Flag() == 1 || SobotPermissionManager.isHasNewPermission(SobotPermissionManager.SCC))) {
                                                    //如果是v6呼叫
                                                    String tempHost = openApiHost;
                                                    if (tempHost.contains("/text")) {
                                                        tempHost = tempHost.replace("/text", "");
                                                    }
                                                    final SobotServiceInfoModel tempServiceInfoModel = serviceInfoModel;
                                                    doAccessToken(cancelTag, tempHost, serviceInfoModel.getToken(), new SobotResultBlock() {
                                                        @Override
                                                        public void resultBolok(SobotResultCode code, String msg, Object obj) {
                                                            if (code == SobotResultCode.CODE_SUCCEEDED) {
                                                                SobotServiceInfoModel tempUserEntity = tempServiceInfoModel;
                                                                if (obj != null && obj instanceof String && SobotStringUtils.isNoEmpty((String) obj)) {
                                                                    String accessToken = (String) obj;
                                                                    tempUserEntity.setAccess_token(accessToken);
                                                                    //判断是否有对话功能
                                                                    if (SobotPermissionManager.checkPermission(SobotPermissionApi.USER_PERMISSION_TYPE_TALK) && isAppOrOnlineLogin) {
                                                                        getAdminStatus(cancelTag, mContext, host, paramsMap, tempUserEntity, resultBlock);
                                                                    } else {
                                                                        setServiceInfo(tempUserEntity);
                                                                        SobotSharedPreferencesUtil.getInstance(mContext).put(SobotLoginConstant.SOBOT_LOGIN_USER_INFO, tempUserEntity);
                                                                        if (resultBlock != null) {
                                                                            resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", tempUserEntity);
                                                                        }
                                                                    }
                                                                } else {
                                                                    SobotLogUtils.i("accessToken获取失败");
                                                                    if (resultBlock != null) {
                                                                        resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", tempServiceInfoModel);
                                                                    }
                                                                }
                                                            } else {
                                                                SobotLogUtils.i("accessToken获取失败");
                                                                if (resultBlock != null) {
                                                                    resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", tempServiceInfoModel);
                                                                }
                                                            }
                                                        }
                                                    });
                                                } else {
                                                    //判断是否有对话功能
                                                    if (SobotPermissionManager.checkPermission(SobotPermissionApi.USER_PERMISSION_TYPE_TALK) && isAppOrOnlineLogin) {
                                                        getAdminStatus(cancelTag, mContext, host, paramsMap, serviceInfoModel, resultBlock);
                                                    } else {
                                                        setServiceInfo(serviceInfoModel);
                                                        SobotSharedPreferencesUtil.getInstance(mContext).put(SobotLoginConstant.SOBOT_LOGIN_USER_INFO, serviceInfoModel);
                                                        if (resultBlock != null) {
                                                            resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", serviceInfoModel);
                                                        }
                                                    }
                                                }
                                            } else {
                                                if (resultBlock != null) {
                                                    resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "登录失败", null);
                                                }

                                            }
                                        } else {
                                            if (resultBlock != null) {
                                                resultBlock.resultBolok(SobotResultCode.CODE_FAILED, SobotStringUtils.isNoEmpty(msg) ? msg : "登录失败", "");
                                            }
                                        }
                                    }
                                });
                            } else {
                                if (resultBlock != null) {
                                    resultBlock.resultBolok(SobotResultCode.CODE_FAILED, (result != null && SobotStringUtils.isNoEmpty(result.getRetMsg())) ? result.getRetMsg() : "登录失败", "");
                                }
                            }
                        }

                        @Override
                        public void onError(Exception e, String msg, int responseCode) {
                            if (resultBlock != null) {
                                resultBlock.resultBolok(SobotResultCode.CODE_FAILED, msg, null);
                            }
                        }

                        @Override
                        public void inProgress(int progress) {

                        }
                    });
                } else {
                    if (resultBlock != null) {
                        resultBlock.resultBolok(SobotResultCode.CODE_FAILED, (result != null && SobotStringUtils.isNoEmpty(result.getRet_msg())) ? result.getRet_msg() : "登录失败", "");
                    }
                }
            }

            @Override
            public void onError(Exception e, String msg, int responseCode) {
                if (resultBlock != null) {
                    resultBlock.resultBolok(SobotResultCode.CODE_FAILED, msg, null);
                }
            }

            @Override
            public void inProgress(int progress) {

            }
        });
    }

    /**
     * 执行登录操作
     * 1、通过账号密码登录获取token;2、根据token获取客服角色权限等信息；3、如果是呼叫V6或者电销，先获取AccessToken；4、再根据客服app或者客服SDK登录同时又买了在线产品判断是否执行在线操作逻辑
     *
     * @param cancelTag
     * @param mContext
     * @param isAppOrOnlineLogin true 客服app或者客服SDK登录,如果有在线产品，再单独执行在线登录逻辑
     * @param host
     * @param openApiHost
     * @param loginAcount        登录账号
     * @param token              公司token(参考文档：https://developer.zhichi.com/pages/4e87dc/)
     * @param paramsMap          单独执行在线登录逻辑 参数
     * @param resultBlock
     */
    public void loginWithCompanyToken(final Object cancelTag, final Context mContext, final boolean isAppOrOnlineLogin, final String host, final String openApiHost, final String loginAcount, String token, final Map<String, Object> paramsMap, final SobotResultBlock resultBlock) {
        if (SobotStringUtils.isEmpty(host)) {
            SobotLogUtils.i("host域名不能为空");
            if (resultBlock != null) {
                resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "域名不能为空", getServiceInfo());
            }
            return;
        }
        if (isLogin(loginAcount)) {
            SobotLogUtils.i("已经登录成功,不用重新登录");
            if (resultBlock != null) {
                resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "已经登录成功", getServiceInfo());
            }
            return;
        }
        Map<String, String> headerMap = new HashMap<>();
        headerMap.put("token", token);
        headerMap.put("from", "2");
        Map<String, Object> params = new HashMap<>();
        params.put("agent_email", loginAcount);
        //获取 个人座席token
        SobotHttpUtils.doPostByJsonString(cancelTag, openApiHost.replace("/text", "") + "/api/public/sso/5/login", params, headerMap, new HttpBaseUtils.StringCallBack() {
            @Override
            public void onResponse(String response) {
                SobotCallBaseCode result = SobotGsonUtil.jsonToBean(response, SobotCallBaseCode.class);
                if (result != null && !SobotStringUtils.isEmpty(result.getRetCode()) && "000000".equals(result.getRetCode()) && !SobotStringUtils.isEmpty(result.getItem())) {
                    final long login_time = System.currentTimeMillis();
                    final String token = (String) result.getItem();
                    getuserEntityInfo(cancelTag, mContext, host, token, "", new SobotResultBlock() {
                        @Override
                        public void resultBolok(SobotResultCode code, String msg, Object obj) {
                            if (code == SobotResultCode.CODE_SUCCEEDED) {
                                SobotServiceInfoModel serviceInfoModel = (SobotServiceInfoModel) obj;
                                if (serviceInfoModel != null) {
                                    serviceInfoModel.setLogin_time(login_time);
                                    serviceInfoModel.setToken(token);
                                    serviceInfoModel.setLoginAccount(loginAcount);
                                    if ((serviceInfoModel.getCallV6Flag() == 1 || SobotPermissionManager.isHasNewPermission(SobotPermissionManager.SCC))) {
                                        //如果是v6呼叫
                                        String tempHost = openApiHost;
                                        if (tempHost.contains("/text")) {
                                            tempHost = tempHost.replace("/text", "");
                                        }
                                        final SobotServiceInfoModel tempServiceInfoModel = serviceInfoModel;
                                        doAccessToken(cancelTag, tempHost, serviceInfoModel.getToken(), new SobotResultBlock() {
                                            @Override
                                            public void resultBolok(SobotResultCode code, String msg, Object obj) {
                                                if (code == SobotResultCode.CODE_SUCCEEDED) {
                                                    SobotServiceInfoModel tempUserEntity = tempServiceInfoModel;
                                                    if (obj != null && obj instanceof String && SobotStringUtils.isNoEmpty((String) obj)) {
                                                        String accessToken = (String) obj;
                                                        tempUserEntity.setAccess_token(accessToken);
                                                        //判断是否有对话功能
                                                        if (SobotPermissionManager.checkPermission(SobotPermissionApi.USER_PERMISSION_TYPE_TALK) && isAppOrOnlineLogin) {
                                                            getAdminStatus(cancelTag, mContext, host, paramsMap, tempUserEntity, resultBlock);
                                                        } else {
                                                            setServiceInfo(tempUserEntity);
                                                            SobotSharedPreferencesUtil.getInstance(mContext).put(SobotLoginConstant.SOBOT_LOGIN_USER_INFO, tempUserEntity);
                                                            if (resultBlock != null) {
                                                                resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", tempUserEntity);
                                                            }
                                                        }
                                                    } else {
                                                        SobotLogUtils.i("accessToken获取失败");
                                                        if (resultBlock != null) {
                                                            resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", tempServiceInfoModel);
                                                        }
                                                    }
                                                } else {
                                                    SobotLogUtils.i("accessToken获取失败");
                                                    if (resultBlock != null) {
                                                        resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", tempServiceInfoModel);
                                                    }
                                                }
                                            }
                                        });
                                    } else {
                                        //判断是否有对话功能
                                        if (SobotPermissionManager.checkPermission(SobotPermissionApi.USER_PERMISSION_TYPE_TALK) && isAppOrOnlineLogin) {
                                            getAdminStatus(cancelTag, mContext, host, paramsMap, serviceInfoModel, resultBlock);
                                        } else {
                                            setServiceInfo(serviceInfoModel);
                                            SobotSharedPreferencesUtil.getInstance(mContext).put(SobotLoginConstant.SOBOT_LOGIN_USER_INFO, serviceInfoModel);
                                            if (resultBlock != null) {
                                                resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", serviceInfoModel);
                                            }
                                        }
                                    }
                                } else {
                                    if (resultBlock != null) {
                                        resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "登录失败", null);
                                    }

                                }
                            } else {
                                if (resultBlock != null) {
                                    resultBlock.resultBolok(SobotResultCode.CODE_FAILED, SobotStringUtils.isNoEmpty(msg) ? msg : "登录失败", "");
                                }
                            }
                        }
                    });
                } else {
                    if (resultBlock != null) {
                        resultBlock.resultBolok(SobotResultCode.CODE_FAILED, (result != null && SobotStringUtils.isNoEmpty(result.getRetMsg())) ? result.getRetMsg() : "登录失败", "");
                    }
                }
            }

            @Override
            public void onError(Exception e, String msg, int responseCode) {
                if (resultBlock != null) {
                    resultBlock.resultBolok(SobotResultCode.CODE_FAILED, msg, null);
                }
            }

            @Override
            public void inProgress(int progress) {

            }
        });

    }

    // sdk 执行退出登录
    public void logOut(Object cancelTag, String host, String loginAcount, final SobotResultBlock resultBlock) {
        if (SobotStringUtils.isEmpty(loginAcount)) {
            if (resultBlock != null) {
                resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "账号为空，退出失败", null);
            }
            return;
        }
        if (!isLogin(loginAcount)) {
            if (resultBlock != null) {
                resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "上次登录的保存信息为空，不用再次退出登录", null);
            }
            return;
        }
        Map<String, Object> params = new HashMap<>();
        params.put("loginUser", loginAcount);
        Map<String, String> headerParams = new HashMap<>();
        headerParams.put("temp-id", getToken());
        headerParams.put("from", "2");
        SobotHttpUtils.doPost(cancelTag, host + "/basic-login/serviceLogOut/4", 8000, params, headerParams, new HttpBaseUtils.StringCallBack() {
            @Override
            public void onResponse(String response) {
                SobotCallBaseCode result = SobotGsonUtil.jsonToBean(response, SobotCallBaseCode.class);
                if (result != null && !SobotStringUtils.isEmpty(result.getRetCode()) && "000000".equals(result.getRetCode())) {
                    clearLoginInfo();
                    if (resultBlock != null) {
                        resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "退出登录成功", null);
                    }
                } else {
                    if (resultBlock != null) {
                        resultBlock.resultBolok(SobotResultCode.CODE_FAILED, (result != null && SobotStringUtils.isNoEmpty(result.getRetMsg())) ? result.getRetMsg() : "退出登录失败", null);
                    }
                }
            }

            @Override
            public void onError(Exception e, String msg, int responseCode) {
                if (resultBlock != null) {
                    resultBlock.resultBolok(SobotResultCode.CODE_FAILED, msg, null);
                }
            }

            @Override
            public void inProgress(int progress) {

            }
        });
    }


    /**
     * 调用座席接口
     *
     * @param cancelTag
     * @param mContext
     * @param host
     * @param token
     * @param resultBlock
     */
    public void getuserEntityInfo(Object cancelTag, Context mContext,
                                  String host, String token, String language, final SobotResultBlock resultBlock) {
        String url = host + "/basic-config-service/consoleAuth/queryAppAgentMenus";
        Map<String, String> headerMap = new HashMap<>();
        if (!SobotStringUtils.isEmpty(token)) {
            headerMap.put("temp-id", token);
        }
        if (!SobotStringUtils.isEmpty(language)) {
            headerMap.put("language", language);
        }
        headerMap.put("from", "2");
        SobotHttpUtils.doGet(cancelTag, url, null, headerMap, new HttpBaseUtils.StringCallBack() {
            @Override
            public void onResponse(String result) {
                if (!SobotStringUtils.isEmpty(result)) {
                    try {
                        org.json.JSONObject resonseObj = new org.json.JSONObject(result);
                        String retCode = resonseObj.optString("retCode");
                        String retMsg = resonseObj.optString("retMsg");
                        if ("000000".equals(retCode)) {
                            SobotServiceInfoModel serviceInfoModel = SobotGsonUtil.jsonToBean(resonseObj.optString("item"), SobotServiceInfoModel.class);
                            List<ServiceFunctionVoModel> functions = new ArrayList<>();
                            JSONArray items = resonseObj.optJSONArray("items");
                            getListByObj(functions, items);//添加新版权限
                            if (serviceInfoModel != null) {
                                if (serviceInfoModel.getFunctionStr() != null && serviceInfoModel.getFunctionStr().size() > 0) {
                                    for (int i = 0; i < serviceInfoModel.getFunctionStr().size(); i++) {
                                        ServiceFunctionVoModel functionVoModel = serviceInfoModel.getFunctionStr().get(i);
                                        functionVoModel.setCheckedCode(functionVoModel.isChecked() ? 1 : 0);
                                        functions.add(functionVoModel);//添加旧版权限
                                    }
                                }
                                if (serviceInfoModel.getGlobalPermissions() != null) {
                                    //全局权限
                                    for (int i = 0; i < serviceInfoModel.getGlobalPermissions().size(); i++) {
                                        if (!SobotStringUtils.isEmpty(serviceInfoModel.getGlobalPermissions().get(i))) {
                                            ServiceFunctionVoModel functionVoModel = new ServiceFunctionVoModel();
                                            functionVoModel.setCode(serviceInfoModel.getGlobalPermissions().get(i));
                                            functions.add(functionVoModel);
                                        }
                                    }
                                }
                                //权限保存入库
                                FunctionManager.getInstance().setFunctionVos(functions);
                                //先保存一次
                                setServiceInfo(serviceInfoModel);
                                if (resultBlock != null) {
                                    resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "获取成功", serviceInfoModel);
                                }
                            }
                        } else {
                            if (resultBlock != null) {
                                resultBlock.resultBolok(SobotResultCode.CODE_FAILED, retMsg == null ? "" : retMsg, null);
                            }
                        }
                    } catch (Exception e) {
                        if (resultBlock != null) {
                            resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "", null);
                        }
                    }
                }
            }

            @Override
            public void onError(Exception e, String msg, int responseCode) {
                if (resultBlock != null) {
                    resultBlock.resultBolok(SobotResultCode.CODE_FAILED, msg, null);
                }
            }

            @Override
            public void inProgress(int progress) {

            }
        });
    }


    private void getListByObj(List<ServiceFunctionVoModel> list, JSONArray items) {
        try {
            if (null != items) {
                for (int i = 0; i < items.length(); i++) {
                    org.json.JSONObject o = items.getJSONObject(i);
                    ServiceFunctionVoModel functionVoModel = SobotGsonUtil.jsonToBean(o.toString(), ServiceFunctionVoModel.class);
                    if (functionVoModel != null) {
                        list.add(functionVoModel);
                    }
                    boolean hasChildren = o.optBoolean("hasChildren", false);
                    if (hasChildren) {
                        if (null != o.optJSONArray("children")) {
                            JSONArray childrens = o.getJSONArray("children");
                            getListByObj(list, childrens);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取accessToken
     */

    public void doAccessToken(Object cancelTag, String host, String token,
                              final SobotResultBlock resultBlock) {
        Map<String, String> headerMap = new HashMap<>();
        if (!SobotStringUtils.isEmpty(token)) {
            headerMap.put("temp-id", token);
        }
        if (SobotStringUtils.isEmpty(host)) {
            //获取accessToken 默认用腾讯云域名
            host = "https://api-c.soboten.com";
        }
        headerMap.put("from", "2");
        SobotHttpUtils.doPost(cancelTag, host + "/tokens/getToken", null, headerMap, new HttpBaseUtils.StringCallBack() {
            @Override
            public void onResponse(String result) {
                if (!SobotStringUtils.isEmpty(result)) {
                    Map map = SobotGsonUtil.jsonToMaps((String) result);
                    if (map != null && map.containsKey("accessToken")) {
                        String accessToken = (String) map.get("accessToken");
                        if (resultBlock != null) {
                            resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "", accessToken);
                        }
                    } else {
                        if (resultBlock != null) {
                            resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "", null);
                        }
                    }
                } else {
                    if (resultBlock != null) {
                        resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "", null);
                    }
                }
            }

            @Override
            public void onError(Exception e, String msg, int responseCode) {
                if (resultBlock != null) {
                    resultBlock.resultBolok(SobotResultCode.CODE_FAILED, msg, null);
                }
            }

            @Override
            public void inProgress(int progress) {

            }
        });
    }


    /**
     * 如果是智齿客服APP 或者客服SDK 并且有对话模块，获取在线状态
      */
    public void getAdminStatus(Object cancelTag, final Context context, String host, Map<String, Object> params, final SobotServiceInfoModel infoModel, final SobotResultBlock resultBlock) {
        if (infoModel != null) {
            Map<String, String> headerMap = new HashMap<>();
            headerMap.put("token", SobotStringUtils.checkStringIsNull(infoModel.getToken()));
            headerMap.put("language", SobotStringUtils.checkStringIsNull(infoModel.getServiceLanguage()));
            headerMap.put("from", "2");
            SobotHttpUtils.doGet(cancelTag, host + "/chat-sdk/sdk/admin/v1/appEnter", 8000, params, headerMap, new HttpBaseUtils.StringCallBack() {
                @Override
                public void onResponse(String result) {
                    if (!SobotStringUtils.isEmpty(result)) {
                        final SobotBaseCode<OnlineUserEntity> baseModel = SobotGsonUtil.jsonToBeans(result, new com.sobot.gson.reflect.TypeToken<SobotBaseCode<OnlineUserEntity>>() {
                        }.getType());
                        if (baseModel != null) {
                            //登录接口和获取坐席信息权限接口都成功才算真正登录成功
                            if ("1".equals(baseModel.getCode()) && baseModel.getData() != null) {
                                OnlineUserEntity userEntity = baseModel.getData();
                                SobotServiceInfoModel tempServiceInfoModel = infoModel;
                                tempServiceInfoModel.setPu(SobotStringUtils.checkStringIsNull(userEntity.getPu()));
                                tempServiceInfoModel.setPuid(SobotStringUtils.checkStringIsNull(userEntity.getPuid()));
                                tempServiceInfoModel.setTempId(SobotStringUtils.checkStringIsNull(userEntity.getTempId()));
                                tempServiceInfoModel.setWslinkDefault(SobotStringUtils.checkStringIsNull(userEntity.getWslinkDefault()));
                                tempServiceInfoModel.setImFlag(userEntity.getImFlag());
                                tempServiceInfoModel.setKbVersion(SobotStringUtils.checkStringIsNull(userEntity.getKbVersion()));
                                tempServiceInfoModel.setRobotVersion(SobotStringUtils.checkStringIsNull(userEntity.getRobotVersion()));
                                tempServiceInfoModel.setOnlineVersion(SobotStringUtils.checkStringIsNull(userEntity.getOnlineVersion()));
                                if(userEntity.getStatus()==2){
                                    tempServiceInfoModel.setStatus(userEntity.getStatusCode());
                                }else {
                                    tempServiceInfoModel.setStatus(userEntity.getStatus());
                                }
                                tempServiceInfoModel.setFuseWork(userEntity.getFuseWork());
                                tempServiceInfoModel.setWslinkBak(userEntity.getWslinkBak());
                                tempServiceInfoModel.setTopFlag(userEntity.getTopFlag());
                                tempServiceInfoModel.setTransferAuditFlag(userEntity.getTransferAuditFlag());
                                tempServiceInfoModel.setSortFlag(userEntity.getSortFlag());
                                tempServiceInfoModel.setDefaultAppLoginStatus(userEntity.getDefaultAppLoginStatus());
                                tempServiceInfoModel.setReadFlag(userEntity.getReadFlag());
                                setServiceInfo(tempServiceInfoModel);
                                SobotSharedPreferencesUtil.getInstance(context).put(SobotLoginConstant.SOBOT_LOGIN_USER_INFO, tempServiceInfoModel);
                                if (resultBlock != null) {
                                    resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", tempServiceInfoModel);
                                }
                            } else {
                                SobotLogUtils.i("appLogin 接口返回code不等于1:" + result);
                                if (resultBlock != null) {
                                    resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", infoModel);
                                }
                            }
                        } else {
                            SobotLogUtils.i("appLogin 接口请求结果为空");
                            if (resultBlock != null) {
                                resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", infoModel);
                            }
                        }
                    }
                }

                @Override
                public void onError(Exception e, String msg, int responseCode) {
                    SobotLogUtils.i(SobotStringUtils.checkStringIsNull(msg));
                    if (resultBlock != null) {
                        resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", infoModel);
                    }
                }

                @Override
                public void inProgress(int progress) {

                }
            });
        } else {
            if (resultBlock != null) {
                resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", infoModel);
            }
        }
    }

}
