# -*- coding: utf-8 -*-
"""Editor for the user's custom classification scheme.

A simple table: code (int), name (text), colour. The user can add and
remove rows and pick a colour per class. Returned as [(code, name, hex)].
"""

from qgis.PyQt.QtWidgets import (
    QDialog, QVBoxLayout, QHBoxLayout, QTableWidget, QTableWidgetItem,
    QPushButton, QLabel, QColorDialog, QDialogButtonBox, QMessageBox,
    QSpinBox,
)
from qgis.PyQt.QtGui import QColor


class CustomClassesDialog(QDialog):
    def __init__(self, classes, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Custom classification classes")
        self.resize(460, 420)
        self._build()
        self._load(classes)

    def _build(self):
        v = QVBoxLayout(self)
        v.addWidget(QLabel(
            "Define your own classes. Code must be a unique whole number; "
            "it is what gets written to each labeled point and used by the "
            "classifier."))
        self.table = QTableWidget(0, 3)
        self.table.setHorizontalHeaderLabels(["Code", "Name", "Colour"])
        self.table.setColumnWidth(0, 70)
        self.table.setColumnWidth(1, 240)
        self.table.setColumnWidth(2, 90)
        v.addWidget(self.table, 1)

        h = QHBoxLayout()
        b_add = QPushButton("Add class")
        b_add.clicked.connect(self._add_row)
        b_del = QPushButton("Remove selected")
        b_del.clicked.connect(self._del_row)
        h.addWidget(b_add)
        h.addWidget(b_del)
        h.addStretch()
        v.addLayout(h)

        bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
        bb.accepted.connect(self._accept)
        bb.rejected.connect(self.reject)
        v.addWidget(bb)

    def _load(self, classes):
        if not classes:
            # seed one example row so the table isn't empty
            self._add_row(1, "Class 1", "#3fa34d")
            return
        for code, name, color in classes:
            self._add_row(code, name, color)

    def _add_row(self, code=None, name="", color="#888888"):
        r = self.table.rowCount()
        self.table.insertRow(r)
        sp = QSpinBox()
        sp.setRange(1, 9999)
        # default to next code
        sp.setValue(int(code) if code is not None else self._next_code())
        self.table.setCellWidget(r, 0, sp)
        self.table.setItem(r, 1, QTableWidgetItem(name))
        btn = QPushButton()
        btn.setStyleSheet("background-color: {};".format(color))
        btn._hex = color
        btn.clicked.connect(lambda _, b=btn: self._pick_color(b))
        self.table.setCellWidget(r, 2, btn)

    def _next_code(self):
        mx = 0
        for r in range(self.table.rowCount()):
            w = self.table.cellWidget(r, 0)
            if w is not None:
                mx = max(mx, w.value())
        return mx + 1

    def _del_row(self):
        rows = sorted({i.row() for i in self.table.selectedIndexes()},
                      reverse=True)
        for r in rows:
            self.table.removeRow(r)

    def _pick_color(self, btn):
        c = QColorDialog.getColor(QColor(btn._hex), self, "Pick class colour")
        if c.isValid():
            btn._hex = c.name()
            btn.setStyleSheet("background-color: {};".format(c.name()))

    def classes(self):
        out = []
        for r in range(self.table.rowCount()):
            sp = self.table.cellWidget(r, 0)
            name_item = self.table.item(r, 1)
            col_btn = self.table.cellWidget(r, 2)
            code = sp.value() if sp else r + 1
            name = (name_item.text().strip() if name_item else "")
            color = getattr(col_btn, "_hex", "#888888")
            if name:
                out.append((code, name, color))
        return out

    def _accept(self):
        cls = self.classes()
        if not cls:
            QMessageBox.warning(self, "No classes",
                                "Add at least one class with a name.")
            return
        codes = [c for c, _, _ in cls]
        if len(set(codes)) != len(codes):
            QMessageBox.warning(self, "Duplicate codes",
                                "Each class needs a unique code.")
            return
        self.accept()
