package com.xplora.xpsettings.Data;

import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;

import com.xplora.xpsettings.Observer.Listener;
import com.xplora.xpsettings.RefInvoke;

import java.util.List;
import java.util.Set;

public class BtManager {
    private BluetoothManager mBluetoothManager = null;
    private BluetoothAdapter mBluetoothAdapter = null;
    private BluetoothA2dp mBluetoothA2dp = null;
    private BluetoothHeadset mBluetoothHeadset = null;

    public BtManager(Context context) {
        mBluetoothManager = (BluetoothManager)context.getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        mBluetoothAdapter.getProfileProxy(context, new BluetoothProfile.ServiceListener() {
            @Override
            public void onServiceConnected(int profile, BluetoothProfile proxy) {
                if (mBluetoothA2dp == null) {
                    mBluetoothA2dp = (BluetoothA2dp) proxy;
                }
            }
            @Override
            public void onServiceDisconnected(int profile) {
            }
        }, BluetoothProfile.A2DP);

        mBluetoothAdapter.getProfileProxy(context, new BluetoothProfile.ServiceListener() {
            @Override
            public void onServiceConnected(int profile, BluetoothProfile proxy) {
                if (mBluetoothHeadset == null) {
                    mBluetoothHeadset = (BluetoothHeadset) proxy;
                }
                Listener.BluetoothInitCompleteListener listener = (Listener.BluetoothInitCompleteListener)context;
                listener.onBluetoothInitComplete();
            }
            @Override
            public void onServiceDisconnected(int profile) {
            }
        }, BluetoothProfile.HEADSET);
    }

    public BluetoothAdapter getBluetoothAdapter() {
        return mBluetoothAdapter;
    }

    /**
     * 检查当前手机是否支持蓝牙
     * @return
     */
    public boolean isSupprotBt() {
        return mBluetoothAdapter != null;
    }

    public boolean isEnabled() {
        if (mBluetoothAdapter != null) {
            return mBluetoothAdapter.isEnabled();
        }
        return false;
    }

