package com.yanzhenjie.andserver.sample.controller;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.le.BluetoothLeScanner;
import android.os.Build;
import android.util.Log;

import androidx.annotation.RequiresApi;

import com.yanzhenjie.andserver.annotation.GetMapping;
import com.yanzhenjie.andserver.annotation.PathVariable;
import com.yanzhenjie.andserver.annotation.PostMapping;
import com.yanzhenjie.andserver.annotation.RequestMapping;
import com.yanzhenjie.andserver.annotation.RequestParam;
import com.yanzhenjie.andserver.annotation.RestController;
import com.yanzhenjie.andserver.sample.MainActivity;
import com.yanzhenjie.andserver.sample.model.ScannedDevice;
import com.yanzhenjie.andserver.sample.util.Constant;
import com.yanzhenjie.andserver.sample.util.Result;
import com.yanzhenjie.andserver.util.MediaType;

import org.apache.commons.lang3.StringUtils;

import java.util.Collection;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.validation.Valid;

import io.mega.megablelib.MegaAdvParse;
import io.mega.megablelib.MegaBleBuilder;
import io.mega.megablelib.MegaBleCallback;
import io.mega.megablelib.MegaBleClient;
import io.mega.megablelib.model.MegaBleDevice;
import io.mega.megablelib.model.bean.MegaAdvOnly;
import io.mega.megablelib.model.bean.MegaAdvertisingParsedEntity;
import io.reactivex.Observable;

// Created by Develoven on 2023/4/23.
// Copyright (c) 2023 redflow. All rights reserved.
//
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@RestController
@RequestMapping("/common")
public class CommonController extends BaseController{

    private static final String TAG = "CommonController";
    private final Long  SCAN_PERIOD = 5L;

    private static BluetoothAdapter mBluetoothAdapter;
    private static BluetoothLeScanner mScanner = null;
    //    private static BluetoothAdapter.LeScanCallback mLeScanCallback ;
    private static HashMap<String,ScannedDevice> scannedDeviceList = new HashMap<>();
    static {
//        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        mBluetoothAdapter = MainActivity.mBluetoothAdapter;
        if(mBluetoothAdapter == null){
            Log.e(TAG,"current device not support bluetooth");
            throw new RuntimeException("current device not support bluetooth");
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mScanner = mBluetoothAdapter.getBluetoothLeScanner();
        }

    }

