# VERSION: v1.8.0 - fire/ui_components/charts/qc_plotly_chart_widget.py # (pre refactoring)
 
# RESP: Widget Qt generico per visualizzare grafici Plotly interattivi e reattivi via JSON.
 
# DEPS: PySide6.QtWebEngineWidgets, ThemeManager, json.
 
# NOTA: Reso robusto a richieste di plot premature tramite un meccanismo di accodamento.
 
  
 
import json
 
from PySide6.QtWidgets import QWidget, QVBoxLayout
 
from PySide6.QtWebEngineWidgets import QWebEngineView
 
from PySide6.QtWebEngineCore import QWebEngineProfile, QWebEnginePage
 
from PySide6.QtCore import Slot
 
import logging
 
from typing import Optional
 
  
 
from ..theme_manager import ThemeManager
 
from fire.app_state import AppState
 
  
 
logger = logging.getLogger(__name__)
 
  
 
class QCPlotlyChartWidget(QWidget):
 
    """
 
    Widget che renderizza una figura Plotly in modo reattivo. Riceve i dati
 
    come stringa JSON e crea un'istanza dinamica di Plotly.js.
 
    """
 
    HTML_SKELETON = """
 
    <!DOCTYPE html>
 
    <html>
 
    <head>
 
        <meta charset="utf-8" />
 
        <title>Plotly Chart</title>
 
        <script src="https://cdn.plot.ly/plotly-2.27.0.min.js"></script>
 
        <style>
 
            body, html {{
 
                margin: 0; padding: 0; height: 100%; width: 100%;
 
                overflow: hidden; background-color: {backgroundColor};
 
            }}
 
            #plotly-div {{ height: 100%; width: 100%; }}
 
        </style>
 
    </head>
 
    <body>
 
        <div id="plotly-div"></div>
 
        <script>
 
            window.renderPlotly = function(figureJson, themeColors) {{
 
                try {{
 
                    const figure = JSON.parse(figureJson);
 
                    const plotlyTheme = {{
 
                        layout: {{
 
                            paper_bgcolor: themeColors.backgroundColor,
 
                            plot_bgcolor: themeColors.backgroundColor,
 
                            font: {{ color: themeColors.textColor }},
 
                            xaxis: {{ gridcolor: themeColors.gridColor }},
 
                            yaxis: {{ gridcolor: themeColors.gridColor }}
 
                        }}
 
                    }};
 
                    if (figure.layout) {{
 
                        Object.assign(figure.layout, plotlyTheme.layout, figure.layout);
 
                    }} else {{
 
                        figure.layout = plotlyTheme.layout;
 
                    }}
 
                    const config = {{ responsive: true, displaylogo: false }};
 
                    Plotly.newPlot('plotly-div', figure.data || [], figure.layout, config);
 
                }} catch (e) {{
 
                    console.error("Errore durante il rendering di Plotly:", e);
 
                }}
 
            }};
 
        </script>
 
    </body>
 
    </html>
 
    """
 
  
 
    def __init__(self, app_state: AppState, parent: QWidget = None):
 
        super().__init__(parent)
 
        self.app_state = app_state
 
        self.is_page_loaded = False
 
        # --- INIZIO MODIFICA: Aggiunta coda per plot in sospeso ---
 
        self._pending_plot_json: Optional[str] = None
 
        # --- FINE MODIFICA ---
 
        self._setup_theme()
 
  
 
        self.profile = QWebEngineProfile(f"QCPlotly_{id(self)}", self)
 
        page = QWebEnginePage(self.profile, self)
 
        self.browser = QWebEngineView()
 
        self.browser.setPage(page)
 
        layout = QVBoxLayout(self)
 
        layout.setContentsMargins(0, 0, 0, 0)
 
        layout.addWidget(self.browser)
 
        formatted_html = self.HTML_SKELETON.format(backgroundColor=self.theme["backgroundColor"])
 
        self.browser.setHtml(formatted_html)
 
        self.browser.loadFinished.connect(self._on_load_finished)
 
  
 
    def _setup_theme(self):
 
        self.theme = {
 
            "backgroundColor": ThemeManager.get_raw_color("chart_backgroundColor").name(),
 
            "textColor": ThemeManager.get_raw_color("chart_textColor").name(),
 
            "gridColor": ThemeManager.get_raw_color("chart_gridColor").name(),
 
        }
 
  
 
    def _on_load_finished(self, ok: bool):
 
        if ok:
 
            self.is_page_loaded = True
 
            logger.debug("QCPlotlyChartWidget (reattivo) inizializzato e pronto.")
 
            # --- INIZIO MODIFICA: Esecuzione del plot in sospeso ---
 
            if self._pending_plot_json:
 
                logger.debug("Esecuzione di un plot in sospeso...")
 
                self.plot(self._pending_plot_json)
 
                self._pending_plot_json = None
 
            # --- FINE MODIFICA ---
 
        else:
 
            logger.error("Il caricamento della pagina HTML scheletro di Plotly è fallito.")
 
  
 
    @Slot(str)
 
    def plot(self, figure_json: str):
 
        # --- INIZIO MODIFICA: Logica di accodamento ---
 
        if not self.is_page_loaded:
 
            logger.warning("Tentativo di plottare prima dell'inizializzazione. Metto in coda la richiesta.")
 
            self._pending_plot_json = figure_json
 
            return
 
        # --- FINE MODIFICA ---
 
        theme_json = json.dumps(self.theme)
 
        js_code = f"window.renderPlotly({json.dumps(figure_json)}, {theme_json});"
 
        self.browser.page().runJavaScript(js_code)
 
  
 
    @Slot(str)
 
    def clear_chart(self, message: str = "Nessun dato da visualizzare."):
 
        if not self.is_page_loaded:
 
            self._pending_plot_json = None # Annulla eventuali plot in sospeso
 
        fig = {
 
            "data": [],
 
            "layout": {
 
                "annotations": [{
 
                    "text": message, "xref": "paper", "yref": "paper",
 
                    "showarrow": False, "font": {"size": 16}
 
                }],
 
                "xaxis": {"visible": False},
 
                "yaxis": {"visible": False}
 
            }
 
        }
 
        self.plot(json.dumps(fig))