package com.huawei.hwmdemo.view;

import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;

import com.google.android.material.tabs.TabLayout;
import com.huawei.cloudlink.openapi.HWMSdk;
import com.huawei.clpermission.CLPPermissionGrentListener;
import com.huawei.clpermission.CLPermConstant;
import com.huawei.clpermission.CLPermissionHelper;
import com.huawei.hwmbiz.HWMBizSdk;
import com.huawei.hwmbiz.eventbus.LoginResult;
import com.huawei.hwmbiz.login.api.SsoAuthParam;
import com.huawei.hwmcommonui.ui.popup.dialog.base.BaseDialogBuilder;
import com.huawei.hwmcommonui.ui.popup.toast.ToastBuilder;
import com.huawei.hwmconf.presentation.constant.Constants;
import com.huawei.hwmconf.presentation.error.ErrorMessageFactory;
import com.huawei.hwmconf.presentation.util.PermissionUtil;
import com.huawei.hwmconf.presentation.view.floatwindow.FloatWindowsManager;
import com.huawei.hwmconf.sdk.model.call.entity.MirrorType;
import com.huawei.hwmdemo.R;
import com.huawei.hwmdemo.delegate.DelegateHolder;
import com.huawei.hwmdemo.dependency.CustomPushExternalVideoFrameStrategy;
import com.huawei.hwmdemo.dependency.NeedCustomType;
import com.huawei.hwmdemo.externalframe.PushExternalFrameFlowWindow;
import com.huawei.hwmdemo.model.FeaturePage;
import com.huawei.hwmdemo.utils.DemoUtil;
import com.huawei.hwmdemo.view.sdk.IPushVideoFrameNotification;
import com.huawei.hwmfoundation.HwmContext;
import com.huawei.hwmfoundation.callback.HwmCallback;
import com.huawei.hwmfoundation.utils.LayoutUtil;
import com.huawei.hwmfoundation.utils.URLUtils;
import com.huawei.hwmfoundation.utils.rom.RomUtils;
import com.huawei.hwmlogger.HCLog;
import com.huawei.hwmsdk.enums.AuthServerType;

import java.util.List;

public class DemoActivity extends BaseActivity {
    private static final String TAG = DemoActivity.class.getSimpleName();

    private TabLayout tlTitle;
    private ViewPager vpContent;
    private WindowManager.LayoutParams floatWindowParams;
    private PushExternalFrameFlowWindow frameFlowWindow;
    private WindowManager mWindowManager;

    private static DemoActivity sInstance;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(DelegateHolder.getHwmUiDelegate().getScreenOrientation());
        ToastBuilder.getInstance().setContextReference(this.getApplicationContext());
        setContentView(R.layout.activity_main);
        sInstance = this;
        tlTitle = findViewById(R.id.main_tab);
        vpContent = findViewById(R.id.main_vp);
        List<FeaturePage> pages = DelegateHolder.getHwmUiDelegate().getHomePages();
        vpContent.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
            @Override
            @NonNull
            public Fragment getItem(int position) {
                return pages.get(position).getFragment();
            }

            @Override
            public int getCount() {
                return pages.size();
            }

