package com.hc.webapp.web;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.StringDef;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.widget.TextView;

import com.hc.lib.DownloadUtils;
import com.hc.lib.MacUtil;
import com.hc.model.YNYD.YNYDContentProvider;
import com.hc.model.YNYD.YNYDService;
import com.hc.request.Config;
import com.hc.request.core.DefaultCallback;
import com.hc.webapp.BuildConfig;
import com.hc.webapp.GetSXHeZiParam;
import com.jewel.lib.java.StringUtil;
import com.orhanobut.logger.Logger;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.regex.Pattern;

import static com.hc.lib.video.IVideoPlayer.PLAY_TIME_NO_LIMIT;


@SuppressWarnings("unused")
public class AndroidToJS {

    public static final String JS_EVENT_BACK = "javascript:onBackEvent()";
    public static final String JS_EVENT_PLAY_FINISH = "javascript:onPlayBackEvent()";
    private static final String JS_EVENT_AUTH_RESULT = "javascript:onAuthResult(%s, %s)";
    public static final String JS_EVENT_PLAY_NEXT = "javascript:onPlayNextEvent()";

    static String backFuc = "function(){if(document.onkeydown){document.onkeydown({keyCode:8});}}";
    public static final String JS_BACK_EVENT = "javascript:(" + backFuc + ")()";

    private static final String HAD_FLOAT_VIDEO = "1"; // 当前H5页面存在小窗视频
    private static final String NEED_MUTE = "0";


    String TAG ="AndroidToJS";

//    private String testVideo = "http://hnh5pic.oss-cn-shenzhen.aliyuncs.com/3.mp4";
//    private String testVideo = "http://163.com-www-letv.com/20180509/457_79ed60e3/index.m3u8";
    private String testVideo = "http://192.168.2.112/000079/000079.m3u8";

    private int platformType = BuildConfig.platformType; //1：百事通，2：银河，3：未来
    private int deviceType = BuildConfig.devicesType;

    /**
     * JS调用类型
     */
    @StringDef({JS_EVENT_BACK, JS_EVENT_PLAY_FINISH, JS_EVENT_PLAY_NEXT})
    @Retention(RetentionPolicy.SOURCE)
    private @interface JsEvent {

    }

    private Context context;
    private WebView webView;
    private YNYDContentProvider contentProvider;
    private YNYDService service;
    private PlayVideoListener playVideoListener;
    private long playTime = PLAY_TIME_NO_LIMIT;

    public AndroidToJS(Context context, WebView webView) {
        this.context = context;
        this.webView = webView;
        contentProvider = new YNYDContentProvider(context);
        service = new YNYDService(context);
    }

    public void setPlayVideoListener(PlayVideoListener playVideoListener) {
        this.playVideoListener = playVideoListener;
    }

    /**
     * 全屏播放
     *
     * @param time               可播放时间。如果为{@link com.hc.lib.video.IVideoPlayer#PLAY_TIME_NO_LIMIT},代表无限制播放
     * @param hadFloatVideo      当前H5页面是否有小窗
     * @param isNextVideo        是否为下一个视频，1表示当前播放的为下一个视频，其他值为第一个视频
     * @param showCompleteDialog 是否显示播放结束弹窗，1表示显示结束弹窗，其他值为不显示结束弹窗，显示结束弹窗时不会调用JS方法中的请求下一个视频方法
     */
    @JavascriptInterface
    public void playFull(String url, String sourceId, String title, String time, String hadFloatVideo, String isNextVideo, String showCompleteDialog) {
        Logger.d("调用全屏播放。源ID(%s)，标题(%s)，播放地址(%s)", sourceId, title, url);
        if (playVideoListener != null) {

            playTime = PLAY_TIME_NO_LIMIT;
            if (isDigitsOnly(time)) {
                playTime = Long.parseLong(time);
            }
            boolean hadFloat = TextUtils.equals(HAD_FLOAT_VIDEO, hadFloatVideo);
            boolean isCurrentNextVideo = TextUtils.equals(HAD_FLOAT_VIDEO, isNextVideo);
            boolean isShowCompleteDialog = TextUtils.equals(HAD_FLOAT_VIDEO, showCompleteDialog);
            Logger.d("调用全屏播放。有小窗(%s)，当前为非初始视频(%s)，显示结束弹窗(%s)", hadFloat, isCurrentNextVideo, isShowCompleteDialog);
            ((Activity) context).runOnUiThread(() -> playFull(url, sourceId, title, playTime, hadFloat, isCurrentNextVideo, isShowCompleteDialog, 0));
        }
    }

