package com.phlx.wool.ui.setting;

import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Application;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;


import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.phlx.wool.BR;
import com.phlx.wool.Configs;
import com.phlx.wool.R;
import com.phlx.wool.data.VMFactory;
import com.phlx.wool.databinding.ActivitySettingBinding;
import com.phlx.wool.net.RetrofitClient;
import com.phlx.wool.rfid.ModuleManager;
import com.phlx.wool.ui.base.BaseActivity;
import com.phlx.wool.ui.main.MainActivity;
import com.phlx.wool.ui.villus.BluetoothDeviceList;
import com.phlx.wool.util.TextUtil;
import com.printer.sdk.PrinterInstance;
import com.printer.sdk.utils.PrefUtils;
import com.printer.sdk.utils.XLog;
import com.printer.sdk.PrinterConstants.Connect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import me.goldze.mvvmhabit.utils.SPUtils;
import me.goldze.mvvmhabit.utils.ToastUtils;

/**
 * <pre>
 *     author : lei
 *     e-mail : 18600395998@163.com
 *     time   : 2019/05/23
 *     desc   :
 *     version: 1.0
 * </pre>
 */
public class SettingActivity extends BaseActivity<ActivitySettingBinding, SettingVM> {

    protected static final String TAG = "SettingActivity";

    //蓝牙
    private static BluetoothDevice mDevice;
    public static String devicesName = "未知设备";

    private static String devicesAddress;
    private BluetoothAdapter mBtAdapter;
    private IntentFilter bluDisconnectFilter;

    // 不同蓝牙链接方式的判断依据 “确认连接”
    public static int connectMains = 0;
    public static final int CONNECT_DEVICE = 1;
    private final static int SCANNIN_GREQUEST_CODE = 2;
    public static final int ENABLE_BT = 3;
    private static boolean hasRegDisconnectReceiver = false;
    private int interfaceType = 0;

    private ProgressDialog dialog;

    @Override
    public int initContentView(Bundle savedInstanceState) {
        return R.layout.activity_setting;
    }

    @Override
    public int initVariableId() {
        return BR.viewModel;
    }


    @Override
    public void initData() {

        Intent _intent = getIntent();
        int settingStatus = _intent.getIntExtra("settingStatus", 0);
        setSupportActionBar(binding.include.toolbar);
        viewModel.initToolbar(settingStatus);

        // 初始化对话框
        dialog = new ProgressDialog(this);
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.setTitle("蓝牙连接中。。。");
        dialog.setMessage("请等待。。。");
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);

        PrefUtils.setString(this, Configs.DEVICEADDRESS, devicesAddress);
        mBtAdapter = BluetoothAdapter.getDefaultAdapter();
        binding.ipAddress.setIpAddress(SPUtils.getInstance().getString(Configs.SP_APP_IP, RetrofitClient.baseUrl));
        binding.portEdit.setText(SPUtils.getInstance().getString(Configs.SP_APP_PORT, RetrofitClient.port));
        ModuleManager.openCom();
        
