from typing import Iterable

import numpy
from silx.gui import qt
from silx.gui.colors import Colormap
from silx.io.utils import DataUrl

from ewoks3dxrd.nexus.peaks import read_peaks_attributes

from .axis_control_toolbar import AxisControlToolbar
from .ewoks3dxrd_widget import Ewoks3DXRDWidget
from .peak_filter_plot2d import PeakFilterPlot2D

_COLORMAP = Colormap(name="viridis", autoscaleMode="percentile_1_99")


class CustomPeakPlot(PeakFilterPlot2D):
    """
    A PeakFilterPlot2D where axes can be changed
    """

    sigAxisChanged = qt.Signal()

    def __init__(self, parent: Ewoks3DXRDWidget) -> None:
        super().__init__(parent)
        parent._logPlotEvents(self._plot)
        self._axisControls = AxisControlToolbar(parent, self)
        self.addPeakAttributesAction(self._axisControls)
        self._axisControls.sigAxisChanged.connect(self._setCustomAxes)
        self._xAxisName = "ds"
        self._yAxisName = "eta"

    def _setCustomAxes(self):
        if self._axisControls is None:
            return

        self._xAxisName = self._axisControls.getSelectedX()
        self._yAxisName = self._axisControls.getSelectedY()
        self.sigAxisChanged.emit()

    def populateAxesToolbar(self, axisNames: Iterable[str]):
        if not self._axisControls:
            return

        self._axisControls.populateAxes(
            axisNames=tuple(axisNames),
            defaultX=self._xAxisName,
            defaultY=self._yAxisName,
        )

    def plotUnfilteredPeaks(self, rawPeaksDataUrl: str):
        peaksDataUrl = DataUrl(rawPeaksDataUrl)
        peaks = read_peaks_attributes(
            filename=peaksDataUrl.file_path(), process_name=peaksDataUrl.data_path()
        )
        self.addUnfilteredScatter(
            x=peaks[self._xAxisName],
            y=peaks[self._yAxisName],
            value=numpy.ones(len(peaks[self._xAxisName])),
            colormap=_COLORMAP,
        )
        self.setGraphXLabel(self._xAxisName)
        self.setGraphYLabel(self._yAxisName)
        self.resetZoomOnce()

    def plotFilteredPeaks(self, rawPeaksDataUrl: str):
        peaksDataUrl = DataUrl(rawPeaksDataUrl)
        peaks = read_peaks_attributes(
            filename=peaksDataUrl.file_path(),
            process_name=peaksDataUrl.data_path(),
        )
        self.addFilteredScatter(
            x=peaks[self._xAxisName],
            y=peaks[self._yAxisName],
            value=peaks["Number_of_pixels"],
            colormap=_COLORMAP,
        )
        self.setGraphXLabel(self._xAxisName)
        self.setGraphYLabel(self._yAxisName)
        self.resetZoomOnce()
