package cn.yyxx.commsdk.impl.merge.channel.huawei;

import android.app.Activity;
import android.app.Application;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;


import com.huawei.agconnect.config.AGConnectServicesConfig;
import com.huawei.agconnect.config.LazyInputStream;
import com.huawei.hmf.tasks.OnFailureListener;
import com.huawei.hmf.tasks.OnSuccessListener;
import com.huawei.hmf.tasks.Task;
import com.huawei.hms.common.ApiException;
import com.huawei.hms.iap.Iap;
import com.huawei.hms.iap.IapApiException;
import com.huawei.hms.iap.entity.ConsumeOwnedPurchaseReq;
import com.huawei.hms.iap.entity.ConsumeOwnedPurchaseResult;
import com.huawei.hms.iap.entity.InAppPurchaseData;
import com.huawei.hms.iap.entity.IsEnvReadyResult;
import com.huawei.hms.iap.entity.OrderStatusCode;
import com.huawei.hms.iap.entity.OwnedPurchasesReq;
import com.huawei.hms.iap.entity.OwnedPurchasesResult;
import com.huawei.hms.iap.entity.ProductInfoReq;
import com.huawei.hms.iap.entity.ProductInfoResult;
import com.huawei.hms.iap.entity.PurchaseIntentReq;
import com.huawei.hms.iap.entity.PurchaseIntentResult;
import com.huawei.hms.jos.AntiAddictionCallback;
import com.huawei.hms.jos.AppParams;
import com.huawei.hms.jos.AppUpdateClient;
import com.huawei.hms.jos.JosApps;
import com.huawei.hms.jos.JosAppsClient;
import com.huawei.hms.jos.games.AppPlayerInfo;
import com.huawei.hms.jos.games.Games;
import com.huawei.hms.jos.games.PlayersClient;
import com.huawei.hms.jos.games.player.Player;
import com.huawei.hms.support.account.AccountAuthManager;
import com.huawei.hms.support.account.request.AccountAuthParams;
import com.huawei.hms.support.account.request.AccountAuthParamsHelper;
import com.huawei.hms.support.account.service.AccountAuthService;
import com.huawei.hms.support.api.client.Status;
import com.huawei.hms.support.hwid.HuaweiIdAuthManager;
import com.huawei.hms.support.hwid.result.AuthHuaweiId;
import com.huawei.updatesdk.service.appmgr.bean.ApkUpgradeInfo;
import com.huawei.updatesdk.service.otaupdate.CheckUpdateCallBack;

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


import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import cn.yyxx.commsdk.base.constants.Constants;
import cn.yyxx.commsdk.base.entity.ResultInfo;
import cn.yyxx.commsdk.base.entity.SdkOrderInfo;
import cn.yyxx.commsdk.base.entity.SdkRoleInfo;
import cn.yyxx.commsdk.base.entity.bean.InitBean;
import cn.yyxx.commsdk.base.internal.ICallback;
import cn.yyxx.commsdk.base.internal.IMsaDeviceCallback;
import cn.yyxx.commsdk.base.internal.feature.IApplication;
import cn.yyxx.commsdk.base.internal.feature.IFeature;
import cn.yyxx.commsdk.base.internal.feature.ILifeCycle;
import cn.yyxx.commsdk.base.internal.feature.IOrder;
import cn.yyxx.commsdk.base.utils.Logger;
import cn.yyxx.commsdk.impl.merge.LoginViewModel;
import cn.yyxx.commsdk.impl.merge.channel.msa.MsaDeviceHandler;
import cn.yyxx.commsdk.impl.merge.channel.utils.ParamsUtils;



public class ChannelBridgeImpl implements IFeature, ILifeCycle, IApplication, IOrder {



    LoginViewModel loginViewModel;

    private String trackId;

    public final static  String  TAG = "HuaWeiSDK";

    public final static  String  AD_TAG = "huawei_pkg_data";

    private boolean hasInit = false;