    /**
     * 全屏播放
     *
     * @param time               可播放时间。如果为{@link com.hc.lib.video.IVideoPlayer#PLAY_TIME_NO_LIMIT},代表无限制播放
     * @param hadFloatVideo      当前H5页面是否有小窗
     * @param isNextVideo        是否为下一个视频，1表示当前播放的为下一个视频，其他值为第一个视频
     * @param showCompleteDialog 是否显示播放结束弹窗，1表示显示结束弹窗，其他值为不显示结束弹窗，显示结束弹窗时不会调用JS方法中的请求下一个视频方法
     * @param seekTime        需要快进的时间
     */
    @JavascriptInterface
    public void playFull(String url, String sourceId, String title, String time, String hadFloatVideo, String isNextVideo, String showCompleteDialog, int seekTime) {
        Logger.d("调用全屏播放。源ID(%s)，标题(%s)，播放地址(%s)", sourceId, title, url);
        if (playVideoListener != null) {
            playTime = PLAY_TIME_NO_LIMIT;
            if (isDigitsOnly(time)) {
                playTime = Long.parseLong(time);
            }
            boolean hadFloat = TextUtils.equals(HAD_FLOAT_VIDEO, hadFloatVideo);
            boolean isCurrentNextVideo = TextUtils.equals(HAD_FLOAT_VIDEO, isNextVideo);
            boolean isShowCompleteDialog = TextUtils.equals(HAD_FLOAT_VIDEO, showCompleteDialog);
            Logger.d("调用全屏播放。有小窗(%s)，当前为非初始视频(%s)，显示结束弹窗(%s)，快进时间(%s)", hadFloat, isCurrentNextVideo, isShowCompleteDialog, seekTime);
            ((Activity) context).runOnUiThread(() -> playFull(url, sourceId, title, playTime, hadFloat, isCurrentNextVideo, isShowCompleteDialog, seekTime));
        }
    }

    private void playFull(String url, String sourceId, String title, long time, boolean hadFloat, boolean isNextVideo, boolean showCompleteDialog, int seekTime) {
        if (isNextVideo) { // 播放下一条视频时，直接在当前全屏窗口开启新视频的播放
            playVideoListener.playFullVideo(url, title, GetSXHeZiParam.getInstance(context).getUserName(), sourceId, time, hadFloat, showCompleteDialog, seekTime);
        } else if (hadFloat) { // 有小窗时，直接切换成全屏
            playVideoListener.playFullVideo(url, title, GetSXHeZiParam.getInstance(context).getUserName(), sourceId, time, true, showCompleteDialog, 0);
        } else { // 开启新的全屏播放窗口
            playVideoListener.playFullVideo(url, title, GetSXHeZiParam.getInstance(context).getUserName(), sourceId, time, false, showCompleteDialog, seekTime);
        }
    }

    /**
     * @param url      播放地址
     * @param sourceId 素材ID
     * @param title    视频标题
     * @param x        小窗起始x坐标
     * @param y        小窗起始y坐标
     * @param width    小窗宽度
     * @param height   小窗高度
     */
    @JavascriptInterface
    public void playFloat(String url, String sourceId, String title,
                          final String x, final String y, final String width, final String height, String needMute) {
        Logger.d("调用小窗口播放。播放地址(%s), 源ID(%s)，标题(%s)", url, sourceId, title);
        Logger.d("调用小窗口播放。坐标(%s, %s)，宽高(%s, %s)", x, y, width, height);
        boolean isMute = TextUtils.equals(NEED_MUTE, needMute);
        Logger.d("调用小窗口播放。需要静音：%s", isMute);
        if (isDigitsOnly(x) && isDigitsOnly(y) && isDigitsOnly(width) && isDigitsOnly(height) && playVideoListener != null) {
            ((Activity) context).runOnUiThread(() -> playFloat(url, sourceId, title,
                    (int) Float.parseFloat(x),
                    (int) Float.parseFloat(y),
                    (int) Float.parseFloat(width),
                    (int) Float.parseFloat(height), isMute));
        }
    }

    private void playFloat(String url, String sourceId, String title, final int x, final int y, final int width, final int height, boolean needMute) {
        playVideoListener.playFloatVideo(url,
                x, y, width, height,
                GetSXHeZiParam.getInstance(context).getUserName(), sourceId, title, needMute);
    }