    /**
     * open blue tooth :http://192.168.137.168:8080/common/open/bluetooth
     * @return
     */
    @GetMapping(value = "/open/bluetooth",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result openBluetooth(){

        //1.open bluetooth
        if (mBluetoothAdapter == null) {
            Log.e(TAG, "--------------- current device not support bluetooth ");
            return fail(null,"current device not support bluetooth");
        }
        if ( !mBluetoothAdapter.isEnabled()) {
            boolean res = mBluetoothAdapter.enable();
            if (!res) {
                Log.e(TAG, "--------------- bluetooth open failed ");
                return fail(null,"bluetooth open failed");
            }
        } else if (mBluetoothAdapter.isEnabled()) {
            Log.e(TAG, "--------------- bluetooth open success");
            return fail(null,"bluetooth open success");
        }
        return success(null,"bluetooth open success");

    }
    /**
     * close bluetooth : http://192.168.137.168:8080/common/close/bluetooth
     * @return
     */
    @GetMapping(value = "/close/bluetooth",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result closeBluetooth(){
        //1.close bluetooth
        if (mBluetoothAdapter == null) {
            Log.e(TAG, "--------------- current device not support bluetooth ");
            return fail(null,"current device not support bluetooth");
        }
        if ( mBluetoothAdapter.isEnabled()) {
            boolean res = mBluetoothAdapter.disable();
            if (!res) {
                Log.e(TAG, "--------------- bluetooth close failed ");
                return fail(null,"bluetooth close failed");
            }
        } else if (!mBluetoothAdapter.isEnabled()) {
            Log.e(TAG, "--------------- bluetooth close success");
            return fail(null,"bluetooth close success");
        }
        return success(null,"bluetooth close success");
    }

    /**
     * check bluetooth status : http://192.168.137.168:8080/common/status/bluetooth
     * @return
     */

    @GetMapping(value = "/status/bluetooth",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result checkBluetoothStatus(){
        if (mBluetoothAdapter == null) {
            Log.e(TAG, "--------------- current device not support bluetooth ");
            return fail(null,"current device not support bluetooth");
        }else {
            return success(mBluetoothAdapter.isEnabled());
        }
    }
    /**
     * scan device by model
     * model = PULSE|ECG
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    @GetMapping(value = "/scan/device/{model}",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result<Collection<ScannedDevice>> scanDevice(@PathVariable("model") String model) throws InterruptedException {
        AtomicBoolean scanStatus = new AtomicBoolean(true);
        BluetoothAdapter.LeScanCallback mLeScanCallback = (device, rssi, scanRecord) -> {
            try{
                Log.d(TAG+"LeScan","device:{"+device.getName()+"  "+rssi+"   "+scanRecord);
                if(StringUtils.isEmpty(device.getName())) {
                    return;
                }
                if (!device.getName().toLowerCase().contains("ring")) return;
                if(scanRecord.length < 62) return;
                // parse 3rd ring
                MegaAdvOnly advOnly = MegaAdvParse.parse(scanRecord);
                //parse 2nd ring
                if(advOnly == null){
                    MegaAdvertisingParsedEntity advEntity = MegaBleClient.parseScanRecord(device, scanRecord);
                    if(advEntity != null){
                        Log.d(TAG,advEntity.toString());
                    }
                }else {
                    Log.d(TAG,advOnly.toString());
                }
                ScannedDevice scannedDevice = new ScannedDevice(device.getName(), device.getAddress(), rssi);
                Log.d(TAG, "device: "+scannedDevice);
                /*int index = scannedDeviceList.indexOf(scannedDevice);
                if(index == -1){
                    scannedDeviceList.add(scannedDevice);
                }else {
                    scannedDeviceList.add(index,scannedDevice);
                }*/
                scannedDeviceList.put(scannedDevice.getAddress(),scannedDevice);
            }catch (Exception e ){
                Log.d(TAG,e.getMessage());
                e.printStackTrace();
            }
        };
        switch (model){

            case Constant.MODEL_ECG:

                break ;
            case Constant.MODEL_PULSE:
                Log.d(TAG,"model=PULSE");
                //scan PULSE device
                Log.d(TAG,"size---"+scannedDeviceList.size());
                if(scannedDeviceList.size()>0){
                    scannedDeviceList.clear();
                }
                Log.d(TAG,"size---"+scannedDeviceList.size());
                //scan ecg device
                Observable.timer(SCAN_PERIOD,TimeUnit.SECONDS).subscribe( aLong -> {
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    scanStatus.set(false);
                    Log.d(TAG,"scannedDeviceList.size---"+scannedDeviceList.size());
                });
                Log.d(TAG,"mLeScanCallback---"+mLeScanCallback);
                Log.d(TAG,"mBluetoothAdapter---"+mBluetoothAdapter);
                Log.i(TAG,"开始扫描");
                mBluetoothAdapter.startLeScan(mLeScanCallback);
/*                Observable.interval(1,TimeUnit.SECONDS).take(SCAN_PERIOD).observeOn(AndroidSchedulers.mainThread()).subscribe(aLong ->{
                    Log.d(TAG,aLong.toString()+"scanning...");

                });*/
                break;
        }
        while (scanStatus.get()){
            Thread.sleep(1000);
            Log.i(TAG,"等待");
        }
        return success(scannedDeviceList.values());
    }

    /**
     * connect bluetooth
     * @return
     */
    @PostMapping(value = "/connect/bluetooth",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result connectBluetooth(@Valid @RequestParam(name = "mac") String mac,@Valid @RequestParam(name = "name") String name){
        Log.i(TAG,mac);
        MegaBleCallback megaBleCallback = new MegaBleCallback() {
            @Override
            public void onConnectionStateChange(boolean connected, MegaBleDevice device) {
                super.onConnectionStateChange(connected, device);
                //状态变更 ：通知前台服务
                if(connected){

                }
            }
        };
        // mock id, key，use yours
        MegaBleBuilder builder = new MegaBleBuilder();
        MegaBleClient megaBleClient = builder
                .withSecretId("D4CE5DD515F81247")
                .withSecretKey("uedQ2MgVEFlsGIWSgofHYHNdZSyHmmJ5")
                .withCallback(megaBleCallback)
                .build();
        // 开发测试时，可以开启debug
        megaBleClient.setDebugEnable(true);
        megaBleClient.connect(mac, name);
        return success();
    }


 /*   //初始化蓝牙广播
    private void initBroadcast(){
        broadcastReceiver = new CustomBroadcastReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); //开始扫描
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//扫描结束
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);//搜索到设备
        intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); //配对状态监听
        registerReceiver(broadcastReceiver,intentFilter);
    }*/


}
