from qgis.PyQt.QtCore import Qt

from openlog.gui.assay_visualization.assay_sort import AssaySort


class AzimuthAnnotation:
    """
    Abstract class for azimuth arrow map annotation.
    Need to be instantiated as AssayWidget attribute.
    """

    def __init__(self, assay_widget):
        self.assay_widget = assay_widget
        self.assay_widget.azimuth_spinbox.valueChanged.connect(self.on_azimuth_changed)
        self.annotation = None

    def on_azimuth_click(self):
        """
        Must be triggered each time azimuth button is clicked.
        Add/remove annotation layer.
        Must be overriden.
        """
        return

    def on_azimuth_changed(self):
        """
        Update arrow angle.
        Must be overriden.
        """
        return


class AssaySorter:
    """
    Class used to sort assay according chosen sorting policy.
    Need to be instantiated inside PlotGrid instance.
    """

    def __init__(self, plot_grid):
        self.plot_grid = plot_grid

    def sort_multiplot_assay(self) -> list:

        reverse = True if self.plot_grid._sort_order == Qt.DescendingOrder else False

        # Sort multiplot config list
        multiplot_config_list = sorted(
            self.plot_grid._multiplot_config.list, key=lambda x: x.name, reverse=reverse
        )

        return multiplot_config_list

    def sort_crossplots(self) -> list:

        reverse = True if self.plot_grid._sort_order == Qt.DescendingOrder else False

        # Sort crossplot config list
        crossplot_config_list = sorted(
            self.plot_grid._crossplot_config.list, key=lambda x: x.name, reverse=reverse
        )

        return crossplot_config_list

    def sort_stacked(self) -> list:

        reverse = True if self.plot_grid._sort_order == Qt.DescendingOrder else False

        # Sort stacked config list
        stacked_config_list = sorted(
            self.plot_grid._stacked_config.list, key=lambda x: x.name, reverse=reverse
        )

        return stacked_config_list

    def sort_assay(self) -> list:

        config_list = None
        reverse = True if self.plot_grid._sort_order == Qt.DescendingOrder else False

        # if state is UNDEFINED and transpose is called, set order to hole_id
        if self.plot_grid._sort in [AssaySort.HOLE_ID, AssaySort.UNDEFINED]:
            config_list = sorted(
                self.plot_grid._visualization_config.list,
                key=lambda x: f"{x.hole_display_name}/{x.assay_display_name}",
                reverse=reverse,
            )
        elif self.plot_grid._sort == AssaySort.ASSAY_NAME:
            config_list = sorted(
                self.plot_grid._visualization_config.list,
                key=lambda x: x.assay_display_name
                if not x.hole_id
                else f"{x.assay_display_name}/{x.hole_display_name}",
                reverse=reverse,
            )

        elif self.plot_grid._sort == AssaySort.X:
            read_iface = self.plot_grid._openlog_connection.get_read_iface()
            config_list = sorted(
                self.plot_grid._visualization_config.list,
                key=lambda x: (
                    read_iface.get_collar(x.hole_id).x,
                    read_iface.get_collar(x.hole_id).y,
                )
                if x.hole_id != ""
                else (0, 0),
                reverse=reverse,
            )

        elif self.plot_grid._sort == AssaySort.Y:
            read_iface = self.plot_grid._openlog_connection.get_read_iface()
            config_list = sorted(
                self.plot_grid._visualization_config.list,
                key=lambda x: (
                    read_iface.get_collar(x.hole_id).y,
                    read_iface.get_collar(x.hole_id).x,
                )
                if x.hole_id != ""
                else (0, 0),
                reverse=reverse,
            )

        return config_list