    String notifyUrl = "";


    private static final int INDEX_REFERRER = 0;

    private static final int INDEX_ENTER_AG_TIME = 1;
    private static final int INDEX_START_DOWNLOAD_TIME = 2;
    private static final int INDEX_TRACKID = 4;
    private static final String PROVIDER_URI = "content://com.huawei.appmarket.commondata/item/5";




    private AccountAuthParams mAuthParam;
    private AccountAuthService mAuthManager;

    private String playerId;



    //login
    public static final int REQUEST_SIGN_IN_LOGIN = 1002;

    //login
    public static final int REQUEST_IAP = 6666;

    private Activity activity;

    public ChannelBridgeImpl(Context context){

    }

    @Override
    public void attachBaseContext(Application application, Context context) {
        /**
        AGConnectOptionsBuilder agConnectOptionsBuilder = new AGConnectOptionsBuilder();
        try {
            agConnectOptionsBuilder.setRoutePolicy(AGCRoutePolicy.CHINA)
                    .setInputStream(context.getAssets().open("agconnect-services.json"));

            AGConnectInstance.initialize(application, agConnectOptionsBuilder);

        } catch (IOException e) {
            e.printStackTrace();
        }

        // 初始化AGC框架
**/

        AGConnectServicesConfig config = AGConnectServicesConfig.fromContext(context);
        config.overlayWith(new LazyInputStream(context) {
            public InputStream get(Context context) {
                try {
                    return context.getAssets().open("agconnect-services.json");
                } catch (IOException e) {
                    return null;
                }
            }
        });

    }

    @Override
    public void initApplication(Application application) {





    }

    @Override
    public void initialize(Activity activity, ICallback callback) {
        init(activity);
        checkUpdate(activity);
        trackId = getTrackId(activity);

        if (judgeStrNull(trackId)){
            Logger.i(TAG,"is null");
        }else{
            Logger.i(TAG,trackId);
        }

        hasInit = true;
    }

    public void init(Activity ac) {

        JosAppsClient appsClient = JosApps.getJosAppsClient(ac);
        AppParams appParams = new AppParams();
        appParams.setAuthScope(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM_GAME);
        appParams.setAntiAddictionCallback(new AntiAddictionCallback() {
            @Override
            public void onExit() {
                System.exit(0);
            }
        });
        appsClient.init(appParams);
        activity = ac;

    }
    public void checkUpdate(final Activity ac) {
        AppUpdateClient client = JosApps.getAppUpdateClient(ac);
        client.checkAppUpdate(ac, new CheckUpdateCallBack() {
            @Override
            public void onUpdateInfo(Intent intent) {

                if (intent != null) {
                    Serializable info = intent.getSerializableExtra("updatesdk_update_info");
                    if (info instanceof ApkUpgradeInfo) {

                        ApkUpgradeInfo apkUpgradeInfo = (ApkUpgradeInfo) info;

                    }
                }
            }

            @Override
            public void onMarketInstallInfo(Intent intent) {

            }

            @Override
            public void onMarketStoreError(int i) {

            }

            @Override
            public void onUpdateStoreError(int i) {

            }
        });
    }

