package ai.pai.lensman.printer;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import com.android.common.utils.LogHelper;
import com.gprinter.aidl.GpService;
import com.gprinter.command.GpCom;
import com.gprinter.io.GpDevice;
import com.gprinter.io.PortParameters;
import com.gprinter.service.GpPrintService;

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

import ai.pai.lensman.App;
import ai.pai.lensman.R;

/**
 * Created by chengzhenyu on 2016/9/1.
 */

public class PrinterSettingPresenter implements PrinterSettingContract.Presenter {

    private Context context;
    private PrinterSettingContract.View view;
    private  BluetoothAdapter bluetoothAdapter;

    private GpService mGpService;
    private PrinterServiceConnection conn = null;

    class PrinterServiceConnection implements ServiceConnection {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i("czy", "onServiceDisconnected() called");
            mGpService = null;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i("czy", "onServiceConnected() called");
            mGpService = GpService.Stub.asInterface(service);
        }
    }


    public PrinterSettingPresenter(Context context, PrinterSettingContract.View view){
        this.view = view;
        this.context = context;
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    }

    @Override
    public void start() {
        registerPrinterBroadcast();
        startAndBindPrintService();
        if(queryBluetoothStatus()){
            view.onBluetoothEnabled();
            view.onPairedDeviceDiscovered(queryPairedDevices());
            view.showToast(context.getString(R.string.query_processing));
            discoverNewDevices();

        }else{
            view.onBluetoothDisabled();
            view.showToast(context.getString(R.string.bt_is_disabled));
        }
    }

    @Override
    public void stop() {
        cancelDiscovery();
        if (conn != null) {
            App.getAppContext().unbindService(conn);
        }
        context.unregisterReceiver(PrinterStatusBroadcastReceiver);
    }

    @Override
    public void queryPrinterStatus() {
        try {

            int status = mGpService.queryPrinterStatus(0, 5000);
            String str = new String();
            if (status == GpCom.STATE_NO_ERR) {
                str = "打印机正常";
            } else {
                str = "打印机 ";
                if ((byte) (status & GpCom.STATE_OFFLINE) > 0) {
                    str += "脱机";
                }
                if ((byte) (status & GpCom.STATE_PAPER_ERR) > 0) {
                    str += "缺纸";
                }
                if ((byte) (status & GpCom.STATE_COVER_OPEN) > 0) {
                    str += "打印机开盖";
                }
                if ((byte) (status & GpCom.STATE_ERR_OCCURS) > 0) {
                    str += "打印机出错";
                }
                if ((byte) (status & GpCom.STATE_TIMES_OUT) > 0) {
                    str += "查询超时";
                }
            }
            view.showToast( "打印机："  + " 状态：" + str);
            view.onPrinterError(str);

        } catch (RemoteException e1) {
            e1.printStackTrace();
        }
    }

    @Override
    public void printTestPage() {
        try {
            int rel = mGpService.printeTestPage(0); //
            Log.i("ServiceConnection", "rel " + rel);
            GpCom.ERROR_CODE r = GpCom.ERROR_CODE.values()[rel];
            if (r != GpCom.ERROR_CODE.SUCCESS) {
                view.showToast( GpCom.getErrorText(r));
            }
        } catch (RemoteException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }

    @Override
    public boolean queryBluetoothStatus() {
        if(bluetoothAdapter==null){
            return false;
        }
        return bluetoothAdapter.isEnabled();
    }

    @Override
    public List<BluetoothDevice> queryPairedDevices() {
        ArrayList<BluetoothDevice> pairedDevices = new ArrayList<>();
        Set<BluetoothDevice> deviceSet = bluetoothAdapter.getBondedDevices();
        for(BluetoothDevice device: deviceSet){
            pairedDevices.add(device);
        }
        return pairedDevices;

    }

    @Override
    public void discoverNewDevices() {
        // Register for broadcasts when a device is discovered
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        context.registerReceiver(mFindBlueToothReceiver, filter);
        // Register for broadcasts when discovery has finished
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        context.registerReceiver(mFindBlueToothReceiver, filter);
        bluetoothAdapter.startDiscovery();
    }

    @Override
    public void connectPrinter(BluetoothDevice device) {
        try {
            int code = mGpService.openPort(0, PortParameters.BLUETOOTH, device.getAddress(), 0);
            LogHelper.d("czy","open port return code ="+code);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void cancelDiscovery() {
        try{
            bluetoothAdapter.cancelDiscovery();
            context.unregisterReceiver(mFindBlueToothReceiver);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void startAndBindPrintService() {
        Intent intent = new Intent(App.getAppContext(), GpPrintService.class);
        App.getAppContext().startService(intent);
        conn = new PrinterServiceConnection();
        App.getAppContext().bindService(intent, conn, Context.BIND_AUTO_CREATE);
    }

    // changes the title when discovery is finished
    private final BroadcastReceiver mFindBlueToothReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            // When discovery finds a device
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                // Get the BluetoothDevice object from the Intent
                BluetoothDevice device = intent
                        .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // If it's already paired, skip it, because it's been listed
                // already
                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                    view.onNewDeviceDiscovered(device);
                }
                // When discovery is finished, change the Activity title
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED
                    .equals(action)) {
                view.showToast(context.getString(R.string.bt_discover_complete));
            }
        }
    };

    private void registerPrinterBroadcast() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(GpCom.ACTION_CONNECT_STATUS);
        context.registerReceiver(PrinterStatusBroadcastReceiver, filter);
    }

    private BroadcastReceiver PrinterStatusBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (GpCom.ACTION_CONNECT_STATUS.equals(intent.getAction())) {
                int type = intent.getIntExtra(GpPrintService.CONNECT_STATUS, 0);
                int id = intent.getIntExtra(GpPrintService.PRINTER_ID, 0);
                Log.d("czy", "connect status " + type);
                if (type == GpDevice.STATE_CONNECTING) {

                } else if (type == GpDevice.STATE_NONE) {

                } else if (type == GpDevice.STATE_VALID_PRINTER) {

                } else if (type == GpDevice.STATE_INVALID_PRINTER) {

                }
            }
        }
    };

}
