import logging

from typing import Callable, Optional

from PyQt6.QtCore import QSize, Qt
from PyQt6.QtGui import QColor, QIcon, QMouseEvent, QPainter, QPixmap
from PyQt6.QtSvg import QSvgRenderer
from PyQt6.QtWidgets import (
    QFrame,
    QHBoxLayout,
    QLabel,
    QPushButton,
    QSizePolicy,
    QWidget,
)
from titlebar_assets import CLOSE, MAXIMIZE, MINIMIZE, GEAR_SVG, POWER_SVG
from version import VERSION

logger = logging.getLogger(__name__)


class TitleBar(QFrame):
    def __init__(self, parent: QWidget, accent_color: str = "#FFFFFF"):
        super().__init__(parent)
        self.parent_window = parent
        self.drag_pos = None
        self._accent_color = accent_color
        self.setFixedHeight(32)
        self.setObjectName("TitleBar")
        self.no_previous_state = True

        self.title_label: Optional[QLabel] = None
        self.version_label: Optional[QLabel] = None
        self.settings_button: Optional[QPushButton] = None
        self.minimize_button: Optional[QPushButton] = None
        self.maximize_button: Optional[QPushButton] = None
        self.close_button: Optional[QPushButton] = None

        self._setup_ui()
        self._apply_style()

    def set_accent_color(self, color: str) -> None:
        self._accent_color = color
        self._update_button_colors()

    def _setup_ui(self) -> None:
        layout = QHBoxLayout(self)
        layout.setContentsMargins(5, 0, 5, 0)
        layout.setSpacing(5)

        left_widget = self._create_left_section()
        right_widget = self._create_right_section()

        self.title_label = QLabel("PROTOCOL 7")
        self.title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.title_label.setSizePolicy(
            QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred
        )

        layout.addWidget(left_widget, 0, Qt.AlignmentFlag.AlignLeft)
        layout.addWidget(self.title_label, 1)
        layout.addWidget(right_widget, 0, Qt.AlignmentFlag.AlignRight)

    def _create_left_section(self) -> QWidget:
        widget = QWidget()
        layout = QHBoxLayout(widget)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(8)

        self.version_label = QLabel(f"v{VERSION}")
        self.version_label.setStyleSheet("color: #888888;")
        self.version_label.setToolTip("Version")
        layout.addWidget(self.version_label, alignment=Qt.AlignmentFlag.AlignLeft)

        widget.setMinimumSize(widget.sizeHint())
        widget.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
        return widget

    def _create_right_section(self) -> QWidget:
        widget = QWidget()
        layout = QHBoxLayout(widget)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(2)
        layout.addStretch()

        self.settings_button = self._create_svg_button(
            GEAR_SVG,
            getattr(self.parent_window, "open_settings_dialog", None),
            "Settings",
        )
        layout.addWidget(self.settings_button)

        self.minimize_button = self._create_svg_button(
            MINIMIZE, self._minimize_window, "Minimize"
        )
        layout.addWidget(self.minimize_button)

        self.maximize_button = self._create_svg_button(
            MAXIMIZE, self._maximize_window, "Maximize"
        )
        layout.addWidget(self.maximize_button)

        self.close_button = self._create_svg_button(
            POWER_SVG, self._close_window, "Shutdown"
        )
        layout.addWidget(self.close_button)

        return widget

    def _apply_style(self) -> None:
        self.setStyleSheet("QFrame { background-color: #000000; }")
        self._update_button_styles()
        self._update_button_colors()

    def update_style(self) -> None:
        self._update_button_styles()
        self._update_button_colors()

    def _update_button_styles(self) -> None:
        button_style = """
            QPushButton {
                background-color: #000000;
                border: none;
                border-radius: 3px;
                padding: 1px;
            }
            QPushButton:hover {
                background-color: #1a1a1a;
            }
        """
        for button in [
            self.minimize_button,
            self.maximize_button,
            self.settings_button,
            self.close_button,
        ]:
            if button:
                button.setStyleSheet(button_style)

    def _update_button_colors(self) -> None:
        accent_color = getattr(self, "_accent_color", "#FFFFFF")
        buttons = [
            (self.minimize_button, MINIMIZE),
            (self.maximize_button, MAXIMIZE),
            (self.settings_button, GEAR_SVG),
            (self.close_button, POWER_SVG),
        ]
        for button, svg_data in buttons:
            if button:
                self._update_svg_button_color(button, svg_data, accent_color)

    @staticmethod
    def _build_svg_pixmap(svg_data: str, color: QColor) -> QPixmap:
        renderer = QSvgRenderer(svg_data.encode("utf-8"))
        icon_size = QSize(16, 16)

        pixmap = QPixmap(icon_size)
        pixmap.fill(Qt.GlobalColor.transparent)
        painter = QPainter(pixmap)

        painter.setRenderHint(QPainter.RenderHint.Antialiasing)
        renderer.render(painter)

        painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceIn)
        painter.fillRect(pixmap.rect(), color)
        painter.end()

        return pixmap

    def _update_svg_button_color(
        self, button: QPushButton, svg_data: str, color: str
    ) -> None:
        try:
            pixmap = self._build_svg_pixmap(svg_data, QColor(color))
            button.setIcon(QIcon(pixmap))
        except Exception as e:
            logger.error(f"Failed to update SVG button color: {e}", exc_info=True)

    def _create_svg_button(
        self,
        svg_data: str,
        on_click: Optional[Callable[[], None]],
        tooltip: str,
    ) -> QPushButton:
        try:
            button = QPushButton()
            button.setToolTip(tooltip)

            pixmap = self._build_svg_pixmap(svg_data, QColor("#FFFFFF"))
            button.setIcon(QIcon(pixmap))
            button.setIconSize(pixmap.size())
            button.setFixedSize(20, 20)

            if on_click:
                button.clicked.connect(on_click)
            return button

        except Exception as e:
            logger.error(f"Failed to create SVG button: {e}", exc_info=True)
            fallback_button = QPushButton("X")
            fallback_button.setFixedSize(20, 20)
            if on_click:
                fallback_button.clicked.connect(on_click)
            return fallback_button

    def _minimize_window(self) -> None:
        self.parent_window.showMinimized()

    def _maximize_window(self) -> None:
        if self.parent_window.isMaximized():
            self.parent_window.showNormal()
        else:
            self.parent_window.showMaximized()

    def _close_window(self) -> None:
        self.parent_window.close()

    def mousePressEvent(self, event: QMouseEvent) -> None:
        if event.button() != Qt.MouseButton.LeftButton:
            event.accept()
            return

        window = self.window().windowHandle()
        if window is not None:
            window.startSystemMove()

        event.accept()