    /**
     * 获取 trackid

     * @return json 格式字符串
     */
    private String getTrackId(Activity activity) {
        String pkgName = getPackageName(activity);
        String trackId = null;
        Cursor cursor = null;
        Uri uri = Uri.parse(PROVIDER_URI);
        ContentResolver contentResolver = activity.getContentResolver();
        String packageName[] = new String[] { pkgName };
        try {
            cursor = contentResolver.query(uri, null, null, packageName, null);

            if (cursor != null) {
                cursor.moveToFirst();
                Logger.i(TAG, "packageName=" + pkgName);
                if (cursor.getColumnCount() > INDEX_TRACKID) {
                    // 10.5.0.300 及之后版本
                    Logger.i(TAG, "version is Version greater than 10.5.0.300");
                    Logger.i(TAG, "referrer=" + cursor.getString(INDEX_REFERRER));
                    Logger.i(TAG, "enter appgallery time=" +
                            cursor.getString(INDEX_ENTER_AG_TIME));
                    Logger.i(TAG, "donwload time=" +
                            cursor.getString(INDEX_START_DOWNLOAD_TIME));
                    Logger.i(TAG, "track id=" + cursor.getString(INDEX_TRACKID));
                    trackId = cursor.getString(INDEX_TRACKID);
                } else if (cursor.getColumnCount() > INDEX_START_DOWNLOAD_TIME){
                    // 兼容旧版本
                    Logger.i(TAG, "version is Version less than 10.5.0.300");
                    trackId = cursor.getString(INDEX_REFERRER);
                    Logger.i(TAG, "referrer=" + cursor.getString(INDEX_REFERRER));
                    Logger.i(TAG, "enter appgallery time=" +
                            cursor.getString(INDEX_ENTER_AG_TIME));
                    Logger.i(TAG, "donwload time=" +
                            cursor.getString(INDEX_START_DOWNLOAD_TIME));
                    return trackId;
                } else {
                    // 不支持归因信息
                    Logger.e(TAG, "appgallery not support");
                }
            }
        }finally {
            if (cursor != null) {
                cursor.close();
            }

        }
        // 如果 trackid 是 json 格式，打印具体内容
        if (!TextUtils.isEmpty(trackId)) {
            try {
                JSONObject attributionMap = new JSONObject(trackId);

                Logger.i(TAG, "json channel id=" + attributionMap.getString("channel"));
                Logger.i(TAG, "json callback=" + attributionMap.get("callback"));
                Logger.i(TAG, "json taskid=" + attributionMap.get("taskid"));

            } catch (JSONException e) {
                e.printStackTrace();
            }
            Logger.i(TAG, "trackId is json  :" + trackId);
        }

        return trackId;
    }

    @Override
    public void initializeSuccess(Activity activity, int loginStatus) {

    }

    @Override
    public void setLogoutListener(Activity activity, ICallback callback) {

    }

    @Override
    public void login(final Activity activity, InitBean initBean, ICallback callback) {

        loginViewModel  = new LoginViewModel(callback);

        signIn(activity);

    }

    private void signIn(Activity activity) {
        mAuthParam = new AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
                .setIdToken()
                .setAccessToken()
                .createParams();
        mAuthManager = AccountAuthManager.getService(activity, mAuthParam);
        activity.startActivityForResult(mAuthManager.getSignInIntent(),REQUEST_SIGN_IN_LOGIN);


    }



