package cn.joyway.joywaybeacon;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.List;

import cn.joyway.lib.ConvertEx;
import cn.joyway.lib.JoywayLib;
import cn.joyway.lib.UpdateManager;
import cn.joyway.lib.bluetooth.BT;
import cn.joyway.lib.bluetooth.Beacon;
import cn.joyway.lib.bluetooth.OnBeaconEventHandler;
import cn.joyway.lib.bluetooth.BeaconConnectStatus;
import cn.joyway.lib.bluetooth.BeaconScanEvent;
import cn.joyway.lib.util.PermissionHelper;
import cn.joyway.lib.util.StringHelper;

public class Activity_Main extends AppCompatActivity implements OnBeaconEventHandler {

    private static Activity_Main _instance;
    protected static Activity_Main getInstance() {
        return _instance;
    }

    UpdateManager _updateMgr;
    TextView _tvDeviceCount;
    Button _bnScan;
    Button _bnClear;
    Button _bnDFU;
    Button _bnCopyAllMacs;
    EditText _etNameFilterValue;
    CheckBox _cbNameFilterNoName;
    TextView _tvRssiFilterValue;
    SeekBar _sbRssiFilterSeekBar;
    ListView _lvDeviceList;
    Adapter_DeviceList _deviceListAdapter;
    boolean _isScanning = false;
    int _rssiFilter = -120;
    String _nameFilter = null;

    //Timer _timerUpdateUI = new Timer();

    void stopScan() {
        BT.setScanTimeLength(0);
        _isScanning = false;
        _bnScan.setText(getString(R.string.scan));
    }

    void startScan() {
        BT.setScanTimeLength(-1);
        _isScanning = true;
        _bnScan.setText(getString(R.string.stop));
    }

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

        _instance = this;

        JoywayLib.init("GET KEY FROM JOYWAY SALES", this, this);
        BT.init(10*1000, //杩炰笂鐨勮澶囷紝10绉掑埛鏂颁竴涓猺ssi
                5*60*1000); //5鍒嗛挓鎵弿涓嶅埌锛屽氨瑕佷粠鍒楄〃涓幓鎺?
        BT.setScanWindowAndInterval(5000, 1000);
        BT.listenBeaconEvent(this, true);

        _tvDeviceCount = findViewById(R.id.tv_device_count_value);
        _bnScan = findViewById(R.id.bn_scan);
        _bnClear = findViewById(R.id.bn_clear);
        _bnDFU = findViewById(R.id.bn_dfu);
        _bnCopyAllMacs = findViewById(R.id.bn_copy_all_macs);
        _etNameFilterValue = findViewById(R.id.et_name_filter_value);
        _cbNameFilterNoName = findViewById(R.id.cb_name_filter_no_name);
        _tvRssiFilterValue = findViewById(R.id.tv_rssi_filter_value);
        _sbRssiFilterSeekBar = findViewById(R.id.sb_rssi_filter_seekbar);
        _lvDeviceList = findViewById(R.id.lv_device_list);
        _deviceListAdapter = new Adapter_DeviceList(this, this);
        _lvDeviceList.setAdapter(_deviceListAdapter);