    public boolean setEnable(boolean isEnable) {
        boolean isChanged = false;
        if (mBluetoothAdapter != null) {
            int state = mBluetoothAdapter.getState();
            if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_TURNING_ON) { //当前开
                if (!isEnable) {
                    mBluetoothAdapter.cancelDiscovery();
                    mBluetoothAdapter.disable();
                    isChanged = true;
                }
            } else { //当前关
                if (isEnable) {
                    mBluetoothAdapter.enable();
                    isChanged = true;
                }
            }
        }
        return isChanged;
    }

    public List<BluetoothDevice> getConnectedDevices() {
        return mBluetoothManager.getConnectedDevices(BluetoothProfile.GATT);
    }

    public Set<BluetoothDevice> getBondedDevices() {
        return mBluetoothAdapter.getBondedDevices();
    }

    public BluetoothDevice getRemoteDevice(String btAddress) {
        BluetoothDevice device = null;
        if (mBluetoothAdapter != null) {
            device = mBluetoothAdapter.getRemoteDevice(btAddress);
        }
        return device;
    }

    public void startScan() {
        if (mBluetoothAdapter != null) {
            mBluetoothAdapter.startDiscovery();
        }
    }

    public void stopScan() {
        if (mBluetoothAdapter != null) {
            mBluetoothAdapter.cancelDiscovery();
        }
    }

    public void bondDevice(BluetoothDevice device) {
        if (device != null && device.getBondState() == BluetoothDevice.BOND_NONE) {
            //直接调用（api 19 以后才支持）
            device.createBond();
            /*
            //反射工具类调用
            try {
                RefInvoke.invokeMethod(BluetoothDevice.class.getName(), "createBond", device);
            } catch (Exception e) {
                if (BuildConstants.DEBUG_SWITCH) {
                    e.printStackTrace();
                }
            }
            */
        }
    }

    public void removeBondDevice(BluetoothDevice device) {
        if (device != null && device.getBondState() != BluetoothDevice.BOND_NONE) {
            //直接调用（需要源码环境）
            //device.removeBond();

            //反射工具类调用
            try {
                RefInvoke.invokeMethod(BluetoothDevice.class.getName(), "removeBond", device);
            } catch (Exception e) {
            }
        }
    }

    public int getConnectionState(BluetoothDevice device) {
        int state = BluetoothAdapter.STATE_DISCONNECTED;
        try {
            if (mBluetoothA2dp != null && doesClassMatch(device, BluetoothProfile.A2DP)) {
                state = mBluetoothA2dp.getConnectionState(device);
            }

            if (state == BluetoothAdapter.STATE_DISCONNECTED) {
                if (mBluetoothHeadset != null && doesClassMatch(device, BluetoothProfile.HEADSET)) {
                    state = mBluetoothHeadset.getConnectionState(device);
                }
            }
        } catch (Exception e) {
        }
        return state;
    }

    public void connBluetoothProfile(Context context) {
        connBluetoothProfile(context, null);
    }

    private void connBluetoothProfile(Context context, final BluetoothDevice device) {
        try {
            final BluetoothProfile.ServiceListener profileListener = new BluetoothProfile.ServiceListener() {
                public void onServiceConnected(int profile, BluetoothProfile proxy) {
                    if (profile == BluetoothProfile.HEADSET) {
                        mBluetoothHeadset = (BluetoothHeadset) proxy;
                    } else if (profile == BluetoothProfile.A2DP) {
                        mBluetoothA2dp = (BluetoothA2dp) proxy;
                    }

                    if (device != null) {
                        connectDevice(device);
                    }
                }

                public void onServiceDisconnected(int profile) {
                    if (profile == BluetoothProfile.HEADSET) {
                        mBluetoothHeadset = null;
                    } else if (profile == BluetoothProfile.A2DP) {
                        mBluetoothA2dp = null;
                    }
                }
            };

            mBluetoothAdapter.getProfileProxy(context, profileListener, BluetoothProfile.HEADSET);
            mBluetoothAdapter.getProfileProxy(context, profileListener, BluetoothProfile.A2DP);
        } catch (Exception e) {

        }
    }

    private void closeBluetoothProfile() {
        try {
            if (mBluetoothHeadset != null) {
                mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
                mBluetoothHeadset = null;
            }

            if (mBluetoothA2dp != null) {
                mBluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, mBluetoothA2dp);
                mBluetoothA2dp = null;
            }
        } catch (Exception e) {
        }
    }

    public void connectDevice(Context context, BluetoothDevice device) {
        try {
            if (mBluetoothHeadset != null && mBluetoothA2dp != null) {
                connectDevice(device);
            } else {
                connBluetoothProfile(context, device);
            }
        } catch (Exception e) {

        }
    }

    public void connectDevice(BluetoothDevice device) {
        if (device != null) {
            try {
                if (mBluetoothHeadset != null) {
                    //直接调用（需要源码环境）
                    //mBluetoothHeadset.connect(device);
                    //反射工具类调用
                    RefInvoke.invokeMethod(mBluetoothHeadset.getClass().getName(), "connect", mBluetoothHeadset, device);
                }

                if (mBluetoothA2dp != null) {
                    //直接调用（需要源码环境）
                    //mBluetoothA2dp.connect(device);
                    //反射工具类调用
                    RefInvoke.invokeMethod(mBluetoothA2dp.getClass().getName(), "connect", mBluetoothA2dp, device);
                }
            } catch (Exception e) {

            }
        }
    }

    public void disConnectDevice(BluetoothDevice device) {
        if (device != null) {
            try {
                if (mBluetoothHeadset != null && doesClassMatch(device, BluetoothProfile.HEADSET)) {
                    //直接调用（需要源码环境）
                    //mBluetoothHeadset.disconnect(device);
                    //反射工具类调用
                    RefInvoke.invokeMethod(mBluetoothHeadset.getClass().getName(), "disconnect", mBluetoothHeadset, device);
                }

                if (mBluetoothA2dp != null && doesClassMatch(device, BluetoothProfile.A2DP)) {
                    //直接调用（需要源码环境）
                    //mBluetoothA2dp.disconnect(device);
                    //反射工具类调用
                    RefInvoke.invokeMethod(mBluetoothA2dp.getClass().getName(), "disconnect", mBluetoothA2dp, device);
                }
            } catch (Exception e) {

            }
        }
    }

    public void doDestroy() {
        stopScan();
        closeBluetoothProfile();
    }

    /**
     * 判断是否支持某profile，需要源码环境
     * @param device
     * @param profile 参数只支持BluetoothProfile.A2DP，BluetoothProfile.HEADSET
     * @return
     */
    private boolean doesClassMatch(BluetoothDevice device, int profile) {
        try {
//            int deviceProfile = profile == BluetoothProfile.A2DP ? BluetoothClass.PROFILE_A2DP : BluetoothClass.PROFILE_HEADSET;
//            return device.getBluetoothClass().doesClassMatch(deviceProfile);
        } catch (Exception e) {

        }

        return true;
    }

    /**
     * 判断设备是否支持音频（耳机/音箱）
     * @param device
     * @return
     */
    public boolean isAudioDevice(BluetoothDevice device) {
        if (device == null) {
            return false;
        }

        //根据设备类型判断（根据常见的设备）
        int deviceClass = device.getBluetoothClass().getDeviceClass();
        if (deviceClass == BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET ||
            deviceClass == BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES ||
            deviceClass == BluetoothClass.Device.Major.AUDIO_VIDEO) {
            return true;
        }

        /*
        //根据设备类型判断（系统的判断更全面）
        boolean result = doesClassMatch(device, BluetoothProfile.A2DP);
        if (!result) {
            result = doesClassMatch(device, BluetoothProfile.HEADSET);
        }
        return result;
         */

        return false;
    }

}
