package com.phlx.anchorcollect.ble;

import android.app.ActivityManager;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import androidx.annotation.NonNull;


import com.phlx.anchorcollect.event.EventKey;
import com.phlx.anchorcollect.event.EventMsg;
import com.phlx.anchorcollect.event.EventUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import cn.wandersnail.ble.Connection;
import cn.wandersnail.ble.ConnectionConfiguration;
import cn.wandersnail.ble.Device;
import cn.wandersnail.ble.EasyBLE;
import cn.wandersnail.ble.RequestBuilder;
import cn.wandersnail.ble.RequestBuilderFactory;
import cn.wandersnail.ble.WriteCharacteristicBuilder;
import cn.wandersnail.ble.WriteOptions;
import cn.wandersnail.ble.callback.ReadCharacteristicCallback;
import cn.wandersnail.ble.callback.ScanListener;


/**
 * <pre>
 *     author : lei
 *     e-mail : 18600395998@163.com
 *     time   : 2019/09/03
 *     desc   :
 *     version: 1.0
 * </pre>
 */
public class BleManagers {
    private Context mContext;
    private static BleManagers bleManagers;
    private Intent bleService;//蓝牙服务声明

    public Connection getConnection() {
        return connection;
    }

    private Connection connection;
    private Map<String, String> devicesNameMap;


    /**
     * 从给定的上下文中获取btUtils
     *
     * @param context context
     * @return btUtils的一个实例
     */
    public static BleManagers from(Context context) {
        if (bleManagers == null) {
            synchronized (BleManagers.class) {
                if (bleManagers == null)
                    bleManagers = new BleManagers(context);
            }
        }
        return bleManagers;
    }

    /**
     * 唯一的构造函数
     *
     * @param context context
     */
    private BleManagers(Context context) {
        mContext = context.getApplicationContext();
        bleService = new Intent(context, BleService.class);
    }


    /**
     * 搜索设备
     *
     * @param listener 监听接口
     */
    public void searchBleDevices(OnBleSearchListener listener) {

        //扫描前，先停止上一次扫描
        cancelBLESearch();
        EasyBLE.getInstance().addScanListener(new ScanListener() {
            @Override
            public void onScanStart() {
                if (devicesNameMap == null)
                    devicesNameMap = new HashMap<>();
                devicesNameMap.clear();
                listener.onStartDiscovery();
            }

            @Override
            public void onScanStop() {
                //搜索停止
//                listener.onStartDiscovery();
            }

            @Override
            public void onScanResult(@NonNull Device device, boolean isConnectedBySys) {
                if (!devicesNameMap.containsKey(device.getAddress())) {
                    devicesNameMap.put(device.getAddress(), device.getName());
                    listener.onBleDeviceFound(device);
                }
            }

            @Override
            public void onScanError(int errorCode, @NonNull String errorMsg) {
                switch (errorCode) {
                    case ScanListener.ERROR_LACK_LOCATION_PERMISSION://缺少定位权限
                        listener.onBleError("缺少定位权限");
                        break;
                    case ScanListener.ERROR_LOCATION_SERVICE_CLOSED://位置服务未开启
                        listener.onBleError("位置服务未开启");
                        break;
                    case ScanListener.ERROR_SCAN_FAILED://搜索失败
                        listener.onBleError("搜索失败");
                        break;
                }
            }
        });
        EasyBLE.getInstance().startScan();
    }

    /**
     * 取消搜索设备
     */
    public void cancelBLESearch() {
        if (EasyBLE.getInstance().isInitialized()) {
            EasyBLE.getInstance().stopScan();
        }
    }


    /**
     * 连接蓝牙
     */
    public void connectBleDevice(Device device) {
        //连接配置，举个例随意配置两项
        ConnectionConfiguration config = new ConnectionConfiguration();
        config.setConnectTimeoutMillis(10000);
        config.setRequestTimeoutMillis(1000);
        config.setTryReconnectMaxTimes(0);
        config.setAutoReconnect(false);
        //观察者监听连接状态
        connection = EasyBLE.getInstance().connect(device, config);
    }

    /**
     * 断开一连接的蓝牙设备
     */
    public void disConnectBLE(Device device) {
        if (device != null && connection != null) {
            EasyBLE.getInstance().disconnectConnection(device);//断开指定连接
            connection = null;
        }
        //关闭蓝牙服务
        stopBleService();
        //清空已存设备地址列表
        devicesNameMap.clear();
    }

    public void writeCharacteristic(UUID uuid_service, UUID uuid_write, byte[] bytes) {
        WriteCharacteristicBuilder builder =
                new RequestBuilderFactory().getWriteCharacteristicBuilder(uuid_service,
                        uuid_write, bytes);
        //根据需要设置写入配置
        builder.setWriteOptions(new WriteOptions.Builder()
                .setPackageSize(20)
                .setPackageWriteDelayMillis(5)
                .setRequestWriteDelayMillis(10)
                .setWaitWriteResult(true)
                .setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT)
                .build());
        //不设置回调，使用观察者模式接收结果
        builder.build().execute(connection);
    }

    public void readCharacteristic(UUID uuid_service, UUID uuid_read) {
        RequestBuilder<ReadCharacteristicCallback> builder =
                new RequestBuilderFactory().getReadCharacteristicBuilder(uuid_service, uuid_read);
        builder.setTag(UUID.randomUUID().toString());
        builder.setPriority(Integer.MAX_VALUE);//设置请求优先级
        builder.build().execute(connection);
    }


    public void startBleService() {
        if (!isServiceRunning(mContext)) {
            mContext.startService(bleService);
        } else {
            EventUtils.post(new EventMsg(EventKey.KEY_BLUETOOTH_CONNECT_SUCCESS,null));
        }
    }

    public void resetBleService() {
        if (!isServiceRunning(mContext)) {
            mContext.startService(bleService);
        }
    }

    public void stopBleService() {
        if (isServiceRunning(mContext)) {
            mContext.stopService(bleService);
        }
    }

    /**
     * 判断服务是否在运行中
     *
     * @param context 即为Context对象
     * @return 是否在运行中
     */
    private boolean isServiceRunning(Context context) {
        if (context != null) {
            ActivityManager activityManager
                    = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            ArrayList<ActivityManager.RunningServiceInfo> runningServiceInfoList
                    =
                    (ArrayList<ActivityManager.RunningServiceInfo>) activityManager.getRunningServices(100);
            for (ActivityManager.RunningServiceInfo runningServiceInfo : runningServiceInfoList) {
                if ("BleService".equals(runningServiceInfo.service.getClassName())) {
                    return true;
                }
            }
        } else {
            return false;
        }
        return false;
    }
}
