package com.fq.channel.sdk;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;

import com.fq.channel.sdk.base.config.FqConfig;
import com.fq.channel.sdk.base.constants.ConstSet;
import com.fq.channel.sdk.base.interfaces.FQPluginApi;
import com.fq.channel.sdk.base.interfaces.PluginResultHandler;
import com.fq.channel.sdk.base.utils.FqLog;
import com.fq.channel.sdk.base.utils.Utils;
import com.tencent.ysdk.api.YSDKApi;
import com.tencent.ysdk.framework.common.BaseRet;
import com.tencent.ysdk.framework.common.eFlag;
import com.tencent.ysdk.framework.common.ePlatform;
import com.tencent.ysdk.module.bugly.BuglyListener;
import com.tencent.ysdk.module.pay.PayListener;
import com.tencent.ysdk.module.pay.PayRet;
import com.tencent.ysdk.module.share.ShareApi;
import com.tencent.ysdk.module.share.ShareCallBack;
import com.tencent.ysdk.module.share.impl.IScreenImageCapturer;
import com.tencent.ysdk.module.share.impl.ShareRet;
import com.tencent.ysdk.module.user.PersonInfo;
import com.tencent.ysdk.module.user.UserListener;
import com.tencent.ysdk.module.user.UserLoginRet;
import com.tencent.ysdk.module.user.UserRelationRet;
import com.tencent.ysdk.module.user.WakeupRet;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.util.Map;

public class SdkPluginYsdk extends FQPluginApi implements UserListener, BuglyListener {

    private static final String TAG = "SdkPluginYsdk";

    private PluginResultHandler loginHandler, payHandler, logoutHander;
    /**
     * 数据统计
     */
    private int dataType;
    private String roleId, roleName, roleLevel, zoneId, zoneName, serverId, serverName, balance, vipLevel, partyName;

    /**
     * 初始化
     */
    @Override
    public void init(Context activity, final PluginResultHandler handler) {
        FqLog.i(TAG, "init");
        String qqAppId = (String) FqConfig.get().get("qqAppId");
        String wxAppId = (String) FqConfig.get().get("wxAppId");
        FqLog.i(TAG, "qqAppId/wxAppId:" + qqAppId + "/" + wxAppId);
        if (TextUtils.isEmpty(qqAppId) || TextUtils.isEmpty(wxAppId)) {
            FqLog.e(TAG, "QQ_APP_ID 或者 WX_APP_ID 为空！");
            fqSdkError(handler);
        }
        fqSdkSuccess(handler);

    }

