"""
SI UI Library - Plot Canvas
Dark-themed matplotlib canvas for embedding in PyQt5 applications.

Usage:
    from si_ui import PlotCanvas

    canvas = PlotCanvas(parent, width=5, height=4,
                        xlabel="X", ylabel="Y", title="My Plot")
    canvas.axes.plot(x, y)
    canvas.draw()
"""

import numpy as np

from PyQt5.QtWidgets import QSizePolicy

import matplotlib
matplotlib.use("Qt5Agg")
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure


class PlotCanvas(FigureCanvas):
    """Embedded matplotlib plot with dark theme.

    Parameters
    ----------
    parent : QWidget or None
        Parent widget.
    width, height : float
        Figure size in inches.
    xlabel, ylabel, title : str
        Default axis labels and title.
    bg_color, fg_color, grid_color, line_color, point_color, secondary_color : str
        Hex colour overrides.
    """

    def __init__(
        self,
        parent=None,
        width: float = 5,
        height: float = 4,
        xlabel: str = "X",
        ylabel: str = "Y",
        title: str = "",
        bg_color: str = "#181825",
        fg_color: str = "#cdd6f4",
        grid_color: str = "#313244",
        line_color: str = "#89b4fa",
        point_color: str = "#a6e3a1",
        secondary_color: str = "#f9e2af",
    ):
        self.bg_color = bg_color
        self.fg_color = fg_color
        self.grid_color = grid_color
        self.line_color = line_color
        self.point_color = point_color
        self.secondary_color = secondary_color

        self._xlabel = xlabel
        self._ylabel = ylabel
        self._title = title

        self.fig = Figure(figsize=(width, height), dpi=100, facecolor=self.bg_color)
        self.axes = self.fig.add_subplot(111)
        self.setup_style()

        super().__init__(self.fig)
        self.setParent(parent)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        # Tracked scatter points
        self.points_x: list[float] = []
        self.points_y: list[float] = []

    # ------------------------------------------------------------------ #
    # Styling
    # ------------------------------------------------------------------ #
    def setup_style(self):
        """Apply dark theme to the axes."""
        self.axes.set_facecolor(self.bg_color)
        self.axes.tick_params(colors=self.fg_color, labelsize=8)
        for spine in self.axes.spines.values():
            spine.set_color(self.grid_color)
        self.axes.xaxis.label.set_color(self.fg_color)
        self.axes.yaxis.label.set_color(self.fg_color)
        self.axes.title.set_color(self.fg_color)
        self.axes.grid(True, color=self.grid_color, alpha=0.3, linestyle="-", linewidth=0.5)

        self.axes.set_xlabel(self._xlabel, fontsize=9)
        self.axes.set_ylabel(self._ylabel, fontsize=9)
        if self._title:
            self.axes.set_title(self._title, fontsize=10, fontweight="bold")

        self.fig.tight_layout(pad=1.5)

    # ------------------------------------------------------------------ #
    # Point tracking helpers
    # ------------------------------------------------------------------ #
    def add_point(self, x: float, y: float):
        """Add a highlighted scatter point and redraw."""
        self.points_x.append(x)
        self.points_y.append(y)
        self.axes.scatter(
            [x], [y],
            color=self.point_color,
            s=50,
            zorder=5,
            edgecolors="white",
            linewidth=1,
        )
        self.draw()

    def clear_points(self):
        """Clear tracked scatter points (does not redraw)."""
        self.points_x.clear()
        self.points_y.clear()

    def redraw_points(self):
        """Re-scatter all tracked points onto the current axes."""
        if self.points_x:
            self.axes.scatter(
                self.points_x,
                self.points_y,
                color=self.point_color,
                s=40,
                zorder=5,
                edgecolors="white",
                linewidth=0.5,
                label="Calculated",
            )
