package cgmblelib.ble;

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;

import java.util.Date;

import cgmblelib.ble.reconnectManagament.ReconnectManagement;
import cgmblelib.ble.scancallback.ManageScanCallback;
import cgmblelib.database.entity.PocDevice;
import cgmblelib.database.entity.PocGlucose;
import cgmblelib.database.repository.RepositoryDevice;
import cgmblelib.database.repository.RepositoryGlucose;
import cgmblelib.receiver.BleServiceReceiver;
import cgmblelib.utils.AxisYForGlucoseLevel;
import cgmblelib.utils.MyLog;
import cgmblelib.utils.NotificationTool;
import cgmblelib.utils.Tool;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import ist.com.sdk.AlgorithmTools;

/**
 * Created by xmin on 2016/9/1.
 * 蓝牙服务类
 *
 * @author minyuchun
 */
public class BleService extends Service {
    /**
     * 当前订阅的设备数据
     */
    private PocDevice mPocBoundDevice;
    /**
     * service 实体类
     */
    private static BleService instance = null;
    /**
     * 自定义Handle 采用弱引用
     */
    private Handler mHandler = null;
    /**
     * 绑定的广播
     */
    private BleServiceReceiver mReceiver;
    /**
     * Consumer device
     */
    private Consumer<PocDevice> consumer;

    public BleService() {
        instance = this;
    }

    /**
     * 获取服务实例
     *
     * @return 服务实例
     */
    public static BleService getInstance() {
        if (instance == null) {
            throw new NullPointerException("BleService is not bind.");
        }
        return instance;
    }

    private final IBinder mBinder = new LocalBinder();

    public class LocalBinder extends Binder {
        public LocalBinder() {
        }

        public BleService getService() {
            return BleService.this;
        }
    }

    /**
     * 开启服务，因为需要开启前台服务，所以开启方式不同
     *
     * @param context 上下文
     */
    public static void startService(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(new Intent(context, BleService.class));
        } else {
            context.startService(new Intent(context, BleService.class));
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mHandler = new Handler(Looper.getMainLooper());
        ReconnectManagement.getInstance().init(this);
        ManageScanCallback.getInstance().init(this);
        //   ManageGattCallback.getInstance().init(this);
        mReceiver = new BleServiceReceiver();
        mReceiver.initReceiver(this);
        checkDevice();
        try {
            MyLog.wLog(AlgorithmTools.getInstance().getVersion().toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        if (instance != null) {
            instance = null;
        }
        return super.onUnbind(intent);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //设置service为前台服务，提高优先级
        mHandler.postDelayed(() -> NotificationTool.getInstance().createServiceNotification(BleService.this), 100);
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        MyLog.i("Service 死亡");
        if (mReceiver != null) {
            mReceiver.unregisterReceiver(this);
        }
        // startService(getApplicationContext());
        super.onDestroy();
    }

    /***
     * 检查设备是否关闭
     */
    private void checkDevice() {
        Observable.just(true)
                .observeOn(Schedulers.io())
                .map(aBoolean -> {
                    if (aBoolean) {
                        PocDevice device = RepositoryDevice.getInstance(BleService.this).getLatestDeviceIoThread();
                        if (device != null && device.isBoundAndConnect()) {
                            PocGlucose glucose = RepositoryGlucose.getInstance(BleService.this).getLatestGlucoseByDeviceIdIoThread(device.getId());
                            Date date = new Date();
                            if (glucose != null) {
                                date = Tool.getParseDate(glucose.getFullDate());
                            }
                            return !RepositoryDevice.getInstance(BleService.this).disconnectIoThread(device, date);
                        }
                    }
                    return false;
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Boolean>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Boolean aBoolean) {
                        if (!aBoolean) {
                            ConsumerDevice();
                        } else {
                            stopSelf();
                        }
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    /**
     * 关联数据库中设备的信息
     */
    private void ConsumerDevice() {
        if (consumer == null) {
            consumer = pocDevice -> {
                if (pocDevice != null && pocDevice.isBound()) {
                    MyLog.setLocalLog(pocDevice.getId(), pocDevice.getName());
                    AxisYForGlucoseLevel.getInstance().setDevice(pocDevice);
                    if (pocDevice.isConnect()) {
                    } else {
                        BluetoothAdapter adapter = Tool.getBluetoothAdapter(this);
                        if (adapter != null && adapter.isEnabled()) {
                            if (mPocBoundDevice != null) {
                                ReconnectManagement.getInstance().reconnect(ReconnectManagement.ReconnectState.STATE_RECONNECT);
                            } else {
                                ReconnectManagement.getInstance().reconnect(ReconnectManagement.ReconnectState.STATE_APP_ON);
                            }
                        } else {
                            ReconnectManagement.getInstance().stopReconnect();
                        }
                    }
                    mPocBoundDevice = pocDevice;
                } else {
                    mPocBoundDevice = null;
                }
            };

//            SYNCHRONOUS_DATA_DEVICE_INSERT();
            RepositoryDevice.getInstance(this).getLatestFlowableDevice(consumer);
        }
    }

}