    @Override
    public void logout() {
        signOut();
    }
    /**
     * Codelab Code
     * sign Out by signOut
     */
    private void signOut() {
        Task<Void> signOutTask = mAuthManager.signOut();
        signOutTask.addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                Logger.i(TAG, "signOut Success");
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                Logger.i(TAG, "signOut fail");
            }
        });
    }

    @Override
    public boolean hasExitView(Activity activity) {
        return false;
    }

    @Override
    public void openExitView(Activity activity, ICallback iCallback) {
        iCallback.onResult(ResultInfo.CODE_SUCCESS,"EXIT GAME.");
    }

    @Override
    public void uploadRoleInfo(Activity activity, String type, SdkRoleInfo roleInfo) {


        if (type == Constants.UPLOAD_TYPE_ENTER_GAME){
            savePlayerInfo(activity,roleInfo.getServerName(),roleInfo.getRoleLevel(),roleInfo.getRoleName(),roleInfo.getPartyName());
        }
    }

    public void savePlayerInfo(Activity ac, String serverName,String roleLevel,String roleName,String partyName) {
        if (TextUtils.isEmpty(playerId)) {

            return;
        }
        PlayersClient client = Games.getPlayersClient(ac);
        AppPlayerInfo appPlayerInfo = new AppPlayerInfo();
        appPlayerInfo.area = serverName;
        appPlayerInfo.rank = roleLevel;
        appPlayerInfo.role = roleName;
        appPlayerInfo.sociaty = partyName;
        appPlayerInfo.playerId = playerId;
        Task<Void> task = client.savePlayerInfo(appPlayerInfo);
        task.addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void v) {

            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                if (e instanceof ApiException) {
                    String result = "rtnCode:" + ((ApiException) e).getStatusCode();

                }
            }
        });
    }

    @Override
    public void reportGameEvent(String event, JSONObject message) {

    }

    @Override
    public void initMsaDeviceIds(Context context, IMsaDeviceCallback iMsaDeviceCallback) {
        MsaDeviceHandler.initMsaDeviceIds(context,iMsaDeviceCallback);
    }

    @Override
    public String getChannelOcfg(Activity activity) {

        String huawei_pkg_data = RealAssertUtils.getSharedPreferences(activity,AD_TAG,AD_TAG);

        Logger.i(AD_TAG + " : ", huawei_pkg_data);

        if (judgeStrNull(huawei_pkg_data)){

            Logger.i(AD_TAG + " : ","is null, frist open the game.");

            String gcp_code = ParamsUtils.getCfgParam(activity,"YYXX_GCP_CODE");
            if (judgeStrNull(gcp_code)){
                return null;
            }else{

                String sp_code  = RealAssertUtils.GetApplicationMetaData(activity,"YYXX_COMM_SP_CODE");
                JSONObject json = new JSONObject();
                try {
                    json.put("gcp_code",gcp_code);
                    if (!judgeStrNull(sp_code)){
                        json.put("sp_code",sp_code);
                    }

                } catch (JSONException e) {
                    e.printStackTrace();
                }
                RealAssertUtils.saveSharedPreferences(activity,AD_TAG,AD_TAG,json.toString());
                return json.toString();
            }
        }else{
            return huawei_pkg_data;
        }


    }


    @Override
    public void onStart(Activity activity) {

    }

    @Override
    public void onResume(Activity activity) {
        showFloatWindowNewWay(activity);
    }

    @Override
    public void onRestart(Activity activity) {

    }

    @Override
    public void onPause(Activity activity) {
        hideFloatWindowNewWay(activity);
    }

    @Override
    public void onStop(Activity activity) {

    }

    @Override
    public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_SIGN_IN_LOGIN) {
            //login success
            //get user message by parseAuthResultFromIntent
            Task<AuthHuaweiId> authHuaweiIdTask = HuaweiIdAuthManager.parseAuthResultFromIntent(data);
            if (authHuaweiIdTask.isSuccessful()) {
                currentPlayerInfo(activity);

            } else {
                Logger.i(TAG, "signIn failed: " + ((ApiException) authHuaweiIdTask.getException()).getStatusCode());
            }
        }
    }


    private void currentPlayerInfo(final Activity ac) {

        PlayersClient client = Games.getPlayersClient(ac);
        Task<Player> task = client.getCurrentPlayer();
        task.addOnSuccessListener(new OnSuccessListener<Player>() {
            @Override
            public void onSuccess(Player player) {
                String ts = player.getSignTs();
                playerId = player.getPlayerId();
                String playerLevel = player.getLevel() + "";
                String playerSSign = player.getPlayerSign();


                JSONObject json = new JSONObject();
                try {
                    json.put("ts",ts);
                    json.put("playerId",playerId);
                    json.put("playerLevel",playerLevel);
                    json.put("playerSSign",playerSSign);


                    if (!judgeStrNull(trackId)){
                        json.put("ntrackId",trackId);
                    }

                } catch (JSONException e) {
                    e.printStackTrace();
                }


                if (playerId != null && playerLevel != null &&playerLevel != null && playerSSign != null){
                    loginViewModel.verifyChannelInfo(ac,json.toString());
                }




            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                // 获取玩家信息失败
                if (e instanceof ApiException) {
                    if (((ApiException) e).getStatusCode() == 7018){
                        init(ac);
                    }

                }
            }
        });
    }


    @Override
    public void onNewIntent(Activity activity, Intent intent) {

    }

    @Override
    public void onConfigurationChanged(Activity activity, Configuration newconfig) {

    }

    @Override
    public void onWindowFocusChanged(Activity activity, boolean hasFocus) {

    }

    @Override
    public void onDestroy(Activity activity) {

    }

    @Override
    public void onCreate(Activity activity, Bundle savedInstanceState) {

    }

    @Override
    public void startPay(Activity activity, SdkOrderInfo sdkOrderInfo, final ICallback callback) {



        String order_id = sdkOrderInfo.getOrder_id();


        String trdext = sdkOrderInfo.getOrder_ext();
        String productId = "";




        try {
            JSONObject json = new JSONObject(trdext);
            notifyUrl = json.getString("notifyUrl");
            productId = json.getString("productId");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        final PurchaseIntentReq request = new PurchaseIntentReq();

        request.setDeveloperPayload(order_id);
        request.setPriceType(0);
        request.setProductId(productId);



        Task<IsEnvReadyResult> task = Iap.getIapClient(activity).isEnvReady();
        task.addOnSuccessListener(new OnSuccessListener<IsEnvReadyResult>() {
            @Override
            public void onSuccess(IsEnvReadyResult result) {
                // 获取接口请求的结果

                obtainOwnedPurchases(activity,request);

            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                if (e instanceof IapApiException) {
                    IapApiException apiException = (IapApiException) e;
                    // Status不支持序列化操作
                    Status status = apiException.getStatus();
                    String error =  status.getErrorString();
                    if (status.getStatusCode() == OrderStatusCode.ORDER_HWID_NOT_LOGIN) {
                        // 未登录帐号
                        if (status.hasResolution()) {
                            try {
                                // 6666是您自定义的常量
                                // 启动IAP返回的登录页面
                                status.startResolutionForResult(activity, REQUEST_IAP);

                            } catch (IntentSender.SendIntentException exp) {
                            }
                        }
                    } else if (status.getStatusCode() == OrderStatusCode.ORDER_ACCOUNT_AREA_NOT_SUPPORTED) {

                    }
                } else {
                    // 其他外部错误

                }
            }
        });

        }


    void obtainOwnedPurchases(Activity activity, final PurchaseIntentReq purchaseIntentReq){

        OwnedPurchasesReq req = new OwnedPurchasesReq();
        req.setPriceType(0);
        Task<OwnedPurchasesResult> task = Iap.getIapClient(activity).obtainOwnedPurchases(req);
        task.addOnSuccessListener(new OnSuccessListener<OwnedPurchasesResult>() {
            @Override
            public void onSuccess(OwnedPurchasesResult result) {
                // Obtain the execution result.
                if (!result.getInAppPurchaseDataList().isEmpty()) {

                    for (int i = 0; i < result.getInAppPurchaseDataList().size(); i++) {
                        String inAppPurchaseData = result.getInAppPurchaseDataList().get(i);
                        String InAppSignature = result.getInAppSignature().get(i);
                        onPaySuccessNotify(activity,inAppPurchaseData,InAppSignature,notifyUrl);
                    }
                }else{
                    obtainProductInfo(activity,purchaseIntentReq);
                }
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                if (e instanceof IapApiException) {
                    IapApiException apiException = (IapApiException)e;
                    Status status = apiException.getStatus();
                    int returnCode = apiException.getStatusCode();
                } else {
                    // Other external errors
                }
            }
        });
    }


    void obtainProductInfo(final Activity activity, final PurchaseIntentReq req){
        ProductInfoReq productInfoReq = new ProductInfoReq();
        productInfoReq.setPriceType(0);
        List<String> productList = new ArrayList<>();
        productList.add(req.getProductId());
        productInfoReq.setProductIds(productList);
        Iap.getIapClient(activity).obtainProductInfo(productInfoReq).addOnSuccessListener(new OnSuccessListener<ProductInfoResult>() {
            @Override
            public void onSuccess(ProductInfoResult productInfoResult) {
                createPurchaseIntent(req,activity);
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                Logger.i(TAG, "查询商品异常");

            }
        });
    }


    private void createPurchaseIntent(PurchaseIntentReq req, final Activity activity){

// 调用createPurchaseIntent接口创建托管商品订单
        Task<PurchaseIntentResult> task = Iap.getIapClient(activity).createPurchaseIntent(req);
        task.addOnSuccessListener(new OnSuccessListener<PurchaseIntentResult>() {
            @Override
            public void onSuccess(PurchaseIntentResult result) {
                // 获取创建订单的结果
                Status status = result.getStatus();
                if (status.hasResolution()) {
                    try {
                        // 6666是您自定义的常量
                        // 启动IAP返回的收银台页面
                        status.startResolutionForResult(activity, REQUEST_IAP);
                    } catch (IntentSender.SendIntentException exp) {
                    }
                }
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                if (e instanceof IapApiException) {

                    IapApiException apiException = (IapApiException) e;

                } else {
                    // 其他外部错误
                }
            }
        });
    }

    private void onPaySuccessNotify(Activity activity,String inAppPurchaseData,String inAppPurchaseDataSignature,String notifyUrl){

        if (judgeStrNull(inAppPurchaseData)){

            return;
        }
        JSONObject json  = new JSONObject();
        try {
            json.put("hwData",inAppPurchaseData);
            json.put("hwSign",inAppPurchaseDataSignature);

        } catch (JSONException e) {
            e.printStackTrace();
        }

        loginViewModel.requestChannelExtInfo(activity,notifyUrl, json, new ICallback() {
            @Override
            public void onResult(int code, String result) {
                if (code == ResultInfo.CODE_SUCCESS){

                        InAppPurchaseData inAppPurchaseDataBean = null;
                        try {
                            inAppPurchaseDataBean = new InAppPurchaseData(inAppPurchaseData);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                        String token = inAppPurchaseDataBean.getPurchaseToken();
                        consumeOwnedPurchase(activity,token);

                    }

            }
        });


    }


    public void consumeOwnedPurchase(Activity activity,String purchaseToken){
        // Constructs a ConsumeOwnedPurchaseReq object.

        ConsumeOwnedPurchaseReq req = new ConsumeOwnedPurchaseReq();
        req.setPurchaseToken(purchaseToken);
// to call the consumeOwnedPurchase API.
// To get the Activity instance that calls this API.

        Task<ConsumeOwnedPurchaseResult> task = Iap.getIapClient(activity).consumeOwnedPurchase(req);
        task.addOnSuccessListener(new OnSuccessListener<ConsumeOwnedPurchaseResult>() {
            @Override
            public void onSuccess(ConsumeOwnedPurchaseResult result) {
                // Obtain the result
                Logger.i("消耗成功");
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                if (e instanceof IapApiException) {
                    IapApiException apiException = (IapApiException)e;
                    Status status = apiException.getStatus();
                    int returnCode = apiException.getStatusCode();
                    Logger.i("消耗失败:"+status);
                } else {
                    // Other external errors
                }
            }
        });
    }


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

    private boolean judgeStrNull(String str) {
        return (str == null || str.equals(""));
    }


    public static String getPackageName(Activity ac) {

        String pkgName = ac.getPackageName();
        return pkgName;
    }


    private void hideFloatWindowNewWay(Activity activity) {
        Games.getBuoyClient(activity).hideFloatWindow();
    }
    private void showFloatWindowNewWay(Activity ac) {
        if (!hasInit) {
            init(ac);
        }
        Games.getBuoyClient(ac).showFloatWindow();
    }
}
