package com.example.java.sample;

import static androidx.navigation.fragment.FragmentKt.findNavController;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import com.example.java.sample.databinding.FragmentDeviceBinding;
import com.seikoinstruments.sdk.thermalprinter.PrinterEvent;
import com.seikoinstruments.sdk.thermalprinter.PrinterInfo;
import com.seikoinstruments.sdk.thermalprinter.PrinterListener;
import com.seikoinstruments.sdk.thermalprinter.PrinterManager;

import java.util.ArrayList;
import java.util.Objects;

/**
 * Fragment responsible for displaying printer discovery results.
 * Implements PrinterListener to handle printer discovery events.
 */
public class DeviceFragment extends Fragment implements PrinterListener {
    private Handler mHandler = null;
    private IndicatorDialogFragment mIndicatorDialog = null;
    private int mPrinterType = PrinterManager.PRINTER_TYPE_BLUETOOTH;
    private Function mSdkFunction = null;
    // ArrayAdapter of the device list.
    private DeviceListArrayAdapter mDeviceListAdapter = null;

    // This property is only valid between onCreateView and onDestroyView.
    private FragmentDeviceBinding binding;

    @Override
    public View onCreateView(
            @NonNull LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState
    ) {
        // Initialize handler and inflate binding
        mHandler = new Handler(Looper.getMainLooper());
        binding = FragmentDeviceBinding.inflate(inflater, container, false);
        return binding.getRoot();
    }

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        // Retrieve printer type from MainActivity
        MainActivity mainActivity = (MainActivity) getActivity();
        mPrinterType = Objects.requireNonNull(mainActivity).mPrinterType;

        mDeviceListAdapter = new DeviceListArrayAdapter(getActivity().getApplicationContext(), 0);
        binding.listViewPrinter.setAdapter(this.mDeviceListAdapter);
        binding.listViewPrinter.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // Handle item click
                final DeviceListItem item = (DeviceListItem) parent.getItemAtPosition(position);

                String address = "";
                if (mPrinterType == PrinterManager.PRINTER_TYPE_TCP) {
                    address = item.getIpAddress();
                } else {
                    address = item.getMacAddress();
                }

                // Pass address back to MainFragment
                Bundle bundle = new Bundle();
                bundle.putString("key_address",address);
                getParentFragmentManager().setFragmentResult(MainActivity.REQUEST_KEY_SEARCH, bundle);
                findNavController(DeviceFragment.this).navigate(R.id.action_DeviceFragment_to_MainFragment);
            }
        });

        binding.buttonReSearch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Perform re-search on button click
                showIndicatorDialog();
                mDeviceListAdapter.clear();
                mSdkFunction.searchDeviceSample((PrinterListener) DeviceFragment.this,mPrinterType);
            }
        });

        mSdkFunction = new Function(requireActivity().getApplicationContext());
        // Start initial search
        showIndicatorDialog();
        mSdkFunction.searchDeviceSample((PrinterListener) DeviceFragment.this,mPrinterType);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }

    private void showIndicatorDialog() {
        // Show indicator dialog
        mIndicatorDialog = new IndicatorDialogFragment(mSdkFunction );
        mIndicatorDialog.setCancelable(true);// Cancellable
        mIndicatorDialog.show(getChildFragmentManager(), "indicator_dialog");

    }

    private void dismissIndicatorDialog() {
        // Dismiss indicator dialog
        mIndicatorDialog.dismiss();
    }

    /**
     * Handles the finish event of printer discovery.
     * This method retrieves the type of event and performs appropriate actions accordingly.
     *
     * @param event The PrinterEvent object representing the finish event.
     */
    @Override
    public void finishEvent(PrinterEvent event) {
        // Handle finish event of printer discovery
        int eventType = event.getEventType();

        // Check the type of event
        switch (eventType) {
            // If the event is finishing or canceling printer discovery
            case PrinterEvent.EVENT_FINISHED_DISCOVERY:
            case PrinterEvent.EVENT_CANCELED_DISCOVERY:
                // Post a new Runnable to the mHandler to update UI on the main thread
                mHandler.post(new Runnable() {
                    public void run() {
                        // Retrieve the list of found printers
                        ArrayList<PrinterInfo> list = mSdkFunction.getFoundPrinter();
                        int count = list.size();

                        // Iterate through the found printers
                        for (int index = 0; index < count; index++) {
                            // Get printer information
                            PrinterInfo info = list.get(index);
                            DeviceListItem item;

                            // Based on the printer type, create a DeviceListItem
                            if (mPrinterType == PrinterManager.PRINTER_TYPE_BLUETOOTH) {
                                // For Bluetooth printers, create a DeviceListItem with Bluetooth information
                                item = new DeviceListItem(info.getPrinterModelName(), info.getBluetoothAddress(), getString(info.getIsBonded()? R.string.paired: R.string.unpaired));
                            } else if(mPrinterType == PrinterManager.PRINTER_TYPE_TCP){
                                // For TCP printers, create a DeviceListItem with IP and MAC addresses
                                item = new DeviceListItem(info.getPrinterModelName(), info.getMacAddress(), info.getIpAddress());
                            } else {
                                // For USB printer types, determine the appropriate printer model and create a DeviceListItem
                                int printerModel = info.getPrinterModel();
                                String[] modelValueList = getResources().getStringArray(R.array.printer_model_values_list);
                                int listIndex = 0;
                                // Find the index of the printer model in the resource array
                                for(int index2 = 0; index2 < modelValueList.length; index2++){
                                    String printerModelString = String.valueOf(printerModel);
                                    if(modelValueList[index2].equals(printerModelString)){
                                        listIndex = index2;
                                        break;
                                    }
                                }
                                // Get the printer model name from resources and create a DeviceListItem
                                String[] modelList = getResources().getStringArray(R.array.printer_model_list);
                                item = new DeviceListItem(modelList[listIndex], info.getDevicePath(),"");
                            }

                            // Add the DeviceListItem to the adapter
                            mDeviceListAdapter.add(item);
                        }
                        // Dismiss any indicator dialogs
                        dismissIndicatorDialog();
                    }
                });
                break;
        }
    }
}