package com.pavle.patternswitch.activities;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import com.pavle.patternswitch.R;
import com.pavle.patternswitch.adapter.PatternAdapter;
import com.pavle.patternswitch.bluetooth.BleWrapper;
import com.pavle.patternswitch.bluetooth.BleWrapperCallbacks;
import com.pavle.patternswitch.bluetooth.BleWrapperProxy;
import com.pavle.patternswitch.db.DBHelperPattern;
import com.pavle.patternswitch.objects.Device;
import com.pavle.patternswitch.objects.Pattern;
import com.pavle.patternswitch.objects.Trigger;


import java.util.ArrayList;


public class PatternPreviewActivity extends Activity implements BleWrapperCallbacks {

    private final static int REQUEST_ENABLE_BT = 1;
    private static final long SCANNING_TIMEOUT = 3 * 1000; /* 3 seconds */

    private Context mContext;
    private BleWrapper BleWrapper = null;
    private ArrayList<Device> mDeviceList;
    private Handler mHandler;
    private ArrayList<Pattern> mPatternList;
    private ArrayList<BleWrapperProxy> mBleProxyList = null;

    private boolean mScanning;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pattern_preview);

        mContext = this;
        mDeviceList = new ArrayList<>();
        mBleProxyList = new ArrayList<>();
        mHandler = new Handler();

        Button btnAdd = (Button) findViewById(R.id.btnAddPattern);
        btnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(PatternPreviewActivity.this, CreateActivity.class);
                startActivity(i);
            }
        });

    }

    private void bleMissing() {
        Toast.makeText(this, "BLE Not supported", Toast.LENGTH_SHORT).show();
        finish();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if(BleWrapper == null) BleWrapper = new BleWrapper(this, this);

        if (BleWrapper.checkAvailableHardware() == false) {
            bleMissing();
        }

        // on every Resume check if BT is enabled (user could turn it off while app was in background etc.)
        if(BleWrapper.isBtEnabled() == false) {
            // BT is not turned on - ask user to make it enabled
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            // see onActivityResult to check what is the status of our request
        }

        if(BleWrapper.initialize() == false) {
            finish();
        }

        // Automatically start scanning for devices
        mScanning = true;
        // remember to add timeout for scanning to not run it forever and drain the battery
        addScanningTimeout();
        BleWrapper.startScanning();

        loadPatternsAndDisplayThem();
    }

    private void loadPatternsAndDisplayThem() {

        /*Load db and read all saved patterns from it*/
        mPatternList = getListOfPatterns();

        /*Display those patterns in the ListView*/
        ListView lvPatterns = (ListView) findViewById(R.id.lvPreviewPattern);
        loadPatternsToListView(lvPatterns, mPatternList);
    }

    private ArrayList<Pattern> getListOfPatterns() {
        ArrayList<Pattern> patternList = new ArrayList<>();
        DBHelperPattern db = new DBHelperPattern(mContext.getApplicationContext());
        int numberOfPatterns  = db.getNumberOfPatterns();
        for(int i = 0,k=0; i < numberOfPatterns ; k++){
            DBHelperPattern dbP = new DBHelperPattern(mContext.getApplicationContext());
            Pattern tmp = dbP.getPattern(k);
                    if(tmp != null){
                        tmp.setDeviceList(mDeviceList);
                        i++;
                        patternList.add(tmp);
                    }
        }
        return  patternList;
    }

    private void loadPatternsToListView(final ListView lvPatterns, final ArrayList<Pattern> list) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                lvPatterns.setAdapter(new PatternAdapter(mContext, R.layout.list_item, list));
            }
        });
    }

    @Override
    protected void onPause() {
        super.onPause();

        mScanning = false;
        BleWrapper.stopScanning();
        mDeviceList.clear();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mScanning = false;
        BleWrapper.stopScanning();
        mDeviceList.clear();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }


    /* make sure that potential scanning will take no longer
   * than <SCANNING_TIMEOUT> seconds from now on */
    private void addScanningTimeout() {
        Runnable timeout = new Runnable() {
            @Override
            public void run() {
                if (BleWrapper == null) return;
                mScanning = false;
                BleWrapper.stopScanning();
            }
        };
        mHandler.postDelayed(timeout, SCANNING_TIMEOUT);
    }

    public void startMonitoringPattern(Pattern p){
            mScanning = true;
            BleWrapper.startScanning();

            p.setChecked(true);
            for(Trigger t:p.getTriggerList()){
                BleWrapperProxy tmp = new BleWrapperProxy(this,t,mDeviceList,p);
                Thread thread = new Thread(tmp);
                thread.start();
                mBleProxyList.add(tmp);
            }
    }

    public void stopMonitoringPattern(Pattern p) {
        p.setChecked(false);
        for(BleWrapperProxy proxy:mBleProxyList){
            proxy.stop();
        }
        for(Pattern pattern:mPatternList){
            if(pattern.isChecked()){
                return;
            }
        }
        mScanning = false;
        BleWrapper.stopScanning();
    }

    private Device newlyDiscovered;

    @Override
    public void uiDeviceFound(BluetoothDevice device, int rssi, byte[] record) {
        if (mDeviceList.contains(device) == false && mDeviceList != null && device.getName().contains("RTRK")) {
            for(Device d:mDeviceList){
                if(d.getDevice().getName().equals(device.getName())) return;
            }
            newlyDiscovered = new Device(device, rssi, record);
            mDeviceList.add(newlyDiscovered);
            updatePatternDeviceList();
        }
    }

    private void updatePatternDeviceList() {
        for(Pattern p:mPatternList){
            p.setDeviceList(mDeviceList);
            if(p.isChecked()){
                for(Trigger t:p.getTriggerList()){
                    if(t.getTriggerDeviceName().equals(newlyDiscovered.getDevice().getName())){
                        BleWrapperProxy proxy = new BleWrapperProxy(this,t,mDeviceList,p);
                        Thread thread = new Thread(proxy);
                        thread.start();
                        mBleProxyList.add(proxy);
                    }
                }
            }
        }
    }

    @Override
    public void uiDeviceConnected() {
    }

    @Override
    public void uiDeviceDisconnected() {

    }

    @Override
    public void uiAvailableServices(boolean success) {

    }

    @Override
    public void uiCharacteristicsForServices(boolean success) {

    }

    @Override
    public void uiNotificationsSet(boolean success) {

    }



    @Override
    public void uiNewRssiAvailable(BluetoothGatt gatt, BluetoothDevice device, int rssi) {

    }

    @Override
    public void uiNewValueForCharacteristic(BluetoothGatt gatt, BluetoothDevice device, BluetoothGattService service, BluetoothGattCharacteristic ch, String strValue, int intValue, byte[] rawValue, String timestamp) {

    }

    @Override
    public void uiGotNotification(BluetoothGatt gatt, BluetoothDevice device, BluetoothGattService service, BluetoothGattCharacteristic characteristic) {

    }

    @Override
    public void uiSuccessfulWrite(BluetoothGatt gatt, BluetoothDevice device, BluetoothGattService service, BluetoothGattCharacteristic ch, String description) {

    }

    @Override
    public void uiFailedWrite(BluetoothGatt gatt, BluetoothDevice device, BluetoothGattService service, BluetoothGattCharacteristic ch, String description) {

    }

    public void createHandler(final BleWrapper wrapper) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                wrapper.createHandler();
            }
        });

    }
}