        initPermissions();
    }

    private void initPermissions() {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
            Log.i(TAG, "sdk < 28 Q");
            if (ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    || ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                String[] strings =
                        {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
                ActivityCompat.requestPermissions(this, strings, 1);
            }
        } else {
            if (ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    || ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    || ActivityCompat.checkSelfPermission(this,
                    "android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) {
                String[] strings = {android.Manifest.permission.ACCESS_FINE_LOCATION,
                        android.Manifest.permission.ACCESS_COARSE_LOCATION,
                        "android.permission.ACCESS_BACKGROUND_LOCATION"};
                ActivityCompat.requestPermissions(this, strings, 2);
            }
        }
    }

    @Override
    public void initViewObservable() {

        viewModel.saveIpEvent.observe(this, aBoolean -> {
            SPUtils.getInstance().put(Configs.SP_APP_IP, binding.ipAddress.getIpAddress());
            if (!TextUtil.isSpace(binding.portEdit.getText().toString())) {
                SPUtils.getInstance().put(Configs.SP_APP_PORT, binding.portEdit.getText().toString());
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //                Intent intent = getPackageManager()
            //                        .getLaunchIntentForPackage(getApplication()
            //                        .getPackageName());
            //                PendingIntent restartIntent = PendingIntent.getActivity
            //                (getApplicationContext(),
            //                        0, intent, 0);
            //                AlarmManager mgr = (AlarmManager) getSystemService(Context
            //                .ALARM_SERVICE);
            //                mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000,
            //                restartIntent); //
            //                // 1秒钟后重启应用
            //                AppManager.getAppManager().AppExit();
            VMFactory.getInstance(getApplication()).refreshRepository();
            ToastUtils.showShort("保存IP,端口成功");
        });

        //连接蓝牙
        viewModel.bluetoothEvent.observe(this, aBoolean -> {
            new MaterialDialog.Builder(this).title("系统信息").content("连接蓝牙")
                    .cancelable(false).canceledOnTouchOutside(false)
                    .positiveText("确定").onPositive(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                    if (which == DialogAction.POSITIVE) {
                        dialog.dismiss();
                        connectMains = 0;
                        // 重新连接
                        if (!(mBtAdapter == null)) {
                            // 判断设备蓝牙功能是否打开
                            if (!mBtAdapter.isEnabled()) {
                                // 打开蓝牙功能
                                Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                                startActivityForResult(enableIntent, ENABLE_BT);
                            } else {
                                // mDevice
                                devicesAddress = PrefUtils.getString(SettingActivity.this, Configs.DEVICEADDRESS, "");

                                if (devicesAddress == null || devicesAddress.length() <= 0) {
                                    Toast.makeText(SettingActivity.this, "您是第一次启动程序，请选择重新搜索连接！", Toast.LENGTH_SHORT).show();
                                } else {
                                    connect2BlueToothdevice();

                                }
                            }
                        }
                    }
                }
            }).negativeText("重新选择").onNegative(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                    if (which == DialogAction.NEGATIVE) {
                        dialog.dismiss();
                        connectMains = 1;
                        if (!(mBtAdapter == null)) {
                            // 判断设备蓝牙功能是否打开
                            if (!mBtAdapter.isEnabled()) {
                                // 打开蓝牙功能
                                Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                                startActivityForResult(enableIntent, SettingActivity.ENABLE_BT);
                            } else {
                                Intent intent = new Intent(SettingActivity.this, BluetoothDeviceList.class);
                                startActivityForResult(intent, CONNECT_DEVICE);

                            }

                        }
                    }
                }
            }).show();
        });

        viewModel.disBluetoothEvent.observe(this, aBoolean -> {
            connect2BlueToothdevice();
        });
    }

    private void connect2BlueToothdevice() {
        dialog.show();
        mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(devicesAddress);
        devicesName = mDevice.getName();
        Configs.myPrinter = PrinterInstance.getPrinterInstance(mDevice, mHandler);
        if (mDevice.getBondState() == BluetoothDevice.BOND_NONE) { // 未绑定
            // IntentFilter boundFilter = new IntentFilter();
            // boundFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
            // mContext.registerReceiver(boundDeviceReceiver, boundFilter);
            PairOrConnect(true);
        } else {
            PairOrConnect(false);
        }
    }

    private void PairOrConnect(boolean pair) {
        if (pair) {
            IntentFilter boundFilter = new IntentFilter();
            boundFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
            registerReceiver(boundDeviceReceiver, boundFilter);
            boolean success = false;
            try {
                // // 自动设置pin值
                // Method autoBondMethod =
                // BluetoothDevice.class.getMethod("setPin", new Class[] {
                // byte[].class });
                // boolean result = (Boolean) autoBondMethod.invoke(mDevice, new
                // Object[] { "1234".getBytes() });
                // Log.i(TAG, "setPin is success? : " + result);

                // 开始配对 这段代码打开输入配对密码的对话框
                Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
                success = (Boolean) createBondMethod.invoke(mDevice);
                // // 取消用户输入
                // Method cancelInputMethod =
                // BluetoothDevice.class.getMethod("cancelPairingUserInput");
                // boolean cancleResult = (Boolean)
                // cancelInputMethod.invoke(mDevice);
                // Log.i(TAG, "cancle is success? : " + cancleResult);

            } catch (IllegalAccessException e) {
                e.printStackTrace();
                Log.e(TAG, "IllegalAccessException: " + e.getMessage());
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                Log.e(TAG, "IllegalArgumentException: " + e.getMessage());
            } catch (InvocationTargetException e) {
                e.printStackTrace();
                Log.e(TAG, "InvocationTargetException: " + e.getMessage());
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
                Log.e(TAG, "NoSuchMethodException: " + e.getMessage());
            }
            Log.i(TAG, "createBond is success? : " + success);
        } else {
            new connectThread().start();

        }
    }

    private class connectThread extends Thread {
        @Override
        public void run() {
            Configs.isConnected = Configs.myPrinter.openConnection();
            Message mes = new Message();
            if (Configs.myPrinter != null && Configs.myPrinter.getCurrentStatus() == 0) {
                mes.what = Connect.SUCCESS;
                Configs.myPrinter.ringBuzzer(2);
                mes.obj = "打印机连接完毕" + Configs.myPrinter.getCurrentStatus();
            } else {
                mes.what = Connect.FAILED;
                mes.obj = "打印机异常：" + Configs.myPrinter.getCurrentStatus();
            }
            mHandler.sendMessage(mes);
        }
    }

    private BroadcastReceiver boundDeviceReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (!mDevice.equals(device)) {
                    return;
                }
                switch (device.getBondState()) {
                    case BluetoothDevice.BOND_BONDING:
                        Log.i(TAG, "bounding......");
                        break;
                    case BluetoothDevice.BOND_BONDED:
                        Log.i(TAG, "bound success");
                        // if bound success, auto init BluetoothPrinter. open
                        // connect.
                        unregisterReceiver(boundDeviceReceiver);
                        dialog.show();
                        // 配对完成开始连接
                        if (Configs.myPrinter != null) {
                            new connectThread().start();
                        }
                        break;
                    case BluetoothDevice.BOND_NONE:
                        Log.i(TAG, "执行顺序----4");
                        unregisterReceiver(boundDeviceReceiver);
                        Log.i(TAG, "bound cancel");
                        if (dialog != null && dialog.isShowing()) {
                            dialog.dismiss();
                            Toast.makeText(SettingActivity.this, "配对失败", Toast.LENGTH_LONG).show();
                        }
                        break;
                    default:
                        break;
                }

            }
        }
    };

    // 用于接受连接状态消息的 Handler
    private Handler mHandler = new Handler() {
        @SuppressLint("ShowToast")
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case Connect.SUCCESS:
                    Configs.isConnected = true;
//                    Configs.ISCONNECTED = Configs.isConnected;
                    Configs.DEVICENAME = devicesName;
                    if (interfaceType == 0) {
                        PrefUtils.setString(SettingActivity.this, Configs.DEVICEADDRESS, devicesAddress);
                        bluDisconnectFilter = new IntentFilter();
                        bluDisconnectFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
                        SettingActivity.this.registerReceiver(myReceiver, bluDisconnectFilter);
                        hasRegDisconnectReceiver = true;
                        viewModel.setBlueStatus(0);
                    }
                    finish();
                    // TOTO 暂时将TSPL指令设置参数的设置放在这
                    // if (setPrinterTSPL(myPrinter)) {
                    // if (interfaceType == 0) {
                    // Toast.makeText(mContext,
                    // R.string.settingactivitty_toast_bluetooth_set_tspl_successful,
                    // 0)
                    // .show();
                    // } else if (interfaceType == 1) {
                    // Toast.makeText(mContext,
                    // R.string.settingactivity_toast_usb_set_tspl_succefful,
                    // 0).show();
                    // }
                    // }
                    break;
                case Connect.FAILED:
                    Configs.isConnected = false;
                    Toast.makeText(SettingActivity.this, "连接失败", Toast.LENGTH_SHORT).show();
                    XLog.i(TAG, "ZL at MainActivity Handler() 连接失败!");
                    viewModel.setBlueStatus(1);
                    break;
                case Connect.CLOSED:
                    Configs.isConnected = false;
//                    Configs.ISCONNECTED = Configs.isConnected;
                    Configs.DEVICENAME = devicesName;
                    Toast.makeText(SettingActivity.this, "连接关闭", Toast.LENGTH_SHORT).show();
                    XLog.i(TAG, "ZL at MainActivity Handler() 连接关闭!");
                    viewModel.setBlueStatus(2);
                    break;
                case Connect.NODEVICE:
                    Configs.isConnected = false;
                    Toast.makeText(SettingActivity.this, "没有设备可以连接", Toast.LENGTH_SHORT).show();
                    viewModel.setBlueStatus(1);
                    break;
                default:
                    break;
            }

