# -*- coding: utf-8 -*-
"""LVT4U — Big Icon Popup Widget (v3 — Light Theme).

Floating grid popup with light/white background, word-wrap labels,
and premium card-style buttons. No black backgrounds.

Author: Lộc Vũ Trung (LVT) / Slow Forest
"""

import os

from qgis.PyQt.QtCore import Qt, QPoint, QSize, pyqtSignal
from qgis.PyQt.QtGui import QIcon, QFont, QCursor, QColor, QPainter, QLinearGradient
from qgis.PyQt.QtWidgets import (
    QFrame, QGridLayout, QLabel, QVBoxLayout, QWidget,
    QScrollArea, QApplication, QGraphicsDropShadowEffect,
)

from .i18n import tr

# ── Light Palette ─────────────────────────────────────────────────────
_BG         = "#F5F7FA"   # popup background — very light grey
_BG_HDR     = "#FFFFFF"   # header background — white
_CARD_NORM  = "#FFFFFF"   # button card — white
_CARD_HOVER = "#EBF4FF"   # hover — very light blue
_CARD_PRESS = "#D0E8FF"   # pressed
_ACCENT     = "#1976D2"   # blue accent (Material Blue 700)
_ACCENT2    = "#0D47A1"   # darker accent for pressed
_SEC_BG     = "transparent"
_SEC_TEXT   = "#1976D2"   # section header — accent blue
_SEC_LINE   = "#DDEAFF"   # section divider
_TEXT       = "#263238"   # label text — dark grey
_BORDER     = "#D0DCE8"   # card border
_GLOW       = "#1976D2"   # hover glow border
_HDR_TEXT   = "#1565C0"   # header title

# ── Geometry ──────────────────────────────────────────────────────────
ICON_PX   = 48   # icon size
BTN_W     = 104  # card button width
BTN_H     = 90   # card button height
HEADER_H  = 40   # popup title strip
SEC_H     = 22   # section label row height
COLS_DEF  = 4    # default columns

# ─────────────────────────────────────────────────────────────────────
#  Custom module button — card style, no QToolButton
# ─────────────────────────────────────────────────────────────────────
class _ModuleButton(QFrame):
    """White card button: icon (top) + word-wrapped label (bottom)."""

    clicked = pyqtSignal()

    def __init__(self, icon: QIcon, label: str, parent=None):
        super().__init__(parent)
        self.setObjectName("LvtCard")
        self.setFixedSize(BTN_W, BTN_H)
        self.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
        self._apply_normal()

        lay = QVBoxLayout(self)
        lay.setContentsMargins(4, 8, 4, 6)
        lay.setSpacing(4)
        lay.setAlignment(Qt.AlignmentFlag.AlignHCenter)

        # ── Drop shadow ───────────────────────────────────────────────
        shadow = QGraphicsDropShadowEffect()
        shadow.setBlurRadius(8)
        shadow.setOffset(0, 2)
        shadow.setColor(QColor(0, 0, 0, 30))
        self.setGraphicsEffect(shadow)

        # ── Icon ──────────────────────────────────────────────────────
        self._ico_lbl = QLabel()
        self._ico_lbl.setFixedSize(ICON_PX, ICON_PX)
        self._ico_lbl.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self._ico_lbl.setStyleSheet("background: transparent; border: none;")
        if not icon.isNull():
            self._ico_lbl.setPixmap(icon.pixmap(ICON_PX, ICON_PX))
        lay.addWidget(self._ico_lbl, alignment=Qt.AlignmentFlag.AlignHCenter)

        # ── Word-wrap label ──────────────────────────────────────────
        self._txt = QLabel(tr(label))
        self._txt.setWordWrap(True)
        self._txt.setAlignment(
            Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop)
        self._txt.setFixedWidth(BTN_W - 8)
        fnt = QFont("Segoe UI", 8)
        fnt.setWeight(QFont.Weight.Medium)
        self._txt.setFont(fnt)
        self._txt.setStyleSheet(
            f"color:{_TEXT};background:transparent;border:none;")
        self._txt.setToolTip(tr(label))
        lay.addWidget(self._txt, alignment=Qt.AlignmentFlag.AlignHCenter)

    def _apply_normal(self):
        self.setStyleSheet(
            f"QFrame#LvtCard{{background:{_CARD_NORM};"
            f"border:1px solid {_BORDER};border-radius:8px;}}")

    def _apply_hover(self):
        self.setStyleSheet(
            f"QFrame#LvtCard{{background:{_CARD_HOVER};"
            f"border:1.5px solid {_GLOW};border-radius:8px;}}")

    def _apply_press(self):
        self.setStyleSheet(
            f"QFrame#LvtCard{{background:{_CARD_PRESS};"
            f"border:1.5px solid {_ACCENT2};border-radius:8px;}}")

    def enterEvent(self, e):
        self._apply_hover()
        super().enterEvent(e)

    def leaveEvent(self, e):
        self._apply_normal()
        super().leaveEvent(e)

    def mousePressEvent(self, e):
        if e.button() == Qt.MouseButton.LeftButton:
            self._apply_press()
        super().mousePressEvent(e)

    def mouseReleaseEvent(self, e):
        if e.button() == Qt.MouseButton.LeftButton:
            self._apply_hover()
            if self.rect().contains(e.pos()):
                self.clicked.emit()
        super().mouseReleaseEvent(e)