    /**
     * 关闭小窗播放
     */
    @JavascriptInterface
    public void closeFloat() {
        Logger.d("关闭小窗口播放。");
        if (playVideoListener != null) {
            playVideoListener.stopFloatVideo();
        }
    }

    /**
     * 获取EPG结果
     */
    @JavascriptInterface
    public void getEPGAuthResult(String body) {
        service.auth(body, new DefaultCallback<String>() {
            @Override
            public void onSuccess(int what, @NonNull String data) {
                super.onSuccess(what, data);
                evaluateJavascript(webView, StringUtil.get(JS_EVENT_AUTH_RESULT, data, Config.RESPONSE_SUCCESS));
            }

            @Override
            public void onFail(int what, String msg) {
                super.onFail(what, msg);
                evaluateJavascript(webView, StringUtil.get(JS_EVENT_AUTH_RESULT, msg, Config.RESPONSE_ERROR));
            }

            @Override
            public void onError(int what, Throwable e) {
                super.onError(what, e);
                evaluateJavascript(webView, StringUtil.get(JS_EVENT_AUTH_RESULT, e.getMessage(), Config.RESPONSE_ERROR));
            }
        });
    }

    @JavascriptInterface
    public String getUserId() {
        return GetSXHeZiParam.getInstance(context).getUserName();
    }

    @JavascriptInterface
    public String getUser() {
        return contentProvider.getUserName();
    }

    @JavascriptInterface
    public String getEpgServer() {
        return GetSXHeZiParam.getInstance(context).getUserEpgServer();
    }

    @JavascriptInterface
    public String getPlatform() {
        return contentProvider.getPlatform();
    }

    @JavascriptInterface
    public String getToken() {
        return GetSXHeZiParam.getInstance(context).getUserToken();
    }

    @JavascriptInterface
    public int getVipState() {
        return 1;
    }

    @JavascriptInterface
    public int getVersionCode() {
        return BuildConfig.VERSION_CODE;
    }

    @JavascriptInterface
    public String getVersionName() {
        return BuildConfig.VERSION_NAME;
    }

    @JavascriptInterface
    public String getMac() {
        return MacUtil.getMac(context);
    }

    @JavascriptInterface
    public int getPlatformType() {
        Log.d(TAG,"platformType:" + platformType );
        return platformType;
    }

    @JavascriptInterface
    public int getDeviceType() {
        Log.d(TAG,"deviceType:" + deviceType);
        return deviceType;
    }

    @JavascriptInterface
    public void pay() {
    }

    @JavascriptInterface
    public void webRequest(String tag,String url){
        playVideoListener.webRequest(tag,url);
    }

    @JavascriptInterface
    public void appExit() {
        ((Activity) context).runOnUiThread(() -> ((Activity) context).finish());
        System.exit(0);
    }

    @JavascriptInterface
    public void update(String apkUrl) {
        ((Activity) context).runOnUiThread(() -> download(apkUrl));
    }

    @JavascriptInterface
    public void install(String apkPath) {
        ((Activity) context).runOnUiThread(() -> installApk(apkPath));
    }

    @JavascriptInterface
    public void uninstall() {
        ((Activity) context).runOnUiThread(() -> {
            Uri uri = Uri.fromParts("package", context.getPackageName(), null);
            Intent intent = new Intent(Intent.ACTION_DELETE, uri);
            context.startActivity(intent);
        });
    }

