"""
NetWeaver node inspector dialog.

A focused inspector for a single NetWeaver topic/column. Shows class counts in
a side table plus a bar chart of class distribution.
"""

from __future__ import annotations

from typing import Any, List, Optional, Tuple

import pandas as pd
from .qt_compat import (
    QAbstractItemView,
    QColor,
    QDialog,
    QFrame,
    QGroupBox,
    QHBoxLayout,
    QHeaderView,
    QLabel,
    QPushButton,
    QSplitter,
    QTableWidget,
    QTableWidgetItem,
    QTextEdit,
    QVBoxLayout,
    QWidget,
    Qt,
)
from .cdp_results_dialog import HorizontalBarChartWidget
from .translator import tr

# Canonical class breaks + classifier live in netweaver_scheme (parity plan
# Phase Q0). Re-exported here for backward compatibility — older code imports
# them from this module.
from .netweaver_scheme import (  # noqa: F401 (re-export)
    NETWEAVER_CLASS_BREAKS,
    classify_netweaver_value,
)


class NetWeaverNodeInspectorDialog(QDialog):
    """Focused inspector for a single NetWeaver topic/column.

    Layout (matches the legacy WPF EmdsNwViewer):
      - Header: workflow / topic / column / selected-row context
      - Horizontal splitter:
          * Left: class-count table + summary stats
          * Right: horizontal bar chart of class counts
      - Buttons: Close
    """

    def __init__(
        self,
        *,
        workflow_name: str,
        topic_name: str,
        column_name: str,
        column_series: pd.Series,
        selected_row_index: Optional[Any] = None,
        selected_row_value: Any = None,
        parent=None,
    ):
        super().__init__(parent)
        self.workflow_name = workflow_name
        self.topic_name = topic_name
        self.column_name = column_name
        self.column_series = column_series
        self.selected_row_index = selected_row_index
        self.selected_row_value = selected_row_value

        self.setWindowTitle(tr("netweaver_inspector.window_title", topic=self.topic_name))
        self.resize(820, 520)
        self._init_ui()

    def _init_ui(self) -> None:
        layout = QVBoxLayout()
        self.setLayout(layout)

        # Header
        header = QLabel(tr(
            "netweaver_inspector.header",
            topic=self.topic_name,
            column=self.column_name,
            workflow=self.workflow_name,
        ))
        header.setWordWrap(True)
        header.setTextFormat(Qt.TextFormat.RichText)
        layout.addWidget(header)

        if self.selected_row_index is not None:
            class_label = (
                classify_netweaver_value(self.selected_row_value)
                or tr("netweaver_inspector.unclassified")
            )
            value_text = (
                "" if self.selected_row_value in (None, "")
                else f"{self.selected_row_value} ({class_label})"
            )
            sel_label = QLabel(tr(
                "netweaver_inspector.selected_row",
                row=self.selected_row_index,
                value=value_text,
            ))
            sel_label.setTextFormat(Qt.TextFormat.RichText)
            sel_label.setWordWrap(True)
            layout.addWidget(sel_label)

        # Horizontal splitter
        splitter = QSplitter(Qt.Orientation.Horizontal)
        layout.addWidget(splitter, 1)

        # Left side: legend strip + class-count table + summary stats
        left_host = QWidget(self)
        left_layout = QVBoxLayout()
        left_layout.setContentsMargins(0, 0, 0, 0)
        left_host.setLayout(left_layout)

        legend_group = QGroupBox(tr("netweaver_inspector.legend_title"))
        legend_outer = QVBoxLayout()
        legend_outer.setContentsMargins(8, 4, 8, 4)
        for lower, upper, label, color_hex in NETWEAVER_CLASS_BREAKS:
            row = QHBoxLayout()
            swatch = QFrame()
            swatch.setFrameShape(QFrame.Shape.StyledPanel)
            swatch.setFixedSize(14, 14)
            swatch.setStyleSheet(
                f"background-color: {QColor(color_hex).name()}; border: 1px solid #666;"
            )
            row.addWidget(swatch)
            upper_text = "1.0" if upper == 1.0 else f"{upper:g}"
            row.addWidget(QLabel(f"{label}: [{lower:g}, {upper_text}{']' if upper == 1.0 else ')'}"))
            row.addStretch()
            legend_outer.addLayout(row)
        legend_group.setLayout(legend_outer)
        left_layout.addWidget(legend_group)

        self.class_table = QTableWidget(0, 3)
        self.class_table.setHorizontalHeaderLabels([
            tr("netweaver_inspector.col_class"),
            tr("netweaver_inspector.col_count"),
            tr("netweaver_inspector.col_percent"),
        ])
        self.class_table.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
        self.class_table.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
        self.class_table.verticalHeader().setVisible(False)
        h = self.class_table.horizontalHeader()
        h.setStretchLastSection(True)
        h.setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch)
        h.setSectionResizeMode(1, QHeaderView.ResizeMode.ResizeToContents)
        left_layout.addWidget(self.class_table, 1)

        self.summary_label = QTextEdit()
        self.summary_label.setReadOnly(True)
        self.summary_label.setMinimumHeight(100)
        left_layout.addWidget(self.summary_label)

        splitter.addWidget(left_host)

        # Right side: horizontal bar chart of class counts
        self.chart = HorizontalBarChartWidget(self)
        splitter.addWidget(self.chart)

        splitter.setStretchFactor(0, 1)
        splitter.setStretchFactor(1, 1)
        splitter.setSizes([360, 460])

        # Bottom buttons
        button_row = QHBoxLayout()
        layout.addLayout(button_row)
        button_row.addStretch()
        close_button = QPushButton(tr("netweaver_inspector.btn_close"))
        close_button.clicked.connect(self.close)
        button_row.addWidget(close_button)

        # Populate
        self._populate_class_data()

    def _populate_class_data(self) -> None:
        numeric_series = pd.to_numeric(self.column_series, errors="coerce")
        valid_values = numeric_series.dropna()
        rows: List[Tuple[str, int, str]] = []
        chart_labels: List[str] = []
        chart_values: List[float] = []

        valid_count = int(valid_values.shape[0])
        for lower, upper, label, _color in NETWEAVER_CLASS_BREAKS:
            if upper == 1.0:
                in_range = (valid_values >= lower) & (valid_values <= upper)
            else:
                in_range = (valid_values >= lower) & (valid_values < upper)
            count = int(in_range.sum())
            pct = (count / valid_count * 100.0) if valid_count else 0.0
            rows.append((label, count, f"{pct:.1f}%"))
            chart_labels.append(label)
            chart_values.append(float(count))

        self.class_table.setRowCount(len(rows))
        for r, (label, count, pct) in enumerate(rows):
            self.class_table.setItem(r, 0, QTableWidgetItem(label))
            count_item = QTableWidgetItem(str(count))
            count_item.setTextAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
            self.class_table.setItem(r, 1, count_item)
            pct_item = QTableWidgetItem(pct)
            pct_item.setTextAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
            self.class_table.setItem(r, 2, pct_item)

        # Summary stats
        lines = [
            tr("netweaver_inspector.total_rows", count=len(self.column_series.index)),
            tr("netweaver_inspector.non_null", count=valid_count),
            tr("netweaver_inspector.null", count=int(numeric_series.isna().sum())),
        ]
        if not valid_values.empty:
            lines.extend(
                [
                    "",
                    tr("netweaver_inspector.minimum", value=f"{valid_values.min():.4f}"),
                    tr("netweaver_inspector.maximum", value=f"{valid_values.max():.4f}"),
                    tr("netweaver_inspector.mean", value=f"{valid_values.mean():.4f}"),
                    tr("netweaver_inspector.median", value=f"{valid_values.median():.4f}"),
                ]
            )
        else:
            lines.extend(["", tr("netweaver_inspector.no_numeric")])
        self.summary_label.setPlainText("\n".join(lines))

        # Bar chart
        self.chart.set_chart_data(
            chart_labels,
            chart_values,
            title=tr("netweaver_inspector.chart_title", column=self.column_name),
            value_label=tr("netweaver_inspector.chart_value_label"),
            empty_message=tr("netweaver_inspector.chart_empty"),
        )
