package com.phlx.anchorcollect.ble;

import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;


import com.hjq.toast.ToastUtils;
import com.phlx.anchorcollect.R;
import com.phlx.anchorcollect.event.EventKey;
import com.phlx.anchorcollect.event.EventMsg;
import com.phlx.anchorcollect.event.EventUtils;
import com.phlx.anchorcollect.util.ConstantUtil;

import java.util.List;

import cn.wandersnail.ble.Connection;
import cn.wandersnail.ble.Device;
import cn.wandersnail.ble.EasyBLE;
import cn.wandersnail.ble.EventObserver;
import cn.wandersnail.ble.Request;
import cn.wandersnail.ble.RequestBuilder;
import cn.wandersnail.ble.RequestBuilderFactory;
import cn.wandersnail.ble.RequestType;
import cn.wandersnail.ble.callback.MtuChangeCallback;
import cn.wandersnail.ble.callback.NotificationChangeCallback;
import cn.wandersnail.commons.observer.Observe;
import cn.wandersnail.commons.poster.RunOn;
import cn.wandersnail.commons.poster.Tag;
import cn.wandersnail.commons.poster.ThreadMode;
import me.yokeyword.fragmentation.SupportActivity;

/**
 * <pre>
 *     author : lei
 *     e-mail : 18600395998@163.com
 *     time   : 2020/06/01
 *     desc   :
 *     version: 1.0
 * </pre>
 */
public class BleDialog extends SupportActivity implements EventObserver {


    private BleManagers bleManagers;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Device device = getIntent().getParcelableExtra("device");
        setContentView(R.layout.activity_ble_connect);
        getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        getWindow().setGravity(Gravity.CENTER);
        EasyBLE.getInstance().registerObserver(this);
        bleManagers = BleManagers.from(this);
        bleManagers.connectBleDevice(device);
    }

    /**
     * 使用{@link Observe}确定要接收消息，{@link RunOn}指定在主线程执行方法，设置{@link Tag}防混淆后找不到方法
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Tag("onConnectionStateChanged")
    @Observe
    @RunOn(ThreadMode.MAIN)
    @Override
    public void onConnectionStateChanged(@NonNull Device device) {
        switch (device.getConnectionState()) {
            case SCANNING_FOR_RECONNECTION:
                break;
            case DISCONNECTED:
                finish();
                ToastUtils.show("蓝牙已断开");
                EventUtils.post(new EventMsg(EventKey.KEY_BLUETOOTH_CONNECT_FAILED, null));
                break;
            case SERVICE_DISCOVERED:
                List<BluetoothGattService> services = bleManagers.getConnection().getGatt().getServices();
                for (BluetoothGattService service : services) {
                    if (!TextUtils.isEmpty(service.getUuid().toString())) {
                        ConstantUtil.uuid_service = service.getUuid();
                        List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
                        for (BluetoothGattCharacteristic characteristic : characteristics) {
                            String characteristicType = getCharacteristicType(characteristic);
                            if (characteristicType.contains("WRITE")) {
                                ConstantUtil.uuid_write = characteristic.getUuid();
                            }
                            if (characteristicType.contains("NOTIFY")) {
                                ConstantUtil.uuid_notify = characteristic.getUuid();
                                boolean isEnabled = bleManagers.getConnection().isNotificationOrIndicationEnabled(ConstantUtil.uuid_service, ConstantUtil.uuid_notify);
                                if (!isEnabled) {
                                    setNotification(isEnabled);
                                } else {
                                    bleManagers.startBleService();
                                }
                            }
                            if (characteristicType.contains("INDICATE")) {
                                ConstantUtil.uuid_indicate = characteristic.getUuid();
                            }
                        }
                    }
                }
                //设置MTU
                Connection connection = EasyBLE.getInstance().getConnection(device);
                RequestBuilder<MtuChangeCallback> builder = new RequestBuilderFactory().getChangeMtuBuilder(512);
                Request request = builder.setCallback(new MtuChangeCallback() {
                    @Override
                    public void onMtuChanged(@NonNull Request request, int mtu) {
                        Log.e("EasyBLE", "MTU修改成功，新值：" + mtu);

                    }

                    @Override
                    public void onRequestFailed(@NonNull Request request, int failType,
                                                @Nullable Object value) {

                    }
                }).build();
                connection.execute(request);
                break;
        }
    }


    private String getCharacteristicType(BluetoothGattCharacteristic characteristic) {
        StringBuilder sb = new StringBuilder();
        int[] properties = new int[]{BluetoothGattCharacteristic.PROPERTY_WRITE,
                BluetoothGattCharacteristic.PROPERTY_INDICATE,
                BluetoothGattCharacteristic.PROPERTY_NOTIFY,
                BluetoothGattCharacteristic.PROPERTY_READ,
                BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE,
                BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE};
        String[] propertyStrs = new String[]{"WRITE", "INDICATE", "NOTIFY", "READ", "SIGNED_WRITE", "WRITE_NO_RESPONSE"};
        for (int i = 0; i < properties.length; i++) {
            int property = properties[i];
            if ((characteristic.getProperties() & property) != 0) {
                if (sb.length() != 0) {
                    sb.append(", ");
                }
                sb.append(propertyStrs[i]);
            }
        }
        return sb.toString();
    }

    private void setNotification(boolean isEnabled) {

        RequestBuilder<NotificationChangeCallback> builder =
                new RequestBuilderFactory().getSetNotificationBuilder(ConstantUtil.uuid_service,
                        ConstantUtil.uuid_notify, !isEnabled);
        builder.build().execute(bleManagers.getConnection());
    }


    @Observe
    @Override
    public void onNotificationChanged(@NonNull Request request, boolean isEnabled) {
        if (request.getType() == RequestType.SET_NOTIFICATION) {
            if (isEnabled) {
                Log.e("onNotificationChanged", "------通知开启了-----");
                bleManagers.startBleService();
                finish();
            } else {
                Log.e("onNotificationChanged", "------通知关闭了-----");
            }
        } else {
            if (isEnabled) {
                bleManagers.startBleService();
                finish();
            } else {
                Log.e("onNotificationChanged", "------Indication关闭了-----");
            }
        }
    }
}
