package com.videogo.ui.login;

import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;

import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

import com.videogo.EzvizApplication;
import com.videogo.exception.BaseException;
import com.videogo.global.DemoConfig;
import com.videogo.global.GlobalKit;
import com.videogo.openapi.EZOpenSDK;
import com.videogo.ui.devicelist.EZDeviceListActivity;
import com.videogo.ui.login.helper.MainActivityHelper;
import com.videogo.ui.login.helper.SdkInitHelper;
import com.videogo.ui.login.helper.TKTokenTestHelper;
import com.videogo.util.LocalInfo;
import com.videogo.util.LogUtil;

import ezviz.ezopensdk.BuildConfig;
import ezviz.ezopensdk.R;

import com.videogo.util.SpTool;
import com.videogo.global.ValueKeys;
import ezviz.ezopensdkcommon.common.RootActivity;
import static com.videogo.EzvizApplication.getOpenSDK;
import static com.videogo.constant.Constant.OAUTH_SUCCESS_ACTION;

public class MainActivity extends RootActivity {

    private final static String TAG = MainActivity.class.getSimpleName();
    private ServerAreasEnum mCurrentServerArea;
    private EditText mApiET;
    private EditText mAuthET;
    private EditText mAppKeyET;
    private EditText mAccessTokenET;
    private EditText mSpecifiedDeviceET;
    // token登录参数
    public static SdkInitParams mInitParams;
    // 萤石云账号登录参数
    private SdkInitParams mSdkInitParams;
    // 萤石账号登录成功回调广播
    private BroadcastReceiver mLoginResultReceiver;
    // 通用 UI 工具
    private MainActivityHelper mHelper;
    // 测试专用工具
    private TKTokenTestHelper mTestHelper;

    /**
     * @param savedInstanceState
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initUI();
        autoLogin();

        mAppKeyET.setText(DemoConfig.APPKEY_DEV);
        mAccessTokenET.setText(DemoConfig.TOKEN_DEV);
        mSpecifiedDeviceET.setText(DemoConfig.DEVICE_DEV);
    }

    /**
     * 通过AccessToken/tkToken进行体验
     */
    public void onClickStartExperience(View view) {
        if (checkLoginInfo()) {
            SdkInitParams sdkInitParams = SdkInitParams.createBy(mCurrentServerArea);
            sdkInitParams.appKey = mHelper.getValidText(mAppKeyET.getText().toString());
            sdkInitParams.token = mHelper.getValidText(mAccessTokenET.getText().toString());
            sdkInitParams.openApiServer = mHelper.getValidText(mApiET.getText().toString());
            sdkInitParams.openAuthApiServer = mHelper.getValidText(mAuthET.getText().toString());
            sdkInitParams.specifiedDevice = mHelper.getValidText(mSpecifiedDeviceET.getText().toString());
            SdkInitHelper.initSdk(getApplication(), sdkInitParams);
            // SDK初始化后，设置暂存的设备级token
            mTestHelper.applyPendingDeviceTokens();
            startCheckLoginValidity(sdkInitParams);
        }
    }

    /**
     * 通过萤石账号进行体验
     */
    public void onClickLoginByEzvizAccount(View view) {
        if (mCurrentServerArea == null || mCurrentServerArea.defaultOpenAuthAppKey == null) {
            showToast("Error occurred! Please try to use demo with appKey & accessToken.");
            return;
        }
        mSdkInitParams = SdkInitParams.createBy(mCurrentServerArea);
        mSdkInitParams.appKey = mHelper.getValidText(mAppKeyET.getText().toString());
        mSdkInitParams.openApiServer = mHelper.getValidText(mApiET.getText().toString());
        mSdkInitParams.openAuthApiServer = mHelper.getValidText(mAuthET.getText().toString());
        /**
         * 国内使用萤石账号登录，一定要设置为false
         * 本Demo是accessToken和tkToken两种模式共存的，如果第一次使用了tkToken，第二次要用accessToken模式登录，需要将enableSDKWithTKToken重置为false
         */
        if (!mSdkInitParams.usingGlobalSDK) {
            EZOpenSDK.enableSDKWithTKToken(false);
        }
        SdkInitHelper.initSdk(getApplication(), mSdkInitParams);
        registerLoginResultReceiver();
        getOpenSDK().openLoginPage();
    }

