package com.sobot.common.login;

import android.content.Context;
import android.text.TextUtils;

import com.sobot.common.login.callback.SobotResultBlock;
import com.sobot.common.login.callback.SobotResultCode;
import com.sobot.common.login.model.HostModel;
import com.sobot.common.login.model.LoginUserEntity;
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.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.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 SobotLoginTools.SobotLoginToolsHolder.instance;
    }

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


    private LoginUserEntity user;

    public LoginUserEntity getLoginUser() {
        return user;
    }

    public void setLoginUser(LoginUserEntity newUser) {
        if (newUser != null) {
            newUser.setLogin_time(System.currentTimeMillis());
        }
        user = newUser;
    }


    private SobotServiceInfoModel mServiceInfoModel;

    public SobotServiceInfoModel getServiceInfo() {
        return mServiceInfoModel;
    }

    public void setServiceInfo(SobotServiceInfoModel newServiceInfo) {
        mServiceInfoModel = newServiceInfo;
    }


    private HostModel mHostModel;

    //获取域名
    public HostModel getHostInfo() {
        return mHostModel;
    }

    public void setHostInfo(HostModel newHostModel) {
        mHostModel = newHostModel;
    }

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

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

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

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

    public boolean isLogin() {
        if (getLoginUser() != null && !SobotStringUtils.isEmpty(getLoginUser().getToken()) && checkExpiresToken()) {
            return true;
        } else {
            return false;
        }
    }


    // 执行APP登录接口
    public void doAppLogin(final Object cancelTag, final Context mContext, final String host, final String openApiHost, long timeout, Map<String, Object> params, Map<String, String> headers, final SobotResultBlock resultBlock) {
        SobotHttpUtils.doPost(cancelTag, host + "/chat-sdk/sdk/admin/v1/login.action", timeout, params, headers, new HttpBaseUtils.StringCallBack() {
            @Override
            public void onResponse(String result) {
                if (!TextUtils.isEmpty(result)) {
                    final SobotBaseCode<LoginUserEntity> baseModel = SobotGsonUtil.jsonToBeans(result, new com.sobot.gson.reflect.TypeToken<SobotBaseCode<LoginUserEntity>>() {
                    }.getType());
                    if (baseModel != null) {
                        //登录接口和获取坐席信息权限接口都成功才算真正登录成功
                        if ("1".equals(baseModel.getCode()) && baseModel.getData() != null) {
                            final LoginUserEntity userEntity = baseModel.getData();
                            getLoginUserInfo(cancelTag, mContext, host, baseModel.getData().getToken(), baseModel.getData().getLanguage(), new SobotResultBlock() {
                                @Override
                                public void resultBolok(SobotResultCode code, String msg, Object obj) {
                                    if (code == SobotResultCode.CODE_SUCCEEDED) {
                                        SobotServiceInfoModel serviceInfoModel = (SobotServiceInfoModel) obj;
                                        if (serviceInfoModel != null) {
                                            if ((serviceInfoModel.getCallV6Flag() == 1 || SobotPermissionManager.isHasNewPermission(SobotPermissionManager.SCC)) && !SobotStringUtils.isEmpty(openApiHost)) {
                                                if (userEntity != null && !SobotStringUtils.isEmpty(userEntity.getToken())) {
                                                    //如果是v6呼叫
                                                    String tempHost = openApiHost;
                                                    if (tempHost.contains("/text")) {
                                                        tempHost = tempHost.replace("/text", "");
                                                    }
                                                    doAccessToken(cancelTag, tempHost, userEntity.getToken(), new SobotResultBlock() {
                                                        @Override
                                                        public void resultBolok(SobotResultCode code, String msg, Object obj) {
                                                            if (code == SobotResultCode.CODE_SUCCEEDED) {
                                                                LoginUserEntity tempUserEntity = userEntity;
                                                                String accessToken = (String) obj;
                                                                tempUserEntity.setLogin_time(System.currentTimeMillis());
                                                                tempUserEntity.setAccess_token(accessToken);
                                                                tempUserEntity.setLogin_time(System.currentTimeMillis());
                                                                setLoginUser(tempUserEntity);
                                                                resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", tempUserEntity);
                                                            } else {
                                                                resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "登录失败", null);
                                                            }
                                                        }
                                                    });
                                                } else {
                                                    resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "登录失败", null);
                                                }
                                            } else {
                                                setLoginUser(userEntity);
                                                resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", userEntity);
                                            }
                                        } else {
                                            resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "登录失败", null);

                                        }
                                    }
                                }
                            });
                        } else {
                            resultBlock.resultBolok(SobotResultCode.CODE_FAILED, baseModel.getMsg(), baseModel.getCode());
                        }
                    } else {
                        resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "接口请求结果为空", null);
                    }
                }
            }

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

            @Override
            public void inProgress(int progress) {

            }
        });
    }

    // sdk 执行登录接口 会获取accesstoken
    public void doLogin(final Object cancelTag, final Context mContext, final String host, final String openApiHost, String loginAcount, String loginPwd, String logintoken, final SobotResultBlock resultBlock) {
        if (SobotStringUtils.isEmpty(logintoken)) {
            Map<String, Object> params = new HashMap<>();
            params.put("loginUser", loginAcount);
            params.put("loginPwd", loginPwd);
            SobotHttpUtils.doPost(cancelTag, host + "/basic-login/serviceAppLogin/4", 8000, params, null, new HttpBaseUtils.StringCallBack() {
                @Override
                public void onResponse(String response) {
                    SobotCallBaseCode result = SobotGsonUtil.jsonToBean(response, SobotCallBaseCode.class);
                    if (result != null && !TextUtils.isEmpty(result.getRetCode()) && "000000".equals(result.getRetCode()) && !SobotStringUtils.isEmpty(result.getItem())) {
                        final LoginUserEntity userEntity = new LoginUserEntity();
                        userEntity.setLogin_time(System.currentTimeMillis());
                        userEntity.setToken((String) result.getItem());
                        getLoginUserInfo(cancelTag, mContext, host, userEntity.getToken(), userEntity.getLanguage(), new SobotResultBlock() {
                            @Override
                            public void resultBolok(SobotResultCode code, String msg, Object obj) {
                                if (code == SobotResultCode.CODE_SUCCEEDED) {
                                    SobotServiceInfoModel serviceInfoModel = (SobotServiceInfoModel) obj;
                                    if (serviceInfoModel != null) {
                                        if ((serviceInfoModel.getCallV6Flag() == 1 || SobotPermissionManager.isHasNewPermission(SobotPermissionManager.SCC)) && !SobotStringUtils.isEmpty(openApiHost)) {
                                            if (userEntity != null && !SobotStringUtils.isEmpty(userEntity.getToken())) {
                                                //如果是v6呼叫
                                                String tempHost = openApiHost;
                                                if (tempHost.contains("/text")) {
                                                    tempHost = tempHost.replace("/text", "");
                                                }
                                                doAccessToken(cancelTag, tempHost, userEntity.getToken(), new SobotResultBlock() {
                                                    @Override
                                                    public void resultBolok(SobotResultCode code, String msg, Object obj) {
                                                        if (code == SobotResultCode.CODE_SUCCEEDED) {
                                                            LoginUserEntity tempUserEntity = userEntity;
                                                            String accessToken = (String) obj;
                                                            tempUserEntity.setLogin_time(System.currentTimeMillis());
                                                            tempUserEntity.setAccess_token(accessToken);
                                                            tempUserEntity.setLogin_time(System.currentTimeMillis());
                                                            setLoginUser(tempUserEntity);
                                                            resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", tempUserEntity);
                                                        } else {
                                                            resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "登录失败", null);
                                                        }
                                                    }
                                                });
                                            } else {
                                                resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "登录失败", null);
                                            }
                                        } else {
                                            setLoginUser(userEntity);
                                            resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", userEntity);
                                        }
                                    } else {
                                        resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "登录失败", null);

                                    }
                                }
                            }
                        });
                    } else {
                        resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "登录失败", null);
                    }
                }

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

                @Override
                public void inProgress(int progress) {

                }
            });

        } else {
            final LoginUserEntity userEntity = new LoginUserEntity();
            userEntity.setLogin_time(System.currentTimeMillis());
            userEntity.setToken(logintoken);
            getLoginUserInfo(cancelTag, mContext, host, userEntity.getToken(), userEntity.getLanguage(), new SobotResultBlock() {
                @Override
                public void resultBolok(SobotResultCode code, String msg, Object obj) {
                    if (code == SobotResultCode.CODE_SUCCEEDED) {
                        SobotServiceInfoModel serviceInfoModel = (SobotServiceInfoModel) obj;
                        if (serviceInfoModel != null) {
                            if ((serviceInfoModel.getCallV6Flag() == 1 || SobotPermissionManager.isHasNewPermission(SobotPermissionManager.SCC))) {
                                if (userEntity != null && !SobotStringUtils.isEmpty(userEntity.getToken())) {
                                    //如果是v6呼叫
                                    String tempHost = host;
                                    if (tempHost.contains("/text")) {
                                        tempHost = tempHost.replace("/text", "");
                                    }
                                    doAccessToken(cancelTag, tempHost, userEntity.getToken(), new SobotResultBlock() {
                                        @Override
                                        public void resultBolok(SobotResultCode code, String msg, Object obj) {
                                            if (code == SobotResultCode.CODE_SUCCEEDED) {
                                                LoginUserEntity tempUserEntity = userEntity;
                                                String accessToken = (String) obj;
                                                tempUserEntity.setLogin_time(System.currentTimeMillis());
                                                tempUserEntity.setAccess_token(accessToken);
                                                tempUserEntity.setLogin_time(System.currentTimeMillis());
                                                setLoginUser(tempUserEntity);
                                                resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", tempUserEntity);
                                            } else {
                                                resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "登录失败", null);
                                            }
                                        }
                                    });
                                } else {
                                    resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "登录失败", null);
                                }
                            } else {
                                setLoginUser(userEntity);
                                resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "登录成功", userEntity);
                            }
                        } else {
                            resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "登录失败", null);

                        }
                    }
                }
            });
        }
    }


    /**
     * 调用座席接口
     *
     * @param cancelTag
     * @param mContext
     * @param host
     * @param token
     * @param resultBlock
     */
    public void getLoginUserInfo(final Object cancelTag, final Context mContext, final String host, String token, String language, final SobotResultBlock resultBlock) {
        final String url = host + "/basic-config-service/consoleAuth/queryAppAgentMenus";
        Map<String, String> headerMap = new HashMap<>();
        if (!TextUtils.isEmpty(token)) {
            headerMap.put("temp-id", token);
        }
        if (!TextUtils.isEmpty(language)) {
            headerMap.put("language", language);
        }
        SobotHttpUtils.doGet(cancelTag, url, null, headerMap, new HttpBaseUtils.StringCallBack() {
            @Override
            public void onResponse(String result) {
                if (!TextUtils.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.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);
                                        }

                                    }
                                }
                                serviceInfoModel.setFunctionStr(functions);
                                //保存在数据库
                                setServiceInfo(serviceInfoModel);
                                SobotSharedPreferencesUtil.getInstance(mContext).put(SobotLoginConstant.SOBOT_LOGIN_USER_INFO, serviceInfoModel);
                                resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "获取成功", serviceInfoModel);
                            }
                        } else {
                            resultBlock.resultBolok(SobotResultCode.CODE_FAILED, retMsg == null ? "" : retMsg, null);
                        }
                    } catch (Exception e) {
                        resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "", null);
                    }
                }
            }

            @Override
            public void onError(Exception e, String msg, int responseCode) {
                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 (!TextUtils.isEmpty(token)) {
            headerMap.put("temp-id", token);
        }
        SobotHttpUtils.doPost(cancelTag, host + "/tokens/getToken", null, headerMap, new HttpBaseUtils.StringCallBack() {
            @Override
            public void onResponse(String result) {
                if (!TextUtils.isEmpty(result)) {
                    Map map = SobotGsonUtil.jsonToMaps((String) result);
                    if (map != null && map.containsKey("accessToken")) {
                        String accessToken = (String) map.get("accessToken");
                        resultBlock.resultBolok(SobotResultCode.CODE_SUCCEEDED, "", accessToken);
                    } else {
                        resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "", null);
                    }
                } else {
                    resultBlock.resultBolok(SobotResultCode.CODE_FAILED, "", null);
                }
            }

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

            @Override
            public void inProgress(int progress) {

            }
        });
    }

}
