package com.handset.serialportsensor.activity;

import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import com.blankj.utilcode.util.ToastUtils;
import com.handset.serialportlib.ByteUtils;
import com.handset.serialportsensor.R;
import com.handset.serialportsensor.account.AccountManager;
import com.handset.serialportsensor.bean.RawData;
import com.handset.serialportsensor.constant.Constant;
import com.handset.serialportsensor.presenter.SurfaceContract;
import com.handset.serialportsensor.presenter.SurfacePresenter;
import com.handset.serialportsensor.utils.ToastHelper;
import com.handset.serialportsensor.utils.SPUtils;

public class LoginActivity extends BaseActivity implements SurfaceContract.ISerialView/*implements ServiceConnection, SerialService.OnReadValueCallback, SerialService.OnMateBaudRateCallback*/ {
    private static final String logTag = "HANDSET-JE002-EX";
    private static int role = Constant.SENIOR_ROLE;
    private static final int DIALOG_TIMEOUT = 30000;
    private static final int READ_TIMEOUT = 3000;

    private Boolean isReady = false;
    private Integer baudRate;
    private EditText etUserName;
    private EditText etPwd;

    private AlertDialog alertDialog;

    private SurfacePresenter mPresenter;

    private Handler mHandlerIdRead = new Handler();
    Handler mHandlerAlertDialog = new Handler();
    private Runnable mRunnableIdRead, mRunnableAlertDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ImageView ivBack = findViewById(R.id.title_back);
        findViewById(R.id.title_layout).setBackground(null);
        ivBack.setVisibility(View.VISIBLE);
        ivBack.setImageResource(R.mipmap.img_back);
        ivBack.setOnClickListener((View view) -> finish());

        etPwd = findViewById(R.id.et_pwd);
        etUserName = findViewById(R.id.et_user_name);

