package com.youmi.android.offer;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.widget.Toast;

import com.sheep.gamegroup.util.DataUtil;
import com.sheep.jiuyan.samllsheep.SheepApp;
import com.sheep.jiuyan.samllsheep.utils.G;

import org.afinal.simplecache.DataKey;

import java.util.Locale;

import cde.ewd.adw.AdManager;
import cde.ewd.adw.os.EarnPointsOrderInfo;
import cde.ewd.adw.os.EarnPointsOrderList;
import cde.ewd.adw.os.OffersBrowserConfig;
import cde.ewd.adw.os.OffersManager;
import cde.ewd.adw.os.PointsChangeNotify;
import cde.ewd.adw.os.PointsEarnNotify;
import cde.ewd.adw.os.PointsManager;

/**
 * Created by realicing on 2018/10/29.
 * realicing@sina.com
 */
public class YmPermissionUtil implements PointsChangeNotify, PointsEarnNotify {
    private Activity activity;

    public YmPermissionUtil(Activity activity) {
        this.activity = activity;
    }

    /**
     * 小tips:这里的int数值不能太大，否则不会弹出请求权限提示，测试的时候,改到1000就不会弹出请求了
     */
    private final static int READ_PHONE_STATE_CODE = 101;

    private final static int WRITE_EXTERNAL_STORAGE_CODE = 102;
    /**
     * 有米 Android SDK 所需要向用户申请的权限列表
     */
    private PermissionModel[] models = new PermissionModel[]{
            new PermissionModel(Manifest.permission.READ_PHONE_STATE, "我们需要读取手机信息的权限来标识您的身份", READ_PHONE_STATE_CODE),
            new PermissionModel(Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    "我们需要您允许我们读写你的存储卡，以方便我们临时保存一些数据",
                    WRITE_EXTERNAL_STORAGE_CODE
            ),
    };

