package com.icod.yk_printer_test;

import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothDevice;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.icod.yk_printer_test.adapter.BluetoothAdapter;
import com.icod.yk_printer_test.model.BluetoothBean;
import com.icod.yk_printer_test.model.BluetoothInfo;
import com.szsicod.print.escpos.PrinterAPI;
import com.szsicod.print.io.BluetoothAPI;
import com.szsicod.print.log.Logger;
import com.szsicod.print.utils.BluetoothUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;

public class BluetoothActivity extends Activity implements View.OnClickListener, BluetoothAPI.BluetoothListener {
    private RelativeLayout rlTop;
    public final  static String EXTRA_ADDRESS="address";
    private Button btnSearch;
    private LinearLayout pbSearchBluetooth;
    private ExpandableListView ebList;
    private BluetoothAPI mBluetoothApi;
    private TextView tvStatus;
    private Button btnOpen;
    private static Thread runThread;
    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothBean mBleBluetoothBean;
    private boolean isConnected=false;
    private Intent intentBack;
    private void findViews() {
        rlTop = (RelativeLayout) findViewById(R.id.rl_top);
        btnSearch = (Button) findViewById(R.id.btn_search);
        btnOpen = (Button) findViewById(R.id.btn_open);
        btnOpen.setVisibility(View.GONE);
        btnOpen.setOnClickListener(this);
        pbSearchBluetooth = (LinearLayout) findViewById(R.id.pb_search_bluetooth);
        ebList = (ExpandableListView) findViewById(R.id.eb_list);
        findViewById(R.id.iv_back).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (intentBack==null||!PrinterAPI.getInstance().isConnect()) {
                    AlertDialog dialog = new AlertDialog.Builder(BluetoothActivity.this)
                            .setTitle("返回").setMessage("还没有连接你确定要返回吗 " + "?")
                            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                    finish();
                                }
                            }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                }
                            }).create();
                    dialog.show();
                }else{
                    setResult(PrinterAPI.SUCCESS,intentBack);
                    finish();
                }
            }
        });
        btnSearch.setOnClickListener(this);
        tvStatus = (TextView) findViewById(R.id.tv_status);
        // 你可以把数据存到全局变量中
        mBleBluetoothBean = new BluetoothBean();
        mBleBluetoothBean.setGroup(new String[]{"已配对", "可用的"});
        mBluetoothAdapter = new BluetoothAdapter(this, mBleBluetoothBean);
        if (PrinterAPI.getInstance().isConnect()){
            PrinterAPI.getInstance().disconnect();//重头开始
        }
        init();

    }

    private boolean isNeedInit;

    private void init() {
        mBluetoothApi = new BluetoothAPI(this.getApplicationContext());
        mBluetoothApi.setPin("0000");//我厂自动配对的;
        mBluetoothApi.setPairStrings(new String[]{"BTPrinter"});//设置自动匹配的设备名
        mBluetoothApi.setBluetoothListener(this);

        //打开蓝牙
        mBluetoothApi.openBluetooth();
        isNeedInit = false;
    }

    @Override
    public void onClick(View v) {
        if (v == btnSearch) {
            if (isNeedInit){
                init();
            }
          runThread=new Thread(new Runnable() {
              @Override
              public void run() {
                  SystemClock.sleep(500);
                  mBluetoothApi.startDiscovery();
              }
          });
      runThread.start();


        } else if (v == btnOpen) {

        }
    }

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

        ebList.setAdapter(mBluetoothAdapter);

        ebList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v, final int groupPosition, final int childPosition, long id) {
                final LinkedList<BluetoothInfo> bluetoothInfos = mBleBluetoothBean.getChild().get(groupPosition);
                if (groupPosition == 0) {

                    final BluetoothInfo info = bluetoothInfos.get
                            (childPosition);


                    AlertDialog dialog = new AlertDialog.Builder(BluetoothActivity.this)
                            .setTitle("连接打印机").setMessage("你确定要连接 :" + info.getAddress() + "?")
                            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                    runThread = new Thread(new Runnable() {
                                        @Override
                                        public void run() {
                                            //已配对的 连接
                                            Logger.i("我要去 连接");
                                            //先关闭其他连接
                                            for (BluetoothInfo other:bluetoothInfos) {
                                                if (other.isConnected()) {
                                                    if (other.getAddress().equalsIgnoreCase(info
                                                            .getAddress())) {

                                                        break;
                                                    }else{
                                                        //关闭正在连接的
                                                        PrinterAPI.getInstance().disconnect();
                                                        intentBack=null;
                                                        other.setConnected(false);
                                                        isNeedInit=true;
                                                    }
                                                }
                                            }
                                            if (!info.isConnected()) {
                                                if (isNeedInit) {
                                                    init();
                                                }
                                                String address = info.getAddress();
                                                int i = mBluetoothApi.checkDevice(address);
                                                if (i == PrinterAPI.SUCCESS) {
                                                    mBluetoothApi.cancelDiscovery();
                                                    int connect = PrinterAPI.getInstance().connect(mBluetoothApi);
                                                    if (connect == PrinterAPI.SUCCESS) {
                                                        info.setConnected(true);
                                                        intentBack = new Intent();
                                                        intentBack.putExtra(EXTRA_ADDRESS, address);
                                                        runOnUiThread(new Runnable() {
                                                            @Override
                                                            public void run() {
                                                                mBluetoothAdapter.notifyDataSetInvalidated();
                                                            }
                                                        });

                                                    }
                                                }else{
                                                    PrinterAPI.getInstance().disconnect();
                                                    isNeedInit=true;
                                                }
                                            } else {
                                                runOnUiThread(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        Toast.makeText(BluetoothActivity.this, "已经连接", Toast
                                                                .LENGTH_LONG).show();
                                                        AlertDialog dialog = new AlertDialog.Builder(BluetoothActivity.this)
                                                                .setTitle("关闭连接吗").setMessage("你确定要关闭连接 " +
                                                                        ":" + info
                                                                        .getAddress() + "?")
                                                                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                                                    @Override
                                                                    public void onClick(DialogInterface dialog, int which) {
                                                                        dialog.dismiss();
                                                                        PrinterAPI.getInstance()
                                                                                .disconnect();
                                                                        intentBack=null;
                                                                        isNeedInit = true;
                                                                        info.setConnected(false);
                                                                        mBluetoothAdapter.notifyDataSetChanged();

                                                                    }
                                                                }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                                                                    @Override
                                                                    public void onClick(DialogInterface dialog, int which) {
                                                                        dialog.dismiss();
                                                                    }
                                                                }).create();
                                                        dialog.show();
                                                    }
                                                });

                                            }
                                        }
                                    });
                                    runThread.start();
                                }
                            }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                }
                            }).create();
                    dialog.show();

                } else {
                    //未配对 去配对
                    Logger.i("我要去 配对");
                    final BluetoothInfo info = bluetoothInfos.get
                            (childPosition);

                    AlertDialog dialog = new AlertDialog.Builder(BluetoothActivity.this)
                            .setTitle("配对").setMessage("你确定配对吗 :" + info.getAddress() + "?")
                            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                    BluetoothDevice remoteDevice = android.bluetooth.BluetoothAdapter.getDefaultAdapter().getRemoteDevice(info
                                            .getAddress());
                                    boolean bond = BluetoothUtils.createBond(remoteDevice);
                                    if (bond) {
                                        runOnUiThread(new Runnable() {
                                            @Override
                                            public void run() {
                                                mBluetoothAdapter.notifyDataSetInvalidated();
                                            }
                                        });
                                    } else {
                                        runOnUiThread(new Runnable() {
                                            @Override
                                            public void run() {
                                                Toast.makeText(BluetoothActivity.this, "配对失败", Toast
                                                        .LENGTH_LONG).show();
                                            }
                                        });
                                    }
                                }
                            }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                }
                            }).create();
                    dialog.show();

                }
                return false;
            }
        });


    }

    @Override
    public void onDiscoveryStart() {
        Logger.i("开始扫瞄");
        tvStatus.setText("开始搜索");
        pbSearchBluetooth.setVisibility(View.VISIBLE);
        ebList.setVisibility(View.GONE);
        Map<Integer, LinkedList<BluetoothInfo>> child = mBleBluetoothBean.getChild();
        if (child != null) {
            LinkedList<BluetoothInfo> bluetoothInfos = child.get(0);
            LinkedList<BluetoothInfo> bluetoothInfos2 = child.get(1);
            if (bluetoothInfos != null) bluetoothInfos.clear();
            if (bluetoothInfos2 != null) bluetoothInfos2.clear();
        }


    }

    @Override
    public void onDiscoveryFinished() {
        tvStatus.setText("完成搜索");
        pbSearchBluetooth.setVisibility(View.GONE);
        ebList.setVisibility(View.VISIBLE);

        Set<BluetoothDevice> bondedDevices = android.bluetooth.BluetoothAdapter.getDefaultAdapter().getBondedDevices();
        Logger.i(Arrays.toString(bondedDevices.toArray()));
        ebList.expandGroup(0);
        ebList.expandGroup(1);
        //可以不用以下的代码,确保 能获取到匹配的
        Map<Integer, LinkedList<BluetoothInfo>> child = mBleBluetoothBean.getChild();
        if (child == null) {
            child = new HashMap<Integer, LinkedList<BluetoothInfo>>();
            mBleBluetoothBean.setChild(child);
        }

        LinkedList<BluetoothInfo> bluetoothInfos = child.get(0);
        if (bluetoothInfos == null) {
            bluetoothInfos = new LinkedList<BluetoothInfo>();
            child.put(0, bluetoothInfos);
        }



        boolean contained = false;
        HashSet<BluetoothInfo> tempData=new HashSet<>();
        for (BluetoothDevice tempInfo : bondedDevices) {
            for (BluetoothInfo info:bluetoothInfos){
            if (tempInfo.getAddress().equalsIgnoreCase(info.getAddress())) {
                Logger.i("是否相等过");
                String name = tempInfo.getName();
                if (!"null".equalsIgnoreCase(name)) {
                    info.setName(name);
                }
                contained=true;
                continue;
            }
            }
            if (!contained){
                contained=false;
                BluetoothInfo bluetoothInfo=new BluetoothInfo();
                bluetoothInfo.setAddress(tempInfo.getAddress());
                bluetoothInfo.setName(tempInfo.getName());
                bluetoothInfo.setConnected(false);
                bluetoothInfos.add(bluetoothInfo);
            }
        }
        for (BluetoothInfo data:tempData){
            bluetoothInfos.add(data);
        }
        mBluetoothAdapter.notifyDataSetChanged();
    }

    @Override
    public void onStateChanged(Intent intent) {
        Logger.i("状态");
        //当状态为关时 里面的代码已经关闭 连接 只需要操作界面即可
        int status = intent.getIntExtra(android.bluetooth.BluetoothAdapter.EXTRA_STATE, 0);
        if (status == android.bluetooth.BluetoothAdapter.STATE_OFF) {

            ebList.setVisibility(View.GONE);
            Map<Integer, LinkedList<BluetoothInfo>> child = mBleBluetoothBean.getChild();
            if (child != null) {
                LinkedList<BluetoothInfo> bluetoothInfos = child.get(0);
                LinkedList<BluetoothInfo> bluetoothInfos2 = child.get(1);
                if (bluetoothInfos != null) bluetoothInfos.clear();
                if (bluetoothInfos2 != null) bluetoothInfos2.clear();
            }
            mBluetoothAdapter.notifyDataSetChanged();
            PrinterAPI.getInstance().disconnect();
            intentBack=null;
            isNeedInit=true;
            Toast.makeText(BluetoothActivity.this,"蓝牙已经关闭", Toast.LENGTH_LONG).show();

        }
    }

    @Override
    public void onFound(BluetoothDevice device) {
        Logger.i("设备类型:"+device.getAddress() +"    :",device.getBluetoothClass()
                .getMajorDeviceClass()
                +"");
        int groupId = device.getBondState() == BluetoothDevice.BOND_BONDED ? 0 : 1;

        Map<Integer, LinkedList<BluetoothInfo>> child = mBleBluetoothBean.getChild();

        if (child == null) {

            child = new HashMap<Integer, LinkedList<BluetoothInfo>>();
            mBleBluetoothBean.setChild(child);
        }
        LinkedList<BluetoothInfo> bluetoothInfos = child.get(groupId);

        if (bluetoothInfos == null) {
            bluetoothInfos = new LinkedList<BluetoothInfo>();
            child.put(groupId, bluetoothInfos);
        }
        BluetoothInfo info = new BluetoothInfo();
        info.setConnected(BluetoothUtils.isConnected(device));
        info.setAddress(device.getAddress());
        info.setName(device.getName() + "");
        boolean contained = false;
        for (BluetoothInfo tempInfo : bluetoothInfos) {
            if (tempInfo.getAddress().equalsIgnoreCase(info.getAddress())) {
                Logger.i("是否相等过");
                String name = tempInfo.getName();
                if (!"null".equalsIgnoreCase(name)){
                    tempInfo.setName(name);
                }
                contained = true;
            }
            if ("null".equals(tempInfo.getName())){
                Logger.i("有null");
                BluetoothDevice device1 = mBluetoothApi.getDevice(tempInfo.getAddress());
               Logger.i("null:  ",device1.getName());
                tempInfo.setName(device1.getName());
            }
        }
        if (!contained) {
            info.setType(device.getBluetoothClass()
                    .getMajorDeviceClass());
            bluetoothInfos.add(info);
        }
        mBluetoothAdapter.notifyDataSetChanged();

    }

    @Override
    public void onBondStateChanged(Intent intent) {
        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, 0);
        int preBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, 0);
        int preIndex = -1;
        int index = -1;
        if (preBondState == BluetoothDevice.BOND_BONDED) {
            preIndex = 0;
            if (bondState == BluetoothDevice.BOND_NONE) {
                index = 1;
            }
        } else if (preBondState == BluetoothDevice.BOND_BONDING) {
            preIndex = 1;
            if (bondState == BluetoothDevice.BOND_BONDED) {
                index = 0;
            }
        }
        if (preIndex >= 0 && index >= 0) {
            Map<Integer, LinkedList<BluetoothInfo>> child = mBleBluetoothBean.getChild();
            if (child != null) {
                LinkedList<BluetoothInfo> bluetoothInfos = child.get(preIndex);
                if (bluetoothInfos != null) {
                    for (BluetoothInfo tempInfo : bluetoothInfos) {
                        if (tempInfo.getAddress().equalsIgnoreCase(device.getAddress())) {
                            bluetoothInfos.remove(tempInfo);
                            break;
                        }
                    }

                }
                bluetoothInfos = child.get(index);
                if (bluetoothInfos == null) {
                    bluetoothInfos = new LinkedList<BluetoothInfo>();
                    child.put(index, bluetoothInfos);
                }

                BluetoothInfo info = new BluetoothInfo();
                info.setConnected((preIndex==1&&index==0)?false: BluetoothUtils.isConnected
                        (device));
                info.setName(device.getName());
                info.setAddress(device.getAddress());
                bluetoothInfos.add(info);

            }



        } else if (preBondState == BluetoothDevice.BOND_BONDING && index < 0) {
            Toast.makeText(this, "配对失败", Toast.LENGTH_LONG).show();
        }
        mBluetoothAdapter.notifyDataSetChanged();
    }

    @Override
    public void onParingSuccess(BluetoothDevice device) {
        mBluetoothAdapter.notifyDataSetChanged();
        Logger.i(" 配对成功 ", device.getAddress());
    }

    @Override
    public void onDisconnected(BluetoothDevice device) {
        Logger.i("已经关闭",device.getAddress());
        isNeedInit=true;
        intentBack=null;
        LinkedList<BluetoothInfo> bluetoothInfos = mBleBluetoothBean.getChild().get(0);
        if (bluetoothInfos!=null){

            for (BluetoothInfo info:bluetoothInfos){
                if (info.getAddress().equals(device.getAddress())){
                    info.setConnected(false);
                }
            }
        }
        mBluetoothAdapter.notifyDataSetChanged();
    }
}