        findViewById(R.id.btn_login).setOnClickListener((View view) -> login());
        mPresenter = new SurfacePresenter(this);
        checkLoginStatus();
    }

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

    @Override
    protected void onStop() {
        super.onStop();
        //mHandlerAlertDialog.removeCallbacks(mRunnableAlertDialog);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //mHandlerAlertDialog.removeCallbacks(mRunnableAlertDialog);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        InputMethodManager im = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        if(im != null) {
            View view = getCurrentFocus();
            if(view != null) {
                im.hideSoftInputFromWindow(getCurrentFocus().getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
            }
        }
        return super.onTouchEvent(event);
    }

    private void login() {
        if (checkoutLoginInfo()) {
            Log.i(logTag, ("auth ok, go to setting view."));
            alertDialog = ToastHelper.showTipDialog((this), R.mipmap.img_loading, R.string.identifying);
            new Thread(
                    () -> {
                        Looper.prepare();
                        new Handler().postDelayed(() -> mPresenter.open(), (1000));
                        Looper.loop();
                    }
            ).start();

            mRunnableAlertDialog = () -> {
                Log.i(logTag, ("alertDialog force close!"));
                alertDialog.dismiss();
            };
            mHandlerAlertDialog.postDelayed(mRunnableAlertDialog, DIALOG_TIMEOUT);
        }
    }

    @Override
    public void onSerialOpen(boolean isOpen) {
        runOnUiThread(() -> {
            if (isOpen) {
                mRunnableIdRead = () -> {
                    String cmd = genCmd(("FFFFFFFF"), Constant.Command.COMMAND_25);
                    Log.e(logTag, "login activity cmd: " + cmd);
                    mPresenter.write(cmd);
                    new Thread(
                            () -> {
                                Looper.prepare();
                                new Handler().postDelayed(() -> {
                                    Log.i(logTag, ("login fetching sensor no ready: " + isReady));
                                    if (!isReady) {
                                        Log.e(logTag, ("login watch dog check, no data report!"));
                                        runOnUiThread(() -> {
                                            ToastUtils.showShort(R.string.test_id_error);
                                            if(alertDialog.isShowing()) {
                                                alertDialog.dismiss();
                                            }
                                            mHandlerAlertDialog.removeCallbacks(mRunnableAlertDialog);
                                            LoginActivity.this.finish();
                                            new Thread(
                                                    () -> {
                                                        Looper.prepare();
                                                        new Handler().post(() -> {
                                                            mPresenter.close();
                                                        });
                                                        Looper.loop();
                                                    }
                                            ).start();
                                        });
                                    } else {
                                        Log.i(logTag, ("login watch dog check, data report normally"));
                                    }
                                }, (1000));
                                Looper.loop();
                            }
                    ).start();
                    //mPresenter.write("DDDDFFFFFFFF0025003E90");
                };
                mHandlerIdRead.postDelayed(mRunnableIdRead, READ_TIMEOUT);
            } else {
                Log.i(logTag, "port is closing!");
            }
        });
    }

    @Override
    public void onSerialBaudRate(Integer baudRate) {
        this.baudRate = baudRate;
    }

    @Override
    public void onSerialData(RawData rawData) {
        if (rawData.getItemType() == RawData.TYPE_RECEIVE) {
            String data = rawData.getMessage();
            Log.i(logTag, ("LoginActivity onSerialData: " + data));
            if (data.length() == 22) {
                isReady = true;
                alertDialog.dismiss();
                mHandlerAlertDialog.removeCallbacks(mRunnableAlertDialog);
                mPresenter.close();
                boolean isRoot = AccountManager.get().getUserId().equals("root");
                boolean sensorThirdEnable = SPUtils.getInstance(this).get(("sensor_third_enable"), (false));
                boolean isOwn = isOwnSensor(data);
                Log.i(logTag, ("onSerialData: isRoot: " + isRoot + ", sensorThirdEnable: " + sensorThirdEnable + ", isOwn: " + isOwn));
                int roleType = (isRoot || sensorThirdEnable || isOwn) ? Constant.SENIOR_ROLE : Constant.NOT_CONNECTED_ROLE;
                SensorSettingsActivity.open(this.baudRate, roleType, data.substring(4, 12), (LoginActivity.this));
                LoginActivity.this.finish();
            }
        }
    }

    private boolean isOwnSensor(String data) {
        byte[] bytes = ByteUtils.hexStrToBytes(data.substring(0, data.length() - 4));
        int no = ((bytes[2] & 0xff) * 100 + (bytes[3] & 0xff)) * 10000 + ((bytes[4] & 0xff) << 8) + (bytes[5] & 0xff);
        String s = "00000000".concat(String.valueOf(no));
        String sensorNo = s.substring(s.length() - 8);
        Log.i(logTag, ("isThirdSensor: " + sensorNo + ", position[4]: " + sensorNo.charAt(4)));

        return sensorNo.charAt(4) == '1';
    }

    @Override
    public void onSerialError(Integer errorCode) {
        runOnUiThread(() -> {
            ToastUtils.showShort(R.string.test_btl_error);
            mPresenter.close();
            alertDialog.dismiss();
            LoginActivity.this.finish();
        });
    }


    private void checkLoginStatus() {
        if (AccountManager.get().isLogin()) {
            login();
        }
    }

    private boolean checkoutLoginInfo() {
        if (AccountManager.get().isLogin()) {
            return true;
        }
        String pwd = etPwd.getText().toString();
        String username = etUserName.getText().toString();
        if (TextUtils.isEmpty(username)) {
            Toast.makeText((this), "登录失败，用户名为空", Toast.LENGTH_SHORT).show();
            return false;
        }
        if (TextUtils.isEmpty(pwd)) {
            Toast.makeText((this), "登录失败，密码为空", Toast.LENGTH_SHORT).show();
            return false;
        }

        String pwdSp = SPUtils.getInstance(this).get(username);
        Log.i(logTag, "pwdSp: " + pwdSp + ", username: " + username);
        if (TextUtils.isEmpty(pwdSp)) {
            if ("root".equals(username) && "root".equals(pwd)) {
                Toast.makeText((this), "root 登录成功", Toast.LENGTH_SHORT).show();
                AccountManager.get().login("root", "root");
                return true;
            }
            if ("admin".equals(username) && "admin".equals(pwd)) {
                AccountManager.get().login("admin", "admin");
                Toast.makeText((this), "admin 登录成功", Toast.LENGTH_SHORT).show();
                return true;
            }
        } else {
            if (pwdSp.equals(pwd)) {
                AccountManager.get().login(username, pwdSp);
                Toast.makeText((this), username + " 登录成功", Toast.LENGTH_SHORT).show();
                return true;
            }
        }
        Toast.makeText((this), "登录失败，用户名或密码错误", Toast.LENGTH_SHORT).show();
        return false;
    }
}
