package com.mayi.fastdevelop.web;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.webkit.JavascriptInterface;

import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.FileProvider;

import com.mayi.fastdevelop.base.BaseActivity;
import com.mayi.fastdevelop.comnon.Key;
import com.mayi.fastdevelop.comnon.RequestCode;
import com.mayi.fastdevelop.util.BitmapUtil;
import com.mayi.fastdevelop.util.DialogUtils;
import com.mayi.fastdevelop.util.LogUtils;
import com.mayi.fastdevelop.util.SpUtil;
import com.mayi.fastdevelop.util.SystemUtil;
import com.mayi.fastdevelop.view.CustomTitleBar;
import com.mayi.fastdevelop.view.dialog.BaseDialog;
import com.tencent.bugly.crashreport.CrashReport;
import com.tencent.smtt.export.external.interfaces.GeolocationPermissionsCallback;
import com.tencent.smtt.export.external.interfaces.WebResourceError;
import com.tencent.smtt.export.external.interfaces.WebResourceRequest;
import com.tencent.smtt.sdk.ValueCallback;
import com.tencent.smtt.sdk.WebChromeClient;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;

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

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/**
 * web基本页面
 * 支持JS和Android相互调用
 * 监听JS报错，上传bugly
 * 支持清除缓存，拍照，相册，定位，打电话，返回上一页，跳转原生页面（待扩展），
 * 开启Debug模式，给web传递用户信息，发送短信
 */
public class BaseWebActivity extends BaseActivity {

    private WebView webView;
    private CustomTitleBar title;
    private Handler handler;
    private ValueCallback<Uri> uploadMessage;
    private ValueCallback<Uri[]> uploadMessageAboveL;
    private String mCurrentPhotoPath;
    private WebListener webListener;