    private void download(String apkUrl) {
        Dialog dialog = new Dialog(context);
        dialog.setCancelable(false);
        dialog.setCanceledOnTouchOutside(false);
        TextView progressText = new TextView(context);
        progressText.setText("开始下载新版本");
        progressText.setTextColor(context.getResources().getColor(android.R.color.black));
        progressText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 40);
        dialog.setContentView(progressText);
        dialog.setTitle("新版本更新");
        DownloadUtils.download(apkUrl, context.getPackageName() + getVersionCode(), "apk", new DownloadUtils.DownloadProgressListener() {
            @Override
            public void onDownloadStart(String fileName) {
                dialog.show();
            }

            @Override
            public void onDownloadProgress(int progress) {
                if (dialog != null && dialog.isShowing()) {
                    progressText.setText(String.format("下载中...%s%s", progress, "%"));
                }
            }

            @Override
            public void onDownloadSuccessful(String filePath) {
                if (dialog != null && dialog.isShowing()) {
                    dialog.dismiss();
                }
                installApk(filePath);
            }
        });
    }

    private void installApk(String filePath) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//4.0以上系统弹出安装成功打开界面
        context.startActivity(intent);
    }

    /**
     * 调用js事件
     *
     * @param webView webView
     * @param script  {@link AndroidToJS#JS_EVENT_BACK}、{@link AndroidToJS#JS_EVENT_PLAY_FINISH}
     */
    public static void evaluateJavascript(WebView webView, @JsEvent String script) {
        if (webView == null) {
            Logger.e("webView对象为空，JS事件调用无法执行");
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            webView.evaluateJavascript(script, value -> {
                //此处为 js 返回的结果
                Log.d(com.hc.lib.TAG.TAG, value);
            });
        } else {
            webView.loadUrl(script);
        }
    }

    private boolean isDigitsOnly(String str) {
        return isInteger(str) || isDouble(str);
    }

    // 判断整数（int）
    private boolean isInteger(String str) {
        if (null == str || "".equals(str)) {
            return false;
        }
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

    //判断浮点数（double和float）
    private boolean isDouble(String str) {
        if (null == str || "".equals(str)) {
            return false;
        }
        Pattern pattern = Pattern.compile("^[-\\+]?[.\\d]*$");
        return pattern.matcher(str).matches();
    }

    /*private String getUserName(){
        try{
            Uri queryUri = Uri.parse("content://stbauthinfo/authentication/");
            Cursor cursor = context.getContentResolver().query(queryUri,new String[]{"value"},"name='username'",null,null);
            cursor.moveToFirst();
            String userName = cursor.getString(cursor.getColumnIndexOrThrow("value"));
            Log.d(TAG,"userName:" + userName);
            cursor.close();
            return userName;
        }catch (Exception e){
            e.printStackTrace();
            return "";
        }
    }



    private String getUserToken(){
        try{
            Uri queryUri = Uri.parse("content://stbauthinfo/authentication/");
            Cursor cursor = context.getContentResolver().query(queryUri,new String[]{"value"},"name='user_token'",null,null);
            cursor.moveToFirst();
            String userToken = cursor.getString(cursor.getColumnIndexOrThrow("value"));
            //userToken = "nBoKXx@OHP3fUP6fmcypIgl135856057";
            //userToken = "Se48ja9jiqjq-Stjhd4izfd";
            Log.d(TAG,"userToken:" + userToken);
            return userToken;
        }catch (Exception e){
            e.printStackTrace();
            return "";
        }
    }

    private String getUserEpgServer(){
        try{
            Uri queryUri = Uri.parse("content://stbauthinfo/authentication/");
            Cursor cursor = context.getContentResolver().query(queryUri,new String[]{"value"},"name='epg_server'",null,null);
            cursor.moveToFirst();
            String epgServer = cursor.getString(cursor.getColumnIndexOrThrow("value"));
            //epgServer = "http://111.20.105.85:9330";
            //epgServer = "http://111.20.42.163:33200";
            Log.d(TAG,"epgServer:" + epgServer);
            return epgServer;
        }catch (Exception e){
            e.printStackTrace();
            return "";
        }
    }*/


    public interface PlayVideoListener {
        /**
         * 小窗播放视频
         *
         * @param url      视频地址
         * @param x        小窗X坐标
         * @param y        小窗Y坐标
         * @param width    小窗宽度
         * @param height   小窗高度
         * @param needMute 是否静音
         */
        void playFloatVideo(String url, int x, int y, int width, int height, String uid, String sourceId, String title, boolean needMute);

        /**
         * 全屏播放
         *
         * @param url           视频地址
         * @param title         视频标题
         * @param uid           用户id
         * @param sourceId      源ID
         * @param playTime      可播放时间。如果为{@link com.hc.lib.video.IVideoPlayer#PLAY_TIME_NO_LIMIT},代表无限制播放
         * @param hadFloatVideo 当前H5页面是否有小窗
         * @param seekTime 全屏时需要快进的时间
         */
        void playFullVideo(String url, String title, String uid, String sourceId, long playTime, boolean hadFloatVideo, boolean showCompleteDialog, int seekTime);

        /**
         * 结束小窗播放
         */
        void stopFloatVideo();

        /*
         * 前端网络访问；
         * */
        void webRequest(String tag,String url);
    }
}
