from typing import Any

import numpy as np
from scipy.signal import savgol_filter

from . import Points
from .signals import Signal


class BDS(Signal):
    """
    Extension of Signal for dielectric spectroscopy purposes.
    """

    def __init__(self, x, y, **kwargs: Any):
        super().__init__(x, y, **kwargs)

        if len(self._x) > 1:
            if np.all(self._x > 0) and np.allclose(self._x[1:]/self._x[:-1], self._x[1]/self._x[0]):
                self.dx = self.x[1] / self.x[0]
            else:
                self.dx = self._x[1] - self._x[0]

    def __repr__(self) -> str:
        return f"{self.meta['mode']}: {self.name}"

    def derivative(self, window_length=9) -> Points:
        """
        Calculates the derivative :math:`-\\frac{\\pi}{2}\\frac{d\\epsilon'}{d\\ln\\omega}`.
        To reduce :func:`scipy.signal.savgol_filter`

        Args:
            window_length (int)

        Returns:
            Points:
            New Points instance with

        Reference:
            Wübbenhorst, M.; van Turnhout, J.: Analysis of complex dielectric spectra.
            I. One-dimensional derivative techniques and three-dimensional modelling.
            J. Non-Cryst. Solid. 305 (2002) https://doi.org/10.1016/s0022-3093(02)01086-4

        """
        y = -savgol_filter(self.y[self.mask].real, window_length, 2, deriv=1) * np.pi / 2
        data = Points(x=self.x[self.mask], y=y)
        data.update(self.meta)
        return data