    public void setWebListener(WebListener webListener) {
        this.webListener = webListener;
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web);
        webView = findViewById(R.id.webview);
        title = findViewById(R.id.title);
        title.setOnClickLeftViewListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                webPageBack();
            }
        });
        handler = new Handler();
        initWebView();
        webView.setWebChromeClient(new WebChromeClient() {

            @Override
            public void onReceivedIcon(WebView view, Bitmap icon) {
                super.onReceivedIcon(view, icon);
            }

            @Override
            public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissionsCallback geolocationPermissionsCallback) {
                geolocationPermissionsCallback.invoke(origin, true, false);
                super.onGeolocationPermissionsShowPrompt(origin, geolocationPermissionsCallback);
            }

            //For Android  >= 5.0
            @Override
            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
                uploadMessageAboveL = filePathCallback;
                uploadPicture();
                return true;
            }

            //For Android  >= 4.1
            public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
                uploadMessage = valueCallback;
                uploadPicture();
            }
        });
        webView.setWebViewClient(new WebViewClient() {

            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {//处理网页加载失败时
                super.onReceivedError(view, errorCode, description, failingUrl);
                Throwable thr = new Throwable("web加载错误： errorCode" + errorCode + " \ndescription=" + description + " \nfailingUrl=" + failingUrl);
                CrashReport.postCatchedException(thr);
                LogUtils.i(thr.getMessage());
            }

            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {//处理网页加载失败时
                super.onReceivedError(view, request, error);
                Throwable thr = new Throwable("web加载错误： errorCode" + error.getErrorCode() + " \ndescription=" + error.getDescription() + " \nfailingUrl=" + request.getUrl());
                CrashReport.postCatchedException(thr);
                LogUtils.i(thr.getMessage());
            }
        });
        initView();
    }

    /**
     * web返回上一页
     */
    private void webPageBack() {
        if (webView.canGoBack()) {
            webView.goBack();
        } else {
            finish();
        }
    }

    private void initView() {
        String url = getIntent().getStringExtra("url");
        if (TextUtils.isEmpty(url)) {
            return;
        }
        if (url.contains("isNeedBackButton=true")) {
            title.setVisibility(View.VISIBLE);
        } else {
            title.setVisibility(View.GONE);
        }
        if (url.contains("userAppTitle=")) {
            int start = url.indexOf("userAppTitle=");
            String text = null;
            if (url.indexOf("&", start) != -1) {
                text = url.substring(start + "userAppTitle=".length(), url.indexOf("&", start));
            } else {
                text = url.substring(start + "userAppTitle=".length());
            }
            String keyWord = "";
            try {
                keyWord = URLDecoder.decode(text, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            title.setTextCenter(keyWord);
        }
        webView.loadUrl(url);
    }

    /**
     * 选择相机或者相册
     */
    public void uploadPicture() {
        BaseDialog dialog = DialogUtils.showSelectPicturesDialog(this, new DialogUtils.DefaultDialogListener() {
            @Override
            public void onClickLeft() {
                //请求拍照权限
                if (ActivityCompat.checkSelfPermission(BaseWebActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                    takePhoto();
                } else {
                    ActivityCompat.requestPermissions(BaseWebActivity.this, new String[]{Manifest.permission.CAMERA}, RequestCode.REQUEST_CODE_PERMISSION_CAMERA);
                }
            }

            @Override
            public void onClickRight() {
                chooseAlbumPic();
            }
        });
        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                //一定要返回null,否则<input type='file'>
                if (uploadMessage != null) {
                    uploadMessage.onReceiveValue(null);
                    uploadMessage = null;
                }
                if (uploadMessageAboveL != null) {
                    uploadMessageAboveL.onReceiveValue(null);
                    uploadMessageAboveL = null;
                }
            }
        });
    }

    /**
     * 拍照
     */
    public void takePhoto() {
        StringBuilder fileName = new StringBuilder();
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        fileName.append(System.currentTimeMillis()).append("_upload.jpg");
        File tempFile = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), fileName.toString());
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri uri = FileProvider.getUriForFile(this, getPackageName() + ".uri", tempFile);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        } else {
            Uri uri = Uri.fromFile(tempFile);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        }
        mCurrentPhotoPath = tempFile.getAbsolutePath();
        startActivityForResult(intent, RequestCode.REQUEST_CODE_CAMERA);
    }

    /**
     * 选择相册照片
     */
    public void chooseAlbumPic() {
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("image/*");
        startActivityForResult(Intent.createChooser(i, "Image Chooser"), RequestCode.REQUEST_CODE_ALBUM);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (webView.canGoBack()) {
                webView.goBack();
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    //app调用web方法
    public void appCallJs(final String method, final String data) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                webView.loadUrl("javascript:appCallJs(" + method + "," + data + ")");
            }
        });
    }

    @JavascriptInterface
    public void invoking(final String method, final String data) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (TextUtils.equals("clearCache", method)) {//清除缓存
                    webView.clearCache(true);
                    webView.clearHistory();
                    webView.clearFormData();
                } else if (TextUtils.equals("goCallPhone", method)) {//去打电话
                    try {
                        JSONObject jsonObject=new JSONObject(data);
                        SystemUtil.makePhoneCall(BaseWebActivity.this, jsonObject.optString("tel"));
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                } else if (TextUtils.equals("backPage", method)) {//返回上一页
                    webPageBack();
                } else if (TextUtils.equals("goPage", method)) {//跳转原生页面
                    goPage(data);
                } else if (TextUtils.equals("openDebug", method)) {//开启Debug模式
                    WebView.setWebContentsDebuggingEnabled(true);
                } else if (TextUtils.equals("goBrowser", method)) {//跳转浏览器
                    SystemUtil.gotoWeb(BaseWebActivity.this, data);
                } else if (TextUtils.equals("getUserInfo", method)) {//给web传递用户信息
                    appCallJs("setUserInfo", SpUtil.get(Key.USER_INFO, ""));
                } else if (TextUtils.equals("sendSMS", method)) {//发送短信
                    sendSMS(data);
                }
//                else if (TextUtils.equals("location", method)) {//定位
//                    LocationUtils.startLocation(BaseWebActivity.this, new LocationUtils.LocationCallback() {
//                        @Override
//                        public void onFail(String msg) {
//                            appCallJs("LocationFail", msg);
//                        }
//
//                        @Override
//                        public void onSuccess(LocationBean bean) {
//                            appCallJs("LocationSuccess", JSON.toJSONString(bean));
//                        }
//                    });
//                }
            }
        });
    }

    private void sendSMS(String data) {
        try {
            JSONObject jsonObject = new JSONObject(data);
            SystemUtil.sendSMS(BaseWebActivity.this, jsonObject.optString("phone")
                    , jsonObject.optString("msg"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    /**
     * 跳转原生页面
     * 待扩展
     */
    public void goPage(String data) {
        String pageName = null, parameter = null;
        try {
            JSONObject jsonObject = new JSONObject(data);
            pageName = jsonObject.optString("page");
            parameter = jsonObject.optString("parameter");
        } catch (JSONException e) {
            e.printStackTrace();
        }
//        if (TextUtils.equals(pageName, "MapLocation")) {//地图定位页面
//            Intent intent = new Intent(this, MapLocationActivity.class);
//            startActivityForResult(intent, RequestCode.MAP_LOCATION_ACTIVITY_RESULTCODE);
//        } else {
        if (webListener != null) {
            webListener.goPageListener(pageName, parameter);
        }
//        }
    }

    private void initWebView() {
        WebSettings settings = webView.getSettings();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            settings.setMixedContentMode(0);
        }
        settings.setBlockNetworkImage(false);

        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("platform", "Android");
            jsonObject.put("versionName", SystemUtil.getVersionName(this));
            jsonObject.put("AppName", SystemUtil.getAppName(this));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        settings.setUserAgentString(jsonObject.toString());

        settings.setSupportMultipleWindows(false);
        settings.setDefaultTextEncodingName("utf-8");
        settings.setJavaScriptEnabled(true);
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setCacheMode(WebSettings.LOAD_DEFAULT);
        settings.setAllowFileAccess(true);
        settings.setAppCacheEnabled(true);
        webView.setHorizontalScrollBarEnabled(false);//水平不显示
        webView.setVerticalScrollBarEnabled(false);   //垂直不显示
        settings.setUseWideViewPort(true);   //适应屏幕
        settings.setLoadWithOverviewMode(true);
        settings.setSupportZoom(true);   //支持屏幕缩放
        settings.setBuiltInZoomControls(true);
        settings.setDisplayZoomControls(false);   //不显示webview缩放按钮
        settings.setDatabaseEnabled(true);
        String dir = getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
        settings.setGeolocationEnabled(true);    //启用地理定位
        settings.setGeolocationDatabasePath(dir);    //设置定位的数据库路径
        settings.setDomStorageEnabled(true);   //最重要的方法，一定要设置，这就是出不来的主要原因
        webView.addJavascriptInterface(this, "jsCallApp");
    }

    private void uploadImage(Uri imageUri) {
        if (uploadMessage != null) {
            uploadMessage.onReceiveValue(imageUri);
            uploadMessage = null;
        }
        if (uploadMessageAboveL != null) {
            if (imageUri == null) {
                uploadMessageAboveL.onReceiveValue(null);
            } else {
                uploadMessageAboveL.onReceiveValue(new Uri[]{imageUri});
            }
            uploadMessageAboveL = null;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 0x04) {//地图定位回调
            if (resultCode == Activity.RESULT_OK) {
                showToast(data.getStringExtra(Key.AVTIVITY_RESULT));
            }
        } else if (requestCode == RequestCode.REQUEST_CODE_ALBUM || requestCode == RequestCode.REQUEST_CODE_CAMERA) {
            if (uploadMessage == null && uploadMessageAboveL == null) {
                return;
            }
            if (resultCode != RESULT_OK) {//取消拍照或者图片选择时
                uploadImage(null);  //一定要返回null,否则<input file> 就是没有反应
            } else if (resultCode == RESULT_OK) { //拍照成功和选取照片时
                Uri imageUri = null;
                switch (requestCode) {
                    case RequestCode.REQUEST_CODE_ALBUM:
                        if (data != null) {
                            imageUri = data.getData();
                        }
                        uploadImage(imageUri);
                        break;
                    case RequestCode.REQUEST_CODE_CAMERA:
                        zoomsInPhoto();
                        showLoadingDialog();
                        break;
                }
            }
            return;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    /**
     * 缩小照片尺寸
     */
    private void zoomsInPhoto() {
        AsyncTask asyncTask = new AsyncTask() {
            @Override
            protected Object doInBackground(Object[] objects) {
                if (!TextUtils.isEmpty(mCurrentPhotoPath)) {
                    BitmapUtil.zoomsInImageFile(mCurrentPhotoPath, mCurrentPhotoPath,
                            Bitmap.CompressFormat.JPEG, 900, 80);
                }
                return null;
            }

            @Override
            protected void onPostExecute(Object o) {
                super.onPostExecute(o);
                Uri uri = null;
                if (!TextUtils.isEmpty(mCurrentPhotoPath)) {
                    File file = new File(mCurrentPhotoPath);
                    uri = Uri.fromFile(file);
                }
                uploadImage(uri);
                dismssLoadingDialog();
            }
        };
        asyncTask.execute();
    }

    @Override
    protected void onPause() {
        super.onPause();
        webView.pauseTimers();
        if (isFinishing()) {
            webView.loadUrl("about:blank");
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        webView.resumeTimers();
    }

    @Override
    protected void onDestroy() {
        ViewParent parent = webView.getParent();
        if (parent != null) {
            ((ViewGroup) parent).removeView(webView);
        }
        // 销毁webview
        webView.removeAllViews();
        webView.destroy();
        webView = null;
        super.onDestroy();
    }
}