//            updateButtonState(Configs.isConnected);

            if (dialog != null && dialog.isShowing()) {
                dialog.dismiss();
            }
        }

    };

    public BroadcastReceiver myReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

            if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {

                if (device != null && Configs.myPrinter != null && Configs.isConnected && device.equals(mDevice)) {
                    Configs.myPrinter.closeConnection();
                    mHandler.obtainMessage(Connect.CLOSED).sendToTarget();
                }
            }

        }
    };

    @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != Activity.RESULT_OK)
            return;
        if (requestCode == CONNECT_DEVICE) {// 连接设备

            devicesAddress = data.getExtras().getString(BluetoothDeviceList.EXTRA_DEVICE_ADDRESS);
            devicesName = data.getExtras().getString(BluetoothDeviceList.EXTRA_DEVICE_NAME);
            connect2BlueToothdevice();

        }
        if (requestCode == SCANNIN_GREQUEST_CODE) {

            // 校验扫描到的mac是否合法
            devicesAddress = data.getExtras().getString(BluetoothDeviceList.EXTRA_DEVICE_ADDRESS);
            Log.i(TAG, "devicesAddress:" + devicesAddress);
            devicesAddress = TextUtil.formatTheString(devicesAddress);
            if (BluetoothAdapter.checkBluetoothAddress(devicesAddress)) {
                connect2BlueToothdevice();
            } else {
                Log.e("yxz", devicesAddress);
                Toast.makeText(this, "蓝牙mac:" + devicesAddress + "不合法", Toast.LENGTH_SHORT).show();
            }
        }
        if (requestCode == ENABLE_BT) {
            if (resultCode == Activity.RESULT_OK) {
                if (!mBtAdapter.isEnabled()) {
                    // 打开蓝牙功能
                    Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    startActivityForResult(enableIntent, ENABLE_BT);
                } else {
                    switch (connectMains) {
                        case 0:
                            // mDevice
                            devicesAddress = PrefUtils.getString(this, Configs.DEVICEADDRESS, "");
                            if (devicesAddress == null || devicesAddress.length() <= 0) {
                                Toast.makeText(SettingActivity.this, "您是第一次启动程序，请选择重新搜索连接！", Toast.LENGTH_SHORT).show();
                            } else {
                                connect2BlueToothdevice();
                            }
                            break;
                        case 1:
                            Intent intent = new Intent(this, BluetoothDeviceList.class);
                            startActivityForResult(intent, CONNECT_DEVICE);
                            break;
                    }
                }
            } else {
                Toast.makeText(SettingActivity.this, "蓝牙未启用", Toast.LENGTH_SHORT).show();
            }
        }
    }

}