            @Override
            public CharSequence getPageTitle(int position) {
                return pages.get(position).getTitle();
            }
        });

        tlTitle.setupWithViewPager(vpContent);
        if (pages.size() > 1) {
            tlTitle.setVisibility(View.VISIBLE);
        } else {
            tlTitle.setVisibility(View.GONE);
        }

        // 启用第三方采集后才需要添加悬浮窗
        if (DemoUtil.needCustom(NeedCustomType.ENABLE_EXTERNAL_CAPTURE)) {
            if (!CLPermissionHelper.hasPermissionWithType(this, CLPermConstant.Type.CAMERA)) {
                PermissionUtil.checkAndRequestPermission(this, CLPermConstant.Type.FRONT_CAMERA,
                    new CLPPermissionGrentListener() {
                        @Override
                        public void onGrant() {
                            HCLog.i(TAG, "checkAndRequestPermission onGrant");
                            requestFloatPermission();
                        }

                        @Override
                        public void onDeny() {
                            HCLog.e(TAG, "checkAndRequestPermission onDeny");
                        }
                    });
            } else {
                requestFloatPermission();
            }
        }

        doSchemaLink(getIntent());
    }

    public static DemoActivity getInstance() {
        return sInstance;
    }

    private void requestFloatPermission() {
        if (!FloatWindowsManager.getInstance().checkPermission(DemoUtil.getApplication())) {
            BaseDialogBuilder baseDialogBuilder = new BaseDialogBuilder(DemoActivity.this);
            baseDialogBuilder
                .setMessage(DemoUtil.getResContext().getString(R.string.hwmconf_apply_folat_win_permission_tip))
                .addAction(DemoUtil.getResContext().getString(R.string.hwmconf_dialog_cancle_btn_str),
                    (dialog, button, i) -> {
                        dialog.dismiss();
                        DemoUtil.showToast("未开启悬浮窗将导致第三方视频采集失败");
                    })
                .addAction(DemoUtil.getResContext().getString(R.string.hwmconf_dialog_confirm_btn_str),
                    (dialog, button, index) -> {
                        FloatWindowsManager.getInstance()
                            .applyPermission(DemoActivity.this, Constants.REQUEST_FLOAT_WINDOW_VIDEO);
                        dialog.dismiss();
                        CustomPushExternalVideoFrameStrategy.registerPushVideoFrameListener(confResultNotification);
                    })
                .show();
        } else {
            CustomPushExternalVideoFrameStrategy.registerPushVideoFrameListener(confResultNotification);
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        doSchemaLink(intent);
    }

    private void doSchemaLink(Intent intent) {
        if (intent != null) {
            Uri uri = intent.getData();
            if (uri != null) {
                String page = URLUtils.getQueryParameterSafe(uri, "page");
                String domain = URLUtils.getQueryParameterSafe(uri, "domain");
                String code = URLUtils.getQueryParameterSafe(uri, "code");
                if ("ssoLogin".equals(page)) {
                    DemoUtil.showToast("sso schema link login domain:" + domain + " code:" + code);
                    doSsoLogin(domain, code);
                }
            }
        }
    }

    private void doSsoLogin(String domain, String code) {
        showLoading();
        SsoAuthParam ssoAuthParam = new SsoAuthParam();
        ssoAuthParam.setDomain(domain);
        ssoAuthParam.setCode(code);
        ssoAuthParam.setAuthServerType(AuthServerType.AUTH_SERVER_TYPE_OAUTH2);
        HWMSdk.getOpenApi(getApplication()).loginBySSO(ssoAuthParam, new HwmCallback<LoginResult>() {
            @Override
            public void onSuccess(LoginResult loginResult) {
                dismissLoading();
                if (loginResult != null) {
                    DemoUtil.showToast("登录成功" + loginResult.getUserUuid() + "; account：" + loginResult.getAccount()
                        + "; thirdAccount：" + loginResult.getThirdAccount());
                } else {
                    DemoUtil.showToast("已登录");
                }
            }

            @Override
            public void onFailed(int retCode, String desc) {
                HCLog.i(TAG, "loginBySSO onFailed" + retCode + " " + desc);
                HwmContext.getInstance().runOnMainThread(() -> {
                    String err = ErrorMessageFactory.create(retCode);
                    if (TextUtils.isEmpty(err)) {
                        err = desc;
                    }
                    DemoUtil.showToastDialog("loginBySSO", retCode, err);
                    dismissLoading();
                });
            }
        });
    }

    @Override
    protected void onDestroy() {
        if (DemoUtil.needCustom(NeedCustomType.ENABLE_EXTERNAL_CAPTURE)) {
            CustomPushExternalVideoFrameStrategy.removePushVideoFrameListener(confResultNotification);
        }
        sInstance = null;
        super.onDestroy();
    }

    IPushVideoFrameNotification confResultNotification = new IPushVideoFrameNotification() {
        @Override
        public void onSetLocalMirrorNotify() {
            //窗口镜像模式 0:不做镜像(默认值) 1:上下镜像(目前未支持) 2:左右镜像
            runOnUiThread(() ->
                HWMBizSdk.getBizOpenApi().setLocalVideoMirrorType(MirrorType.MIRROR_LEFT_RIGHT));
        }

        @Override
        public void onPushVideoFrameStarted() {
            createExternalFrameFloatWindow(DemoActivity.this);
        }

        @Override
        public void onPushVideoFrameEnded() {
            removeExternalFrameFloatWindow(DemoActivity.this);
        }
    };

    /**
     * 创建第三方采集悬浮窗
     * @param context
     */
    public void createExternalFrameFloatWindow(Context context) {
        HCLog.i(TAG, "createExternalFrameFloatWindow start");
        if (mWindowManager == null) {
            mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        }
        int screenWidth = LayoutUtil.getScreenWidth(DemoUtil.getApplication());
        int marginRight = 1;
        int marginTop = 1;
        int statusBarHeight = LayoutUtil.getStatusBarHeight(DemoUtil.getApplication());
        if (frameFlowWindow == null) {
            frameFlowWindow = new PushExternalFrameFlowWindow(context);
            if (floatWindowParams == null) {
                floatWindowParams = new WindowManager.LayoutParams();
                //兼容性，8.0谷歌对TYPE_TOAST进行了制裁
                floatWindowParams.packageName = context.getPackageName();
                //兼容性，8.0谷歌对TYPE_TOAST进行了制裁
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    floatWindowParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
                } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    floatWindowParams.type = WindowManager.LayoutParams.TYPE_PHONE;
                } else {
                    floatWindowParams.type = WindowManager.LayoutParams.TYPE_TOAST;
                }
                // 非小米手机并且android系统小于7.1.1，将type设置成TYPE_TOAST
                if (!RomUtils.checkIsMiuiRom() && Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
                    floatWindowParams.type = WindowManager.LayoutParams.TYPE_TOAST;
                }
                floatWindowParams.format = PixelFormat.RGBA_8888;
                floatWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
                floatWindowParams.gravity = Gravity.LEFT | Gravity.TOP;
                floatWindowParams.width = frameFlowWindow.getViewWidth();
                floatWindowParams.height = frameFlowWindow.getViewHeight();
                floatWindowParams.x = screenWidth - marginRight - floatWindowParams.width;
                floatWindowParams.y = marginTop - statusBarHeight;
            }
            mWindowManager.addView(frameFlowWindow, floatWindowParams);
            frameFlowWindow.setKeepScreenOn(true);
            frameFlowWindow.createOrientationListener();
        }
    }

    /**
     * 移除第三方采集悬浮框
     *
     * @param context
     */
    public void removeExternalFrameFloatWindow(Context context) {
        HCLog.i(TAG, "removeExternalFrameFloatWindow start");
        if (frameFlowWindow != null) {
            try {
                WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
                frameFlowWindow.destroyOrientationListener();
                windowManager.removeView(frameFlowWindow);
                frameFlowWindow = null;
                floatWindowParams = null;
            } catch (IllegalArgumentException ex) {
                HCLog.e(TAG, "catch not attached to window manager");
            }
        }
        HCLog.i(TAG, "removeExternalFrameFloatWindow end");
    }
}