    /**
     * 登录
     */
    @Override
    public void login(final Context activity, final PluginResultHandler handler) {
        FqLog.i(TAG, "login ");
        loginHandler = handler;
        final Dialog mDialog = new Dialog(activity, Utils.getIdentifier("LoginDialog", "style"));
        mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        final View view = LayoutInflater.from((Activity) activity).inflate(Utils.getIdentifier("fq_ysdk_login", "layout"), null);
        Button wx = view.findViewById(Utils.getIdentifier("ysdk_wx", "id"));
        Button qq = view.findViewById(Utils.getIdentifier("ysdk_qq", "id"));
        mDialog.setContentView(view);
        mDialog.show();
        mDialog.getWindow().setGravity(Gravity.BOTTOM);
        mDialog.setCancelable(false);

        wx.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FqLog.i(TAG, "weChat login--");
                YSDKApi.login(ePlatform.WX);
                mDialog.dismiss();
            }
        });

        qq.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FqLog.i(TAG, "qq login--");
                YSDKApi.login(ePlatform.QQ);
                mDialog.dismiss();
            }
        });

    }

    @Override
    public void pay(final Context context, final Map<String, Object> map,
                    final PluginResultHandler handler) {
        FqLog.i(TAG, "pay map:" + (map != null ? map.toString() : ""));
        payHandler = handler;
        String orderId = String.valueOf(map.get(ConstSet.PAY_ORDER_ID));
        String extral = String.valueOf(map.get(ConstSet.PAY_EXTRAL_INFO));
        float price = Float.valueOf((String) map.get(ConstSet.PAY_PRICE));
        String productName = String.valueOf(map.get(ConstSet.PAY_PRODUCT_NAME));
        String goodsResData = String.valueOf(map.get(ConstSet.PAY_CHARGE_ID));
        String notifyUrl = String.valueOf(map.get(ConstSet.PAY_NOTIFY_URl));
        int amount = 0;
        try {
            amount = (int) (price * 100); // 支付金额，单位分
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] appResData = baos.toByteArray();

        YSDKApi.recharge("1", String.valueOf(price), false, appResData,  "ysdkExt", new PayListener() {
            @Override
            public void OnPayNotify(PayRet ret) {
                FqLog.i(TAG, ret.toString());
                if (PayRet.RET_SUCC == ret.ret) {
                    // 支付流程成功
                    switch (ret.payState) {
                        // 支付成功
                        case PayRet.PAYSTATE_PAYSUCC:
                            fqSdkSuccess(payHandler);
                            break;
                        // 取消支付
                        case PayRet.PAYSTATE_PAYCANCEL:
                            fqSdkCancel(payHandler);
                            break;
                        // 支付结果未知
                        case PayRet.PAYSTATE_PAYUNKOWN:
                            FqLog.i(TAG, ret.toString());
                            fqSdkError(payHandler);
                            break;
                        // 支付失败
                        case PayRet.PAYSTATE_PAYERROR:
                            fqSdkError(payHandler);
                            break;
                    }
                } else {
                    switch (ret.flag) {
                        case eFlag.Login_TokenInvalid:
                            // 用户取消支付
                            Log.d(TAG, ret.toString());
                            fqSdkError(payHandler);
                            // 并且注销
                            YSDKApi.logout();
                            if (null != logoutHander) {
                                fqSdkSuccess(logoutHander);
                            }
                            break;
                        case eFlag.Pay_User_Cancle:
                            fqSdkCancel(payHandler);
                            break;
                        case eFlag.Pay_Param_Error:
                            fqSdkError(payHandler);
                            break;
                        case eFlag.Error:
                        default:
                            Log.d(TAG, ret.toString());
                            fqSdkError(payHandler);
                            break;
                    }
                }
            }
        });
    }

    /**
     * 退出
     *
     * @param context
     * @param prh
     */
    public void exit(Context context, final PluginResultHandler prh) {
        FqLog.i(TAG, "exit");
        exitFqSdkNoConfirmDialog(prh);
    }

    /**
     * 注销
     */
    public void logout(final Context context, final PluginResultHandler cb) {
        Log.d(TAG, "logout");
        logoutHander = cb;
        YSDKApi.logout();
        fqSdkSuccess(cb);
    }

    @Override
    public void changeAccount(Activity activity, final PluginResultHandler prh) {
        FqLog.i(TAG, " changeAccount ");
    }


    private void showTips(final String message) {
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {

            @Override
            public void run() {
//				Activity activity = IdsLingdoCache.get().getCurrentActivity();
//				if (null != activity){
//					Toast.makeText(activity, message, Toast.LENGTH_SHORT).show();
//				}
            }
        });
    }

    /**
     * 游戏角色信息
     *
     * @param data
     */
    public void setRoleInfo(Bundle data) {
        if (null == data) {
            data = new Bundle();
        }
        Log.i(TAG, "setExtraBundle data:" + data.toString());

        roleName = data.getString("roleName");// 角色名称
        roleLevel = data.getString("roleLevel");//当前登录的玩家角色等级
        roleId = data.getString("roleId");// 角色名称
        serverId = data.getString("serverId"); //当前登录的游戏区服ID
        serverName = data.getString("serverName");//当前登录的游戏区服名称
        balance = data.getString("balance");//当前用户游戏币余额
        vipLevel = data.getString("vipLevel");//当前用户VIP等级
        partyName = data.getString("partyName");//当前用户所属帮派
        zoneId = data.getString("zoneId");//角色所在区域唯一标示
        zoneName = data.getString("zoneName");//角色所在区域名称
        dataType = data.getInt("dataType");//统计判断类型

        StringBuffer reportData = new StringBuffer();
        reportData.append("[");
        reportData.append(" roleName:" + roleName);
        reportData.append(" roleLevel:" + roleLevel);
        reportData.append(" roleId:" + roleId);
        reportData.append(" serverId:" + serverId);
        reportData.append(" serverName:" + serverName);
        reportData.append(" balance:" + balance);
        reportData.append(" vipLevel:" + vipLevel);
        reportData.append(" partyName:" + zoneId);
        reportData.append(" zoneName:" + zoneName);
        reportData.append(" dataType:" + dataType);
        reportData.append("]");

        switch (dataType) {
            case 0://创建角色
                showTips("数据上报：创建角色 ");
                Log.i(TAG, "reportData" + reportData);
                break;

            case 1://角色升级
                showTips("数据上报：角色升级");
                Log.i(TAG, "reportData" + reportData);
                break;

            case 2:// 上传区服信息
                showTips("数据上报：上传区服信息");
                Log.i(TAG, "reportData" + reportData);
                break;

            case 3://登录
                showTips("数据上报：登录");
                Log.i(TAG, "reportData" + reportData);
                break;

            case 4://支付
                showTips("数据上报：进入游戏");
                Log.i(TAG, "reportData" + reportData);
                break;

            case 5:// 选择服务器
                showTips("数据上报：支付");
                Log.i(TAG, "reportData" + reportData);
                break;

            case 6://退出游戏
                showTips("数据上报：退出游戏");
                Log.i(TAG, "reportData" + reportData);
                break;

            case 7:// 备注（预留参数）
                showTips("数据上报：退出游戏");
                FqLog.i(TAG, "reportData" + reportData);
                break;
            default:
                break;
        }

        String roleId = data.getString("roleId");// 角色id
        String roleName = data.getString("roleName");
        String roleLevel = data.getString("roleLevel");// 角色等级
        String zoneId = data.getString("zoneId");
        String zoneName = data.getString("zoneName");
        String serverId = data.getString("serverId");
        String serverName = data.getString("serverName");
        int dataType = data.getInt("dataType");
        switch (dataType) {
            //这个在登入的时候调用
            case 3:
                FqLog.i(TAG, "setExtraBundle: roleId:" + roleId + ",roleName:" + roleName + ",roleLevel:" + roleLevel + ",serverId:" + serverId + ",serverName:" + serverName + ",chapter:Idreamsky");
                break;

            default:
                break;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

    }

    @Override
    public int getPayId() {
        return 4;
    }

    /**
     * 释放资源时调用，当用户退出界面或者游戏的时候，
     * 调用此接口，释放资源才允许退出！
     *
     * @param context
     */
    public void releaseSdkResource(Context context) {
        FqLog.i(TAG, "releaseSdkResource");

        Toast.makeText(context, "释放SDK资源", Toast.LENGTH_SHORT).show();

        try {
            /**渠道存在退出界面,此处游戏必须调用,begin*/
            Intent startMain = new Intent(Intent.ACTION_MAIN);
            startMain.addCategory(Intent.CATEGORY_HOME);
            startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(startMain);
            /**渠道存在退出界面,此处游戏必须调用,end*/
        } catch (Exception e) {
            FqLog.e(TAG, "releaseSdkResource 抛出异常！");
        }
    }

    /**
     * 复写生命周期方法,里面调用
     */
    public void onStart(Activity context) {
        FqLog.i(TAG, "onStart");
    }

    public void onCreate(final Activity activity, Bundle handler) {
        FqLog.i(TAG, "onCreate");
        YSDKApi.onCreate(activity);
        // 设置java层或c++层回调,如果两层都设置了则会只回调到java层
        // 全局回调类，游戏自行实现
        YSDKApi.setUserListener(this);
        YSDKApi.setBuglyListener(this);
        YSDKApi.handleIntent(activity.getIntent());

        //游戏助手内截屏分享功能
        YSDKApi.setScreenCapturer(new IScreenImageCapturer() {
            @Override
            public Bitmap caputureImage() {
                // TODO GAME 游戏需要集成此方法并根据各自游戏引擎实现截图方法
                // ----以下部分代码仅作为一种示例不作为实际实现方式----
                View view = activity.getWindow().getDecorView();
                view.setDrawingCacheEnabled(true);
                view.buildDrawingCache();
                Rect rect = new Rect();
                view.getWindowVisibleDisplayFrame(rect);
                int statusBarHeight = rect.top;
                WindowManager windowManager = activity.getWindowManager();
                DisplayMetrics outMetrics = new DisplayMetrics();
                windowManager.getDefaultDisplay().getMetrics(outMetrics);
                int width = outMetrics.widthPixels;
                int height = outMetrics.heightPixels;
                Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache(), 0, statusBarHeight, width,
                        height - statusBarHeight);
                view.destroyDrawingCache();
                view.setDrawingCacheEnabled(false);
                // ----以上部分代码仅作为示例不作为实际实现----
                return bitmap;
            }
        });
        //注册分享监听器接受分享状态信息
        ShareApi.getInstance().regShareCallBack(new ShareCallBack() {
            @Override
            public void onSuccess(ShareRet ret) {
                FqLog.i("Share", "分享成功！  分享路径：" + ret.shareType.name() + " 透传信息：" + ret.extInfo);
            }

            @Override
            public void onError(ShareRet ret) {
                FqLog.i("Share", "分享失败  分享路径：" + ret.shareType.name() + " 错误码：" + ret.retCode + " 错误信息：" + ret.retMsg + " 透传信息：" + ret.extInfo);
            }

            @Override
            public void onCancel(ShareRet ret) {
                FqLog.i("Share", "分享用户取消！  分享路径：" + ret.shareType.name() + " 透传信息：" + ret.extInfo);
            }
        });
    }

    public void onRestart(Activity context) {
        Log.i(TAG, "onRestart");
        YSDKApi.onRestart((Activity) context);
    }

    public void onResume(Activity context) {
        Log.i(TAG, "onResume");
        YSDKApi.onResume((Activity) context);
    }

    public void onPause(Activity context) {
        Log.i(TAG, "onPause");
        YSDKApi.onPause((Activity) context);
    }

    public void onStop(Activity context) {
        Log.i(TAG, "onStop");
        YSDKApi.onStop((Activity) context);
    }

    public void onDestroy(Activity context) {
        Log.i(TAG, "onDestroy");
        YSDKApi.onDestroy((Activity) context);
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        FqLog.i(TAG, "onActivityResult requestCode:" + requestCode + " resultCode:" + resultCode + " data:" + data);
        YSDKApi.onActivityResult(requestCode, resultCode, data);
    }

    public void onNewIntent(Intent intent) {
        FqLog.i(TAG, "onNewIntent");
        YSDKApi.handleIntent(intent);
    }

    @Override
    public void attachBaseContext(Context context) {

    }

    @Override
    public void onApplicationCreate(Context context) {

    }

    public void onSaveInstanceState(Activity context, Bundle outState) {
    }

    @Override
    public String OnCrashExtMessageNotify() {
        return null;
    }

    @Override
    public byte[] OnCrashExtDataNotify() {
        return new byte[0];
    }

    /**
     * 登录回调
     */
    /* YSDK会在三种情况下（每次游戏启动、后台运行一分钟以上切换回前台、在前台持续运行30分钟以上）触发自动验证票据有效性的逻辑，
     * 并将验证结果通过loginNotify回调给游戏（回调内容与游戏主动调用login接口一致）。
     * 如果SDK已经为登录状态则在YSDK回调 loginNotify 时无需重新登录。
     */
    @Override
    public void OnLoginNotify(UserLoginRet ret) {
        FqLog.i(TAG, "OnLoginNotify called ret:" + ret.getAccessToken() + " the ret:" + ret.toString());
        switch (ret.flag) {
            case eFlag.Succ:
                YSDKApi.getLoginRecord(ret);

                if (ret.ret != BaseRet.RET_SUCC) {
                    Log.d(TAG, "UserLogin error!!!");
                    fqSdkError(loginHandler, "UserLogin error!!!");
                    YSDKApi.logout();
                    return;
                }
                ePlatform mPlatform = ePlatform.QQ;

                if (ret.platform == ePlatform.PLATFORM_ID_QQ) {
                    mPlatform = ePlatform.QQ;
                    YSDKApi.queryUserInfo(mPlatform);
                } else if (ret.platform == ePlatform.PLATFORM_ID_WX) {
                    mPlatform = ePlatform.WX;
                    YSDKApi.queryUserInfo(mPlatform);
                }

                break;
            // 游戏逻辑，对登录失败情况分别进行处理
//            case eFlag.QQ_UserCancel:
//                showToastTips("用户取消授权，请重试");
//                isLogin = false;
//                loginLedouSdkError(loginHandler, "用户取消授权，请重试");
//                break;
//            case eFlag.QQ_LoginFail:
//                showToastTips("QQ登录失败，请重试");
//                isLogin = false;
//                loginLedouSdkError(loginHandler, "QQ登录失败，请重试");
//                break;
//            case eFlag.QQ_NetworkErr:
//                showToastTips("QQ登录异常，请重试");
//                isLogin = false;
//                loginLedouSdkError(loginHandler, "QQ登录异常，请重试");
//                break;
//            case eFlag.QQ_NotInstall:
//                showToastTips("手机未安装手Q，请安装后重试");
//                isLogin = false;
//                loginLedouSdkError(loginHandler, "手机未安装手Q，请安装后重试");
//                break;
//            case eFlag.QQ_NotSupportApi:
//                showToastTips("手机手Q版本太低，请升级后重试");
//                isLogin = false;
//                loginLedouSdkError(loginHandler, "手机手Q版本太低，请升级后重试");
//                break;
//            case eFlag.WX_NotInstall:
//                showToastTips("手机未安装微信，请安装后重试");
//                isLogin = false;
//                loginLedouSdkError(loginHandler, "手机未安装微信，请安装后重试");
//                break;
//            case eFlag.WX_NotSupportApi:
//                showToastTips("手机微信版本太低，请升级后重试");
//                isLogin = false;
//                loginLedouSdkError(loginHandler, "手机微信版本太低，请升级后重试");
//                break;
//            case eFlag.WX_UserCancel:
//                showToastTips("用户取消授权，请重试");
//                isLogin = false;
//                loginLedouSdkError(loginHandler, "用户取消授权，请重试");
//                break;
//            case eFlag.WX_UserDeny:
//                showToastTips("用户拒绝了授权，请重试");
//                isLogin = false;
//                loginLedouSdkError(loginHandler, "用户拒绝了授权，请重试");
//                break;
//            case eFlag.WX_LoginFail:
//                showToastTips("微信登录失败，请重试");
//                isLogin = false;
//                loginLedouSdkError(loginHandler, "微信登录失败，请重试");
//                break;
//            case eFlag.Login_TokenInvalid:
//                loginLedouSdkError(loginHandler, "您尚未登录或者之前的登录已过期，请重试");
//                break;
//            case eFlag.Login_NotRegisterRealName:
//                // 显示登录界面
//                showToastTips("您的账号没有进行实名认证，请实名认证后重试");
//                loginLedouSdkError(loginHandler, "您的账号没有进行实名认证，请实名认证后重试");
//                break;

        }
    }

    @Override
    public void OnWakeupNotify(WakeupRet ret) {
        FqLog.i(TAG, "called");
        FqLog.i(TAG, ret.toString() + ":flag:" + ret.flag);
        FqLog.i(TAG, ret.toString() + "msg:" + ret.msg);
        FqLog.i(TAG, ret.toString() + "platform:" + ret.platform);
        // MainActivity.platform = ret.platform;
        // TODO GAME 游戏需要在这里增加处理异账号的逻辑
        if (eFlag.Wakeup_YSDKLogining == ret.flag) {
            // 用拉起的账号登录，登录结果在OnLoginNotify()中回调
        } else if (ret.flag == eFlag.Wakeup_NeedUserSelectAccount) {
            // 异账号时，游戏需要弹出提示框让用户选择需要登录的账号
            FqLog.i(TAG, "diff account");
            YSDKApi.logout();
        } else if (ret.flag == eFlag.Wakeup_NeedUserLogin) {
            // 没有有效的票据，登出游戏让用户重新登录
            FqLog.i(TAG, "need login");
            YSDKApi.logout();
        } else {
            FqLog.i(TAG, "logout");
            YSDKApi.logout();
        }
    }

    @Override
    public void OnRelationNotify(UserRelationRet relationRet) {
        String result = "";
        result = result + "flag:" + relationRet.flag + "\n";
        result = result + "msg:" + relationRet.msg + "\n";
        result = result + "platform:" + relationRet.platform + "\n";
        Log.d(TAG, "OnRelationNotify:" + result);
        PersonInfo personInfo = null;
        JSONObject userProperty = new JSONObject();
        if (relationRet.persons != null && relationRet.persons.size() > 0) {
            personInfo = (PersonInfo) relationRet.persons.firstElement();
            try {
                userProperty.put("nick_name", personInfo.nickName);
                userProperty.put("open_id", personInfo.openId);
                userProperty.put("userId", personInfo.userId);
                userProperty.put("gender", personInfo.gender);
                userProperty.put("picture_small", personInfo.pictureSmall);
                userProperty.put("picture_middle", personInfo.pictureMiddle);
                userProperty.put("picture_large", personInfo.pictureLarge);
                userProperty.put("provice", personInfo.province);
                userProperty.put("city", personInfo.city);
                userProperty.put("country", personInfo.country);

            } catch (JSONException e) {
                FqLog.e(TAG, "JSONException:" + e);
                e.printStackTrace();
            }
        } else {
            result = result + "relationRet.persons is bad";
        }
        FqLog.e(TAG,"OnRelationNotify" + result);
        // 发送结果到结果展示界面

    }
}