        _etNameFilterValue.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                _nameFilter = _etNameFilterValue.getText().toString().toLowerCase();
            }
        });
        _tvRssiFilterValue.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                _rssiFilter = Integer.parseInt(_tvRssiFilterValue.getText().toString().trim());
            }
        });
        _sbRssiFilterSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                int rssiFilter = -progress;
                _tvRssiFilterValue.setText(String.valueOf(rssiFilter));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        _bnScan.setOnClickListener(v -> {
            //鎵弿涔嬪墠蹇呴』鍐嶆纭鏈?鏂扮殑杩囨护鏉′欢
            _nameFilter = _etNameFilterValue.getText().toString().toLowerCase();
            _rssiFilter = Integer.parseInt(_tvRssiFilterValue.getText().toString().trim());

            if (!_isScanning) {
                startScan();
            } else {
                stopScan();
            }
        });

        _bnClear.setOnClickListener(v -> {
            updateUI_for_deviceList_and_deviceCountLabel_inMainThread(DeviceListAction.clear, null);

            BT.clearScannedButDisconnectedBeacons();//涓轰簡璁╁箍鎾棿闅斿?煎浣?
        });

        _bnDFU.setOnClickListener(v -> {
            stopScan();//蹇呴』鍏堝仠姝㈡壂鎻忥紝鍚﹀垯dfu绐楀彛閲屼細鑷姩寮?濮嬪崌绾?
            //Intent intent = new Intent(Activity_Main.this, Activity_DFU.class);
            //Activity_Main.this.startActivity(intent);
        });

        _bnCopyAllMacs.setOnClickListener(v -> {
            try {
                String path = Activity_Main.this.getExternalFilesDir(null).getPath() + "/Mac.txt";
                File file = new File(path);
                //if (!file.exists())
                //    file.createNewFile();
                if (true) {
                    FileOutputStream fos = new FileOutputStream(file);
                    OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
                    BufferedWriter writer = new BufferedWriter(osw);
                    writer.write(ConvertEx.StringList_to_String(_deviceListAdapter._deviceMacs, ", "));
                    Toast.makeText(Activity_Main.this,
                            "Mac鍦板潃宸茬粡鍐欏叆鍒版枃浠禡ac.txt閲岋紝鍙互閫氳繃QQ浼犺緭杩欎釜鏂囦欢",
                            Toast.LENGTH_LONG).show();
                    Toast.makeText(Activity_Main.this,
                            "鏂囦欢璺緞锛?" + path,
                            Toast.LENGTH_LONG).show();
                    writer.close();
                    osw.close();
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        _cbNameFilterNoName.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                _etNameFilterValue.setEnabled(!isChecked);
            }
        });

        //鏍规嵁鎺т欢鐨勫垵濮嬪?兼潵鍒濆鍖栧唴瀛樺彉閲?
        int rssiFilter = -(_sbRssiFilterSeekBar.getProgress());
        _tvRssiFilterValue.setText(String.valueOf(rssiFilter));
        //鏍规嵁鎺т欢鐨勫垵濮嬪?兼潵鍒濆鍖栧唴瀛樺彉閲?
        _nameFilter = _etNameFilterValue.getText().toString().toLowerCase();

        /** 閫氳繃timer瀹氭椂鍣紝瀹炵幇1绉掑埛鏂颁竴娆I
        _timerUpdateUI.schedule(new TimerTask() {
            @Override
            public void run() {
                updateUI_for_deviceList_and_deviceCountLabel_inMainThread();
            }
        }, 0, 1000);*/

        /** 璋冭瘯妯″紡锛屽彲浠ラ鍏堣緭鍏ュ悕绉帮紝鎻愰珮璋冭瘯鏁堢巼 */
        if (JoywayLib.DEBUG) {
            //_etNameFilterValue.setText("JW1602G4V5");
        }

    }

    private String[] ALL_PERMISSIONS() {

        final String[] permissions;

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            permissions = new String[]{
                    Manifest.permission.BLUETOOTH,
                    Manifest.permission.BLUETOOTH_ADMIN,

                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION,

                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.READ_EXTERNAL_STORAGE,

                    //Manifest.permission.INTERNET,涓嶉渶瑕佸姩鎬佺敵璇?

                    //Manifest.permission.CAMERA,
                    //Manifest.permission.SEND_SMS,
            };
        }
        else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
            permissions = new String[]{
                    Manifest.permission.BLUETOOTH,
                    Manifest.permission.BLUETOOTH_ADMIN,

                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION,

                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.READ_EXTERNAL_STORAGE,

                    //Manifest.permission.INTERNET,涓嶉渶瑕佸姩鎬佺敵璇?

                    //Manifest.permission.CAMERA,

                    //Manifest.permission.SEND_SMS,

                    //Manifest.permission.REQUEST_INSTALL_PACKAGES,
            };
        }
        else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
            permissions = new String[]{
                    Manifest.permission.BLUETOOTH,
                    Manifest.permission.BLUETOOTH_ADMIN,
                    Manifest.permission.BLUETOOTH_SCAN,
                    Manifest.permission.BLUETOOTH_CONNECT,

                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION,

                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.READ_EXTERNAL_STORAGE,

                    //Manifest.permission.INTERNET,涓嶉渶瑕佸姩鎬佺敵璇?

                    //Manifest.permission.CAMERA,

                    //Manifest.permission.SEND_SMS,

                    //Manifest.permission.REQUEST_INSTALL_PACKAGES,
            };
        }
        //瀹夊崜14鏄疷PSIDE_DOWN_CAKE = 34
        else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
            permissions = new String[]{
                    Manifest.permission.BLUETOOTH,
                    Manifest.permission.BLUETOOTH_ADMIN,
                    Manifest.permission.BLUETOOTH_SCAN,
                    Manifest.permission.BLUETOOTH_CONNECT,

                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION,

                    //Manifest.permission.READ_MEDIA_IMAGES, 浠巃ndroid14+寮?濮嬪簾鎺夛紝涔熸棤娉曠敵璇峰埌锛屼細瀵艰嚧涓嶅仠鎻愮ず鏉冮檺鏈幏鍙栵紝鍥犳蹇呴』娉ㄩ噴鎺?

                    //Manifest.permission.INTERNET,涓嶉渶瑕佸姩鎬佺敵璇?

                    //Manifest.permission.CAMERA,

                    Manifest.permission.POST_NOTIFICATIONS,//瑙ｅ喅瀹夊崜14涓嶈兘鎵撳紑閫氱煡鐨勯棶棰?

                    //Manifest.permission.SEND_SMS,

                    //Manifest.permission.REQUEST_INSTALL_PACKAGES,
            };
        }
        else {
            permissions = new String[]{
                    Manifest.permission.BLUETOOTH,
                    Manifest.permission.BLUETOOTH_ADMIN,
                    Manifest.permission.BLUETOOTH_SCAN,
                    Manifest.permission.BLUETOOTH_CONNECT,

                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION,

                    //Manifest.permission.READ_MEDIA_IMAGES,搴熸帀鐨勶紝涔熸棤娉曠敵璇峰埌锛屼細瀵艰嚧涓嶅仠鎻愮ず鏉冮檺鏈幏鍙栵紝鍥犳蹇呴』娉ㄩ噴鎺?

                    //Manifest.permission.INTERNET,涓嶉渶瑕佸姩鎬佺敵璇?

                    //Manifest.permission.CAMERA,

                    Manifest.permission.POST_NOTIFICATIONS,//瑙ｅ喅瀹夊崜14涓嶈兘鎵撳紑閫氱煡鐨勯棶棰?

                    //Manifest.permission.SEND_SMS,

                    //Manifest.permission.REQUEST_INSTALL_PACKAGES,
            };
        }

        return permissions;
    }

    public static boolean isHarmonyOS() {
        return Build.MANUFACTURER.equalsIgnoreCase("HUAWEI")
                && Build.VERSION.SDK_INT >= 28
                && "HMS".equalsIgnoreCase(Build.BRAND);
    }

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

        //region 濡傛灉鐢ㄦ埛娌℃湁閫氳繃鍏ㄩ儴鏉冮檺锛屽氨瑕佸憡鐭ョ敤鎴峰悗鍙板畾浣嶇殑鍘熷洜锛屽苟鐢宠鏉冮檺
        List<String> noPermissions = PermissionHelper.checkWhichPermissionsAreNotGranted(ALL_PERMISSIONS());
        if (!noPermissions.isEmpty()) {
            new AlertDialog.Builder(this)
                    .setTitle("Note")
                    .setMessage("Joyway Beacon uses bluetooth to scan & connect nearby devices," +
                    "this feature requires location service, so you should turn on both bluetooth and " +
                    "location service of your phone. The app will not collects your location data.")
                    .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();

                            //鐢ㄦ埛鐐瑰嚮鎸夐挳涔嬪悗锛屽啀鎵ц鑾峰彇鏉冮檺鐨勫姩浣?
                            final int REQUEST_CODE = 99;
                            PermissionHelper.checkAndRequestMorePermissions(ALL_PERMISSIONS(), REQUEST_CODE,
                                    new PermissionHelper.PermissionRequestSuccessCallBack() {
                                        @Override
                                        public void onHasPermission() {

                                        }
                                    });
                        }
                    }).create().show();
        }
        //endregion

        //濡傛灉楦胯挋绯荤粺锛岄渶瑕佸崟鐙负浠栫敵璇枫?愮綉缁滄潈闄愩??
        if (isHarmonyOS()) {
            PermissionHelper.checkAndRequestPermission("ohos.permission.INTERNET", 100);
        }

        //region 鑷姩鏇存柊杞欢. 銆愭敞鎰忋?憌ww.joyway.cn 鏄? https鐨勩??
        if (_updateMgr == null) {
            _updateMgr = new UpdateManager(
                    this,
                    "https://www.joyway.cn/download/android_app_version_info/JoywayBeacon.xml",
                    "cn.joyway.beacon");
            _updateMgr.checkUpdate();
        }//endregion
    }

    @Override
    public void onBeaconScanEvent(BeaconScanEvent beaconScanEvent) {
        if (beaconScanEvent.isScanned) {

            String advName = beaconScanEvent.beacon.getDeviceAdvertisingName();

            //region 杩囨护涓嶇鍚堢殑
            //rssi 娌℃湁杈惧埌杩囨护闂ㄦ锛屽拷鐣ュ畠
            if (beaconScanEvent.beacon.getRssiRawValueNow() < _rssiFilter) {
                return;
            }
            //涓嶈兘鏈夊悕瀛楋紝浣嗘槸瀹冩湁锛屽垯蹇界暐瀹?
            if (_cbNameFilterNoName.isChecked() && !advName.isEmpty()) {
                return;
            }
            //鍙互鏈夊悕瀛楋紝浣嗘槸鎸夎姹傚悕瀛楄浠XX寮?濮嬶紝浣嗘槸瀹冧笉鏄紝蹇界暐瀹?
            if (!_cbNameFilterNoName.isChecked() &&
                    !StringHelper.isNullOrEmpty(_nameFilter) &&
                    !advName.toLowerCase().contains(_nameFilter)) {
                return;
            }
            //endregion

            // 娣诲姞骞跺埛鏂癠I
            updateUI_for_deviceList_and_deviceCountLabel_inMainThread(DeviceListAction.add, beaconScanEvent.beacon);

        } else {

            //鍒犻櫎骞跺埛鏂癠I
            updateUI_for_deviceList_and_deviceCountLabel_inMainThread(DeviceListAction.remove, beaconScanEvent.beacon);
        }
    }

    @Override
    public void onBeaconConnectStatusChanged(String mac, BeaconConnectStatus beaconConnectStatus, BeaconConnectStatus beaconConnectStatus1) {

    }

    @Override
    public void onBeaconData(String mac, byte[] bytes, String str) {

    }

    @Override
    public void onBeaconRssiChanged(String mac, int i, int i1) {
        //浣跨敤timer瀹氭椂鍒锋柊鍒楄〃锛岃妭鐪丆PU
    }

    @Override
    public void onDataSentToBeacon(String mac, byte[] bytes, String str) {

    }

    enum DeviceListAction {
        add,
        remove,
        clear,
    }

    private void updateUI_for_deviceList_and_deviceCountLabel_inMainThread(DeviceListAction action, Beacon beacon) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                try {

                    //region 淇敼mac鍒楄〃閲岀殑鍐呭
                    if (action == DeviceListAction.add) {
                        _deviceListAdapter.addDevice(beacon);
                    } else if (action == DeviceListAction.remove) {
                        _deviceListAdapter.removeDevice(beacon._mac);
                    } else if (action == DeviceListAction.clear) {
                        _deviceListAdapter._deviceMacs.clear();
                    } //endregion

                    //鍒锋柊鍒楄〃鏄剧ず
                    _deviceListAdapter.notifyDataSetChanged();

                    //鍒锋柊璁惧鏁伴噺鏄剧ず
                    int deviceCount = _deviceListAdapter._deviceMacs.size();
                    _tvDeviceCount.setText(String.valueOf(deviceCount));

                }catch (Exception ignored) {

                }
            }
        });
    }
}