    /**
     * 这里我们演示如何在Android 6.0+上运行时申请权限
     */
    public void checkPermissions() {
        try {

            for (PermissionModel model : models) {
                if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(activity, model.permission)) {
                    ActivityCompat.requestPermissions(activity, new String[]{model.permission}, model.requestCode);
                    return;
                }
            }

            // 到这里就表示有米所有需要的权限已经通过申请，权限已经申请就打开demo
            showYmOffersAds();
        } catch (Throwable e) {
            Log.e("YoumiSdk", "", e);
        }
    }

    public void showYmOffersAds() {
        initYoumi();
        OffersManager.getInstance(activity).showOffersWall();
    }

    private void initYoumi() {
        // 自v6.3.0起，所有其他代码必须在初始化接口调用之后才能生效
        // 初始化接口，应用启动的时候调用，参数：appId, appSecret, isEnableYoumiLog
        AdManager.getInstance(SheepApp.getInstance()).init(YmConfig.getAppId(), YmConfig.getAppSecret(), YmConfig.isShowLog());

        // 有米android 积分墙sdk 5.0.0之后支持定制浏览器顶部标题栏的部分UI
         setOfferBrowserConfig();

        // 如果开发者使用积分墙的服务器回调,
        // 1.需要告诉sdk，现在采用服务器回调
        // 2.建议开发者传入自己系统中用户id（如：邮箱账号之类的）（请限制在50个字符串以内）
        // 3.务必在下面的OffersManager.getInstance(this).onAppLaunch();代码之前声明使用服务器回调
//        如果使用了服务器订单回调，则上文所述的客户端积分功能
//                积分管理
//        监听积分余额变动
//                监听积分订单到账通知
//        配置积分到账提醒
//        将不再适用，即SDK将不会通知客户端应用订单到账，所有积分流程只能通过服务器实现，可以极大地提高积分 安全性
        OffersManager.getInstance(activity).setUsingServerCallBack(true);
         OffersManager.getInstance(activity).setCustomUserId(DataUtil.getInstance().getUserId());

        // 如果使用积分广告，请务必调用积分广告的初始化接口:
        OffersManager.getInstance(activity).onAppLaunch();

        // (可选)注册积分监听-随时随地获得积分的变动情况

        PointsManager.getInstance(activity).registerNotify(this);

        // (可选)注册积分订单赚取监听（sdk v4.10版本新增功能）
        PointsManager.getInstance(activity).registerPointsEarnNotify(this);

        // (可选)设置是否在通知栏显示下载相关提示。默认为true，标识开启；设置为false则关闭。（sdk v4.10版本新增功能）
        // AdManager.getInstance(this).setIsDownloadTipsDisplayOnNotification(false);

        // (可选)设置安装完成后是否在通知栏显示已安装成功的通知。默认为true，标识开启；设置为false则关闭。（sdk v4.10版本新增功能）
        // AdManager.getInstance(this).setIsInstallationSuccessTipsDisplayOnNotification(false);

        // (可选)设置是否在通知栏显示积分赚取提示。默认为true，标识开启；设置为false则关闭。
        // 如果开发者采用了服务器回调积分的方式，那么本方法将不会生效
        // PointsManager.getInstance(this).setEnableEarnPointsNotification(false);

        // (可选)设置是否开启积分赚取的Toast提示。默认为true，标识开启；设置为false这关闭。
        // 如果开发者采用了服务器回调积分的方式，那么本方法将不会生效
        // PointsManager.getInstance(this).setEnableEarnPointsToastTips(false);

        // 查询积分余额
        // 从5.3.0版本起，客户端积分托管将由 int 转换为 float
//        float pointsBalance = PointsManager.getInstance(activity).queryPoints();
        if(YmConfig.isToastTotalPrice())
            G.showToast("积分余额：" + DataUtil.getAsInt(DataKey.YM_TOTAL_PRICE, 0));
    }

    /**
     * 设置积分墙浏览器标题栏样式
     */
    private void setOfferBrowserConfig() {

        // 设置标题栏——标题
        OffersBrowserConfig.getInstance(activity).setBrowserTitleText("有米积分");

        // 设置标题栏——背景颜色（ps：积分墙标题栏默认背景颜色为#FFBB34）
        OffersBrowserConfig.getInstance(activity).setBrowserTitleBackgroundColor(Color.parseColor("#29d6fd"));

        // 设置标题栏——是否显示积分墙右上角积分余额区域 true：是 false：否
        OffersBrowserConfig.getInstance(activity).setPointsLayoutVisibility(true);

        // 设置标题栏——是否显示有米的logo
        OffersBrowserConfig.getInstance(activity).setLogoVisibility(false);

    }

    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case READ_PHONE_STATE_CODE:
            case WRITE_EXTERNAL_STORAGE_CODE:
                // 如果用户不允许，我们视情况发起二次请求或者引导用户到应用页面手动打开
                if (PackageManager.PERMISSION_GRANTED != grantResults[0]) {

                    // 二次请求，表现为：以前请求过这个权限，但是用户拒接了
                    // 在二次请求的时候，会有一个“不再提示的”checkbox
                    // 因此这里需要给用户解释一下我们为什么需要这个权限，否则用户可能会永久不在激活这个申请
                    // 方便用户理解我们为什么需要这个权限
                    if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permissions[0])) {
                        new AlertDialog.Builder(activity).setTitle("权限申请")
                                .setMessage(findPermissionExplain(permissions[0]))
                                .setPositiveButton("确定", new DialogInterface.OnClickListener() {

                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        checkPermissions();
                                    }
                                })
                                .show();
                    }
                    // 到这里就表示已经是第3+次请求，而且此时用户已经永久拒绝了，这个时候，我们引导用户到应用权限页面，让用户自己手动打开
                    else {
                        G.shortToast("部分权限被拒绝获取，将会会影响后续功能的使用，建议重新打开");
                        openAppPermissionSetting();
                    }
                    return;
                }

                // 到这里就表示用户允许了本次请求，我们继续检查是否还有待申请的权限没有申请
                if (isAllRequestedPermissionGranted()) {
                    showYmOffersAds();
                } else {
                    checkPermissions();
                }
                break;
            default:
                break;
        }
    }

    private String findPermissionExplain(String permission) {
        if (models != null) {
            for (PermissionModel model : models) {
                if (model != null && model.permission != null && model.permission.equals(permission)) {
                    return model.explain;
                }
            }
        }
        return null;
    }

    private boolean isAllRequestedPermissionGranted() {
        for (final PermissionModel model : models) {
            if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(activity, model.permission)) {
                return false;
            }
        }
        return true;
    }

    private void openAppPermissionSetting() {
        try {
            Intent intent =
                    new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + activity.getPackageName()));
            intent.addCategory(Intent.CATEGORY_DEFAULT);

            // Android L 之后Activity的启动模式发生了一些变化
            // 如果用了下面的 Intent.FLAG_ACTIVITY_NEW_TASK ，并且是 startActivityForResult
            // 那么会在打开新的activity的时候就会立即回调 onActivityResult
            // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            activity.startActivityForResult(intent, 123456789);
        } catch (Throwable e) {
            Log.e("YoumiSdk", "", e);
        }
    }

    /**
     * 积分余额发生变动时，就会回调本方法（本回调方法执行在UI线程中）
     * <p/>
     * 从5.3.0版本起，客户端积分托管将由 int 转换为 float
     */
    @Override
    public void onPointBalanceChange(float pointsBalance) {
        G.showToast("积分余额：" + pointsBalance);
    }

    /**
     * 积分订单赚取时会回调本方法（本回调方法执行在UI线程中）
     */
    @Override
    public void onPointEarn(Context context, EarnPointsOrderList list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        // 遍历订单并且toast提示
        for (int i = 0; i < list.size(); ++i) {
            EarnPointsOrderInfo info = list.get(i);
            G.shortToast(info.getMessage());
        }
    }

    public void onDestroy() {

        // （可选）注销积分监听
        // 如果在onCreate调用了PointsManager.getInstance(this).registerNotify(this)进行积分余额监听器注册，那这里必须得注销
        PointsManager.getInstance(activity).unRegisterNotify(this);

        // （可选）注销积分订单赚取监听
        // 如果在onCreate调用了PointsManager.getInstance(this).registerPointsEarnNotify(this)进行积分订单赚取监听器注册，那这里必须得注销
        PointsManager.getInstance(activity).unRegisterPointsEarnNotify(this);

        // 回收积分广告占用的资源
        OffersManager.getInstance(activity).onAppExit();
    }

    private static class PermissionModel {

        /**
         * 请求的权限
         */
        String permission;

        /**
         * 解析为什么请求这个权限
         */
        String explain;

        /**
         * 请求代码
         */
        int requestCode;

        PermissionModel(String permission, String explain, int requestCode) {
            this.permission = permission;
            this.explain = explain;
            this.requestCode = requestCode;
        }
    }
}
