"""
Block table widget - one row per sync block, colour-coded by type.
Row tints use alpha-transparent QColor values so they blend with whatever
base colour the OS palette provides, keeping type indication readable on
both light and dark themes.
"""
from __future__ import annotations

from PySide6.QtCore import Signal, Qt
from PySide6.QtWidgets import (
    QTableWidget, QTableWidgetItem, QHeaderView, QAbstractItemView,
)
from PySide6.QtGui import QColor, QBrush

from src.gui.adapters import BlockRow

_COL_NAMES = [
    "#sync", "orig#", "Type", "Dur (uss)", "RF", "ADC", "Grad",
    "Delay", "gRF", "gADC", "gTR", "T-start (uss)",
]

# Row background tints - alpha ~80/255 so they blend with the OS base colour.
# On a white base: soft pastels.  On a dark base: subtle dark tints.
_BG: dict[str, QColor] = {
    "START": QColor(244, 143, 177,  80),  # pink  - start delay
    "TR":    QColor(144, 202, 249,  80),  # blue  - TR delay
    "RF":    QColor(255, 224, 130,  80),  # amber - RF delay
    "adc":   QColor(165, 214, 167,  80),  # green - ADC block
    "rf":    QColor(244, 143, 177,  80),  # pink  - RF block
    "grad":  QColor(206, 147, 216,  80),  # purple - gradient block
    "plain": QColor(0,   0,   0,    0 ),  # transparent - no tint
}

# Structural stylesheet only - base text/background come from the OS palette.
# Only the selection highlight and hover state are pinned to explicit colours
# because they need to be clearly visible on any background.
_STYLESHEET = """
QTableWidget {
    gridline-color: #333355;
    font-size: 12px;
    background: #16162a;
    color: #ddddff;
    border: 1px solid #2a2a4a;
}
QTableWidget::item {
    padding: 2px 4px;
}
QTableWidget::item:selected {
    background-color: #e65100;
    color: #ffffff;
}
QTableWidget::item:hover:!selected {
    background-color: #252545;
}
QHeaderView::section {
    background: #252535;
    color: #aaaaaa;
    border: none;
    border-bottom: 1px solid #333355;
    border-right:  1px solid #333355;
    padding: 4px 6px;
    font-weight: bold;
}
QScrollBar:horizontal, QScrollBar:vertical {
    background: #16162a;
}
"""


def _bg_for(row: BlockRow) -> QColor:
    if row.is_delay:
        return _BG.get(row.delay_type, _BG["plain"])
    if row.has_adc:
        return _BG["adc"]
    if row.has_rf:
        return _BG["rf"]
    if row.has_grad:
        return _BG["grad"]
    return _BG["plain"]


class BlockTable(QTableWidget):
    blockSelected     = Signal(int)   # sync_index  (single click / keyboard)
    blockDoubleClicked = Signal(int)  # sync_index  (double click → zoom)

    def __init__(self, parent=None):
        super().__init__(0, len(_COL_NAMES), parent)
        self.setHorizontalHeaderLabels(_COL_NAMES)
        self.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.setAlternatingRowColors(False)
        self.verticalHeader().setDefaultSectionSize(20)
        self.verticalHeader().setVisible(False)
        self.setStyleSheet(_STYLESHEET)
        self._rows: list[BlockRow] = []
        self._suppress = False
        self.itemSelectionChanged.connect(self._on_selection)
        self.itemDoubleClicked.connect(self._on_double_click)

    # -- public ----------------------------------------------------------------

    def load_rows(self, rows: list[BlockRow]) -> None:
        self._rows = rows
        self.setRowCount(0)
        self.setRowCount(len(rows))
        for r, row in enumerate(rows):
            bg = QBrush(_bg_for(row))
            vals = [
                str(row.sync_index),
                str(row.orig_index) if row.orig_index >= 0 else "-",
                row.block_type,
                f"{row.duration * 1e6:.3f}",
                "OK" if row.has_rf else "",
                "OK" if row.has_adc else "",
                "OK" if row.has_grad else "",
                row.delay_type if row.is_delay else "",
                str(row.gate_rf),
                str(row.gate_adc),
                str(row.gate_tr),
                f"{row.t_start * 1e6:.3f}",
            ]
            for c, val in enumerate(vals):
                item = QTableWidgetItem(val)
                item.setTextAlignment(Qt.AlignCenter)
                item.setBackground(bg)
                # Foreground intentionally not set: the OS palette Text role
                # provides the correct readable colour for the current theme.
                self.setItem(r, c, item)

    def select_by_sync_index(self, sync_index: int) -> None:
        self._suppress = True
        try:
            for r, row in enumerate(self._rows):
                if row.sync_index == sync_index:
                    self.selectRow(r)
                    self.scrollTo(self.model().index(r, 0))
                    break
        finally:
            self._suppress = False

    def row_for_sync_index(self, sync_index: int) -> BlockRow | None:
        for row in self._rows:
            if row.sync_index == sync_index:
                return row
        return None

    # -- private ---------------------------------------------------------------

    def _on_selection(self) -> None:
        if self._suppress:
            return
        selected = self.selectionModel().selectedRows()
        if selected:
            r = selected[0].row()
            if r < len(self._rows):
                self.blockSelected.emit(self._rows[r].sync_index)

    def _on_double_click(self, item) -> None:
        r = item.row()
        if r < len(self._rows):
            self.blockDoubleClicked.emit(self._rows[r].sync_index)
