package it.integry.integrywmsnative.gest.settings;

import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.Bundle;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.preference.EditTextPreference;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;

import com.annimon.stream.Stream;
import com.harrysoft.androidbluetoothserial.BluetoothManager;

import java.util.ArrayList;
import java.util.Collection;

import it.integry.barcode_base_android_library.model.BarcodeSetting;
import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.barcode_reader.BarcodeManager;
import it.integry.integrywmsnative.core.interfaces.ITitledFragment;
import it.integry.integrywmsnative.core.utility.UtilityResources;

public class MainSettingsFragment extends PreferenceFragmentCompat implements ITitledFragment, Preference.OnPreferenceChangeListener {

    private final ArrayList<Runnable> onPreDestroyList = new ArrayList<>();

    public static final String KEY_PALLET_BT_DEVICE = "pallet_scale_bt_device";
    public static final String KEY_TRIGGER_SCAN_MODE = "TRIG_SCAN_MODE";
    public static final String KEY_TRIGGER_SCAN_DELAY = "TRIG_SCAN_DELAY";

    private Collection<BluetoothDevice> btPairedDevices;

    @Override
    public void onCreateActionBar(AppCompatTextView titleText, Context context) {
        titleText.setText(context.getText(R.string.settings_category).toString());
    }

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.app_preferences, rootKey);

        var palletScaleBtDeviceListPref = (ListPreference) findPreference(KEY_PALLET_BT_DEVICE);
        var triggerScanDelayPref = (EditTextPreference) findPreference(KEY_TRIGGER_SCAN_DELAY);
        var triggerScanModeListPref = (ListPreference) findPreference(KEY_TRIGGER_SCAN_MODE);
        setListPreferenceData(palletScaleBtDeviceListPref);
        palletScaleBtDeviceListPref.setOnPreferenceChangeListener(this);

        triggerScanDelayPref.setOnPreferenceChangeListener(this);
        triggerScanDelayPref.setSummary(triggerScanDelayPref.getText());

        loadScanModePreferences();
        triggerScanModeListPref.setOnPreferenceChangeListener(this);
        triggerScanModeListPref.setSummary(triggerScanModeListPref.getValue());
    }


    protected void loadScanModePreferences() {
        var triggerScanModeListPref = (ListPreference) findPreference(KEY_TRIGGER_SCAN_MODE);
        if (triggerScanModeListPref != null) {
            var scanModes = BarcodeSetting.getTriggerScanModes();
            triggerScanModeListPref.setEntries(scanModes);
            triggerScanModeListPref.setEntryValues(scanModes);
            triggerScanModeListPref.setOnPreferenceChangeListener(this);
        }
    }

    protected void setListPreferenceData(ListPreference lp) {
        BluetoothManager bluetoothManager = BluetoothManager.getInstance();
        if (bluetoothManager == null) {
            // Bluetooth unavailable on this device :( tell the user
            Toast.makeText(requireActivity(), "Bluetooth not available", Toast.LENGTH_LONG).show(); // Replace context with your context instance.
            return;
        }

        btPairedDevices = bluetoothManager.getPairedDevicesList();

        if (!Stream.of(btPairedDevices).anyMatch(x -> x.getAddress().equalsIgnoreCase(lp.getValue()))) {
            lp.setValue(null);
        }

        updatePalletBtDeviceSummary(lp, lp.getValue());

        if (!btPairedDevices.isEmpty()) {
            CharSequence[] entries = new CharSequence[btPairedDevices.size()];
            Stream.of(btPairedDevices)
                    .map(BluetoothDevice::getName)
                    .toList()
                    .toArray(entries);

            CharSequence[] entryValues = new CharSequence[btPairedDevices.size()];
            Stream.of(btPairedDevices)
                    .map(BluetoothDevice::getAddress)
                    .toList()
                    .toArray(entryValues);

            lp.setEntries(entries);
            lp.setEntryValues(entryValues);
        } else {
            lp.setEntries(new CharSequence[0]);
            lp.setEntryValues(new CharSequence[0]);
            lp.setDialogMessage("Nessun dispositivo bluetooth associato. Associane uno dalle impostazioni bluetooth prima di procedere.");
        }
    }


    @Override
    public void addOnPreDestroy(Runnable onPreDestroy) {
        onPreDestroyList.add(onPreDestroy);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();

        for (Runnable onPreDestroy : onPreDestroyList) {
            onPreDestroy.run();
        }
    }

    @Override
    public boolean onPreferenceChange(@NonNull Preference preference, Object newValue) {

        final int idx;
        switch (preference.getKey()) {
            case KEY_PALLET_BT_DEVICE:
                final var palletScaleBtDeviceListPref = (ListPreference) preference;
                updatePalletBtDeviceSummary(palletScaleBtDeviceListPref, (String) newValue);
                break;
            case KEY_TRIGGER_SCAN_DELAY:
                final var scanDelayPref = (EditTextPreference) preference;
                scanDelayPref.setSummary((String) newValue);
                updateBarcodeScannerSettings();
                break;
            case KEY_TRIGGER_SCAN_MODE:
                final var scanTriggerMode = (ListPreference) preference;
                scanTriggerMode.setSummary((String) newValue);
                updateBarcodeScannerSettings();
                break;

        }
        // Set result so knows to refresh itself
//        getActivity().setResult(RESULT_OK);
        return true;
    }

    private void updateBarcodeScannerSettings() {
        try {
            BarcodeManager.init(requireContext());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void updatePalletBtDeviceSummary(ListPreference listPref, String btDeviceAddress) {
        String btDeviceName = Stream.of(btPairedDevices)
                .filter(x -> x.getAddress().equalsIgnoreCase(btDeviceAddress))
                .map(BluetoothDevice::getName)
                .findFirstOrElse(UtilityResources.getString(R.string.pallet_scale_bt_device_selection_info));
        listPref.setSummary(btDeviceName);
    }

}