    public void jcTestClick(View view) {
        if (!GlobalKit.isJCTest) {
            mTestHelper.showTKTokenBatchSetupDialog(mAppKeyET, mAccessTokenET, mSpecifiedDeviceET);
            return;
        }
        mCurrentServerArea = ServerAreasEnum.getAllServers().get(0);
        mAppKeyET.setText(DemoConfig.APPKEY_JC);
        mAccessTokenET.setText(DemoConfig.TOKEN_JC);
        mSpecifiedDeviceET.setText(DemoConfig.DEVICE_JC);
        mApiET.setText(mCurrentServerArea.openApiServer);
        mAuthET.setText(mCurrentServerArea.openAuthApiServer);
        onClickStartExperience(null);
    }

    /**
     * 跳转设备列表页面
     */
    private void jumpToCameraListActivity() {
        Intent toCameraListIntent = new Intent(getApplicationContext(), EZDeviceListActivity.class);
        startActivity(toCameraListIntent);
        finish();
    }

    @SuppressLint("UnspecifiedRegisterReceiverFlag")
    private void registerLoginResultReceiver() {
        if (mLoginResultReceiver == null) {
            mLoginResultReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    Log.i(TAG, "login success by h5 page");
                    unregisterLoginResultReceiver();
                    SpTool.storeValue(ValueKeys.SDK_INIT_PARAMS, mSdkInitParams.toString());
                    jumpToCameraListActivity();
                    finish();
                }
            };
            IntentFilter filter = new IntentFilter(OAUTH_SUCCESS_ACTION);
            // 添加版本兼容性判断
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {// Android 8.0及以上
                registerReceiver(mLoginResultReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
            } else {
                registerReceiver(mLoginResultReceiver, filter);
            }
            Log.i(TAG, "registered login result receiver");
        }
    }

    private void unregisterLoginResultReceiver() {
        if (mLoginResultReceiver != null) {
            unregisterReceiver(mLoginResultReceiver);
            mLoginResultReceiver = null;
            Log.i(TAG, "unregistered login result receiver");
        }
    }

    private void initData() {
        mHelper = new MainActivityHelper(this);
        mTestHelper = new TKTokenTestHelper(this);

        SpTool.init(getApplicationContext());
        mInitParams = SdkInitParams.loadLast();
        if (mInitParams == null || mInitParams.appKey == null) {
            mInitParams = SdkInitParams.createDefault();
        }
        if (!TextUtils.isEmpty(mInitParams.appKey) && !TextUtils.isEmpty(mInitParams.token)) {
            SdkInitHelper.initSdk(getApplication(), mInitParams);
        }
    }

    /**
     * 检查AccessToken是否有效，在子线程中执行
     *
     * @param paramsToSave 验证成功后需要保存的参数，传 null 则不保存
     */
    private void startCheckLoginValidity(SdkInitParams paramsToSave) {
        new Thread(() -> {
            mHelper.showLoginAnim(true);
            if (checkAppKeyAndAccessToken()) {
                if (paramsToSave != null) {
                    SpTool.storeValue(ValueKeys.SDK_INIT_PARAMS, paramsToSave.toString());
                }
                jumpToCameraListActivity();
            }
            mHelper.showLoginAnim(false);
        }).start();
    }

    /**
     * 通过调用服务接口判断AppKey和AccessToken且有效
     *
     * @return 是否依旧有效
     */
    private boolean checkAppKeyAndAccessToken() {
        boolean isValid = false;
        try {
            EzvizApplication.getOpenSDK().getDeviceList(0, 1);
            isValid = true;
        } catch (BaseException e) {
            e.printStackTrace();
            Log.e(TAG, "Error code is " + e.getErrorCode());
            int errCode = e.getErrorCode();
            String errMsg;
            switch (errCode) {
                case 400031:
                    errMsg = getApplicationContext().getString(R.string.tip_of_bad_net);
                    break;
                default:
                    errMsg = getApplicationContext().getString(R.string.login_expire) + "\n" + e.getErrorInfo().description;
                    break;
            }
            showToast(errMsg);
        }
        return isValid;
    }

    /**
     * 验证是否输入 AppKey 和 AccessToken
     */
    private boolean checkLoginInfo() {
        if (mAppKeyET.getText().toString().equals("")) {
            showToast("AppKey不能为空");
            return false;
        }
        if (mAccessTokenET.getText().toString().equals("")) {
            showToast("AccessToken不能为空");
            return false;
        }
        return true;
    }

    private void initUI() {
        // 设置服务器区域下拉框显示和监听
        Spinner areaServerSp = findViewById(R.id.sp_server_area);
        if (areaServerSp != null) {
            ServerAreasSpAdapter adapter = new ServerAreasSpAdapter(getApplicationContext(), ServerAreasEnum.getAllServers());
            areaServerSp.setAdapter(adapter);
            areaServerSp.setOnItemSelectedListener(mServerAreasOnItemCLickLister);
        }
        mAppKeyET = findViewById(R.id.et_app_key);
        mAccessTokenET = findViewById(R.id.et_access_token);
        mApiET = findViewById(R.id.et_api_url);
        mAuthET = findViewById(R.id.et_auth_server);
        mSpecifiedDeviceET = findViewById(R.id.et_specified_device);

        SdkInitParams sdkInitParams = SdkInitParams.loadLast();
        if (sdkInitParams != null) {
            mAppKeyET.setText(sdkInitParams.appKey);
            try {
                mAccessTokenET.setText(EZOpenSDK.getInstance().getEZAccessToken().getAccessToken());
                mApiET.setText(sdkInitParams.openApiServer);
                mAuthET.setText(sdkInitParams.openAuthApiServer);
                mSpecifiedDeviceET.setText(sdkInitParams.specifiedDevice);
            } catch (Exception e) {
                LogUtil.d(TAG, "failed to load AccessToken");
            }
            for (int position = 0; position < ServerAreasEnum.getAllServers().size(); position++) {
                if (sdkInitParams.serverAreaId == ServerAreasEnum.getAllServers().get(position).id) {
                    if (areaServerSp != null) {
                        areaServerSp.setSelection(position);
                    }
                }
            }
        }

        TextView sdkVerTv = findViewById(R.id.tv_sdk_ver);
        if (sdkVerTv != null) {
            sdkVerTv.setText("SDK Version: " + BuildConfig.VERSION_NAME);
        }

        // 为所有输入框设置清除按钮
        mHelper.setupClearButton(mApiET);
        mHelper.setupClearButton(mAuthET);
        mHelper.setupClearButton(mAppKeyET);
        mHelper.setupClearButton(mAccessTokenET);
        mHelper.setupClearButton(mSpecifiedDeviceET);
    }

    /**
     * 自动登录
     */
    private void autoLogin() {
        View view = findViewById(R.id.page_container);
        if (view != null) {
            view.post(() -> {
                if (TextUtils.isEmpty(mInitParams.appKey)) {
                    showToast("AppKey is empty!");
                    return;
                }
                LocalInfo localInfo = LocalInfo.getInstance();
                boolean isNotExistAccessToken = localInfo == null || localInfo.getEZAccesstoken() == null
                        || localInfo.getEZAccesstoken().getAccessToken() == null;
                boolean isNotExistTKToken = localInfo == null || localInfo.getEZAccesstoken() == null
                        || localInfo.getEZAccesstoken().getHttpToken() == null;
                if (isNotExistAccessToken && isNotExistTKToken) {
                    String tip = "AccessToken/TKToken is empty!";
                    LogUtil.i(TAG, tip);
                    return;
                }
                startCheckLoginValidity(null);
            });
        }
    }

    private AdapterView.OnItemSelectedListener mServerAreasOnItemCLickLister = new AdapterView.OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            mCurrentServerArea = ServerAreasEnum.getAllServers().get(position);
            mApiET.setText(mCurrentServerArea.openApiServer);
            mAuthET.setText(mCurrentServerArea.openAuthApiServer);
            // 仅预置了appKey的区域才展示萤石账号登录按钮
            showEzvizAccountLoginTv(mCurrentServerArea.defaultOpenAuthAppKey != null);
            // 萤石测试将appKey代入，方便测试
            if (DemoConfig.EzvizTest.equals(mCurrentServerArea.areaName)) {
                mAppKeyET.setText(mCurrentServerArea.defaultOpenAuthAppKey);
                mAccessTokenET.setText("");
                mSpecifiedDeviceET.setText("");
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            showEzvizAccountLoginTv(false);
        }

        private void showEzvizAccountLoginTv(boolean show) {
            View loginTv = findViewById(R.id.tv_ezviz_account_login);
            loginTv.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
        }

    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterLoginResultReceiver();
    }

    @Override
    public void onBackPressed() {
        if (mHelper.isShowLoginAnim()) {
            showToast(getApplicationContext().getString(R.string.cancel_init_sdk));
            mHelper.showLoginAnim(false);
        } else {
            super.onBackPressed();
        }
    }
}