# ─────────────────────────────────────────────────────────────────────
#  Main popup
# ─────────────────────────────────────────────────────────────────────
class LvtBigPopup(QFrame):
    """Floating light-themed grid popup.

    Parameters
    ----------
    sections : list of (title_or_None, [(icon_file, label, callback), ...])
    """

    def __init__(self, parent, title, sections, icons_dir, cols=COLS_DEF):
        super().__init__(parent,
                         Qt.WindowType.Popup |
                         Qt.WindowType.FramelessWindowHint)
        self._icons_dir = icons_dir
        self._cols = max(1, cols)
        self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground, True)

        # Outer shadow frame
        outer_frame = QFrame(self)
        outer_frame.setObjectName("LvtPopup")
        outer_frame.setStyleSheet(
            "QFrame#LvtPopup{"
            f"background:{_BG};"
            "border:1px solid #C5D5E8;"
            "border-radius:12px;"
            "}"
        )
        shadow = QGraphicsDropShadowEffect()
        shadow.setBlurRadius(24)
        shadow.setOffset(0, 6)
        shadow.setColor(QColor(0, 0, 0, 60))
        outer_frame.setGraphicsEffect(shadow)

        main_lay = QVBoxLayout(self)
        main_lay.setContentsMargins(0, 0, 0, 0)
        main_lay.addWidget(outer_frame)

        inner_lay = QVBoxLayout(outer_frame)
        inner_lay.setContentsMargins(0, 0, 0, 0)
        inner_lay.setSpacing(0)

        # ── Title strip ───────────────────────────────────────────────
        hdr = QLabel(f"  {tr(title).upper()}  ")
        hdr.setFixedHeight(HEADER_H)
        hdr.setAlignment(Qt.AlignmentFlag.AlignCenter)
        hdr.setFont(QFont("Segoe UI", 10, QFont.Weight.Bold))
        hdr.setStyleSheet(
            f"background:{_BG_HDR};"
            f"color:{_HDR_TEXT};"
            "border:none;"
            "border-bottom:2px solid #1976D2;"
            "border-top-left-radius:12px;"
            "border-top-right-radius:12px;"
            "letter-spacing:2px;"
        )
        inner_lay.addWidget(hdr)

        # ── Grid content ──────────────────────────────────────────────
        content = QWidget()
        content.setStyleSheet(f"background:{_BG};border:none;")
        grid = QGridLayout(content)
        grid.setContentsMargins(10, 10, 10, 12)
        grid.setHorizontalSpacing(8)
        grid.setVerticalSpacing(8)

        row = 0
        for sec_title, items in sections:
            if sec_title:
                # Section label
                sec = QLabel(sec_title)
                sec.setFixedHeight(SEC_H)
                sec.setFont(QFont("Segoe UI", 8, QFont.Weight.Bold))
                sec.setStyleSheet(
                    f"color:{_SEC_TEXT};background:{_SEC_BG};"
                    "border:none;letter-spacing:1px;padding:2px 2px 0 2px;")
                grid.addWidget(sec, row, 0, 1, self._cols)
                row += 1
                # Divider
                line = QFrame()
                line.setFixedHeight(1)
                line.setStyleSheet(
                    f"background:{_SEC_LINE};border:none;margin-bottom:2px;")
                grid.addWidget(line, row, 0, 1, self._cols)
                row += 1

            col = 0
            for icon_name, label_text, callback in items:
                btn = _ModuleButton(self._icon(icon_name), label_text)
                btn.clicked.connect(callback)
                btn.clicked.connect(self.hide)
                grid.addWidget(btn, row, col,
                                alignment=Qt.AlignmentFlag.AlignTop)
                col += 1
                if col >= self._cols:
                    col = 0
                    row += 1
            if col > 0:
                row += 1

        # Scroll wrapper
        scroll = QScrollArea()
        scroll.setWidget(content)
        scroll.setWidgetResizable(True)
        scroll.setFrameShape(QFrame.Shape.NoFrame)
        scroll.setHorizontalScrollBarPolicy(
            Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        scroll.setStyleSheet(
            f"QScrollArea{{background:{_BG};border:none;}}"
            "QScrollBar:vertical{width:5px;background:#ECEFF1;"
            "border-radius:3px;}"
            "QScrollBar::handle:vertical{background:#90A4AE;"
            "border-radius:3px;min-height:20px;}"
            "QScrollBar::add-line:vertical,"
            "QScrollBar::sub-line:vertical{height:0px;}"
        )

        popup_w = self._cols * (BTN_W + 8) + 20
        scroll.setFixedWidth(popup_w)

        screen = QApplication.primaryScreen()
        max_h = int(screen.availableGeometry().height() * 0.8) if screen \
            else 600
        content.adjustSize()
        needed = content.sizeHint().height() + 12
        scroll.setFixedHeight(min(needed, max_h - HEADER_H - 20))

        inner_lay.addWidget(scroll)

    # ── Icon loader ────────────────────────────────────────────────────
    def _icon(self, name: str) -> QIcon:
        base, _ = os.path.splitext(name)
        for ext in (".svg", ".png"):
            path = os.path.join(self._icons_dir, base + ext)
            if os.path.isfile(path):
                return QIcon(path)
        return QIcon()

    # ── Popup positioning ──────────────────────────────────────────────
    def popup_at(self, global_pos: QPoint):
        self.adjustSize()
        w, h = self.width(), self.height()

        screen = QApplication.screenAt(global_pos)
        if screen is None:
            screen = QApplication.primaryScreen()
        geom = screen.availableGeometry() if screen else None

        x, y = global_pos.x(), global_pos.y()
        if geom:
            if x + w > geom.right():
                x = geom.right() - w
            if y + h > geom.bottom():
                y = global_pos.y() - h
            x = max(x, geom.left())
            y = max(y, geom.top())

        self.move(x, y)
        self.show()
        self.raise_()

    def keyPressEvent(self, e):
        if e.key() == Qt.Key.Key_Escape:
            self.hide()
        else:
            super().keyPressEvent(e)
