"""
Frame picker dialog for pyPhotoAlbum

Dialog for selecting decorative frames to apply to images.
"""

from typing import Optional, Tuple
from PyQt6.QtWidgets import (
    QDialog,
    QVBoxLayout,
    QHBoxLayout,
    QLabel,
    QPushButton,
    QTabWidget,
    QWidget,
    QGridLayout,
    QScrollArea,
    QFrame,
    QGroupBox,
    QCheckBox,
)
from PyQt6.QtCore import Qt, pyqtSignal
from PyQt6.QtGui import QPainter, QColor, QPen

from pyPhotoAlbum.frame_manager import get_frame_manager, FrameCategory, FrameDefinition, FrameType


class FramePreviewWidget(QFrame):
    """Widget that shows a preview of a frame"""

    clicked = pyqtSignal(str)  # Emits frame name when clicked

    def __init__(self, frame: FrameDefinition, parent=None):
        super().__init__(parent)
        self.frame = frame
        self.selected = False
        self.setFixedSize(100, 100)
        self.setFrameStyle(QFrame.Shape.Box)
        self.setCursor(Qt.CursorShape.PointingHandCursor)

    def paintEvent(self, event):
        super().paintEvent(event)
        painter = QPainter(self)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)

        # Background
        if self.selected:
            painter.fillRect(self.rect(), QColor(200, 220, 255))
        else:
            painter.fillRect(self.rect(), QColor(245, 245, 245))

        # Draw a simple preview of the frame style
        margin = 15
        rect = self.rect().adjusted(margin, margin, -margin, -margin)

        # Draw "photo" placeholder
        painter.fillRect(rect, QColor(180, 200, 220))

        # Draw frame preview based on type
        pen = QPen(QColor(80, 80, 80))
        pen.setWidth(2)
        painter.setPen(pen)

        if self.frame.frame_type.value == "corners":
            # Draw corner decorations
            corner_size = 12
            x, y, w, h = rect.x(), rect.y(), rect.width(), rect.height()

            # Top-left
            painter.drawLine(x, y + corner_size, x, y)
            painter.drawLine(x, y, x + corner_size, y)

            # Top-right
            painter.drawLine(x + w - corner_size, y, x + w, y)
            painter.drawLine(x + w, y, x + w, y + corner_size)

            # Bottom-right
            painter.drawLine(x + w, y + h - corner_size, x + w, y + h)
            painter.drawLine(x + w, y + h, x + w - corner_size, y + h)

            # Bottom-left
            painter.drawLine(x + corner_size, y + h, x, y + h)
            painter.drawLine(x, y + h, x, y + h - corner_size)

        else:
            # Draw full border
            painter.drawRect(rect.adjusted(-3, -3, 3, 3))
            painter.drawRect(rect)

        # Draw frame name
        painter.setPen(QColor(0, 0, 0))
        text_rect = self.rect().adjusted(0, 0, 0, 0)
        text_rect.setTop(self.rect().bottom() - 20)
        painter.drawText(text_rect, Qt.AlignmentFlag.AlignCenter, self.frame.display_name)

    def mousePressEvent(self, event):
        self.clicked.emit(self.frame.name)

    def set_selected(self, selected: bool):
        self.selected = selected
        self.update()


class FramePickerDialog(QDialog):
    """Dialog for selecting a decorative frame"""

    def __init__(
        self,
        parent,
        current_frame: Optional[str] = None,
        current_color: Tuple[int, int, int] = (0, 0, 0),
        current_corners: Tuple[bool, bool, bool, bool] = (True, True, True, True),
    ):
        super().__init__(parent)
        self.setWindowTitle("Select Frame")
        self.setMinimumSize(500, 500)

        self.selected_frame: Optional[str] = current_frame
        self.frame_color = current_color
        self.frame_corners = current_corners  # (TL, TR, BR, BL)
        self.frame_widgets: dict[str, FramePreviewWidget] = {}

        self._setup_ui()

    def _setup_ui(self):
        layout = QVBoxLayout(self)

        # Tab widget for categories
        self.tab_widget = QTabWidget()

        # All frames tab
        all_tab = self._create_category_tab(None)
        self.tab_widget.addTab(all_tab, "All")

        # Category tabs
        for category in FrameCategory:
            tab = self._create_category_tab(category)
            self.tab_widget.addTab(tab, category.value.title())

        layout.addWidget(self.tab_widget)

        # Selected frame info
        info_group = QGroupBox("Selected Frame")
        info_layout = QVBoxLayout(info_group)

        # Frame name and color row
        name_color_layout = QHBoxLayout()
        self.selected_label = QLabel("None")
        name_color_layout.addWidget(self.selected_label)

        # Color button
        from pyPhotoAlbum.dialogs.style_dialogs import ColorButton

        name_color_layout.addWidget(QLabel("Color:"))
        self.color_btn = ColorButton(self.frame_color)
        name_color_layout.addWidget(self.color_btn)
        name_color_layout.addStretch()
        info_layout.addLayout(name_color_layout)

        # Corner selection (for corner-type frames)
        self.corners_group = QGroupBox("Corner Decorations")
        corners_layout = QGridLayout(self.corners_group)

        # Create a visual grid for corner checkboxes
        self.corner_tl = QCheckBox("Top-Left")
        self.corner_tl.setChecked(self.frame_corners[0])
        self.corner_tl.stateChanged.connect(self._update_corners)

        self.corner_tr = QCheckBox("Top-Right")
        self.corner_tr.setChecked(self.frame_corners[1])
        self.corner_tr.stateChanged.connect(self._update_corners)

        self.corner_br = QCheckBox("Bottom-Right")
        self.corner_br.setChecked(self.frame_corners[2])
        self.corner_br.stateChanged.connect(self._update_corners)

        self.corner_bl = QCheckBox("Bottom-Left")
        self.corner_bl.setChecked(self.frame_corners[3])
        self.corner_bl.stateChanged.connect(self._update_corners)

        corners_layout.addWidget(self.corner_tl, 0, 0)
        corners_layout.addWidget(self.corner_tr, 0, 1)
        corners_layout.addWidget(self.corner_bl, 1, 0)
        corners_layout.addWidget(self.corner_br, 1, 1)

        # Quick selection buttons
        quick_btns_layout = QHBoxLayout()
        all_btn = QPushButton("All")
        all_btn.clicked.connect(self._select_all_corners)
        none_btn = QPushButton("None")
        none_btn.clicked.connect(self._select_no_corners)
        diag_btn = QPushButton("Diagonal")
        diag_btn.clicked.connect(self._select_diagonal_corners)
        quick_btns_layout.addWidget(all_btn)
        quick_btns_layout.addWidget(none_btn)
        quick_btns_layout.addWidget(diag_btn)
        quick_btns_layout.addStretch()
        corners_layout.addLayout(quick_btns_layout, 2, 0, 1, 2)

        info_layout.addWidget(self.corners_group)

        layout.addWidget(info_group)

        # Update corners group visibility based on frame type
        self._update_corners_visibility()

        # Buttons
        button_layout = QHBoxLayout()

        clear_btn = QPushButton("No Frame")
        clear_btn.clicked.connect(self._clear_selection)
        button_layout.addWidget(clear_btn)

        button_layout.addStretch()

        ok_btn = QPushButton("OK")
        ok_btn.clicked.connect(self.accept)
        button_layout.addWidget(ok_btn)

        cancel_btn = QPushButton("Cancel")
        cancel_btn.clicked.connect(self.reject)
        button_layout.addWidget(cancel_btn)

        layout.addLayout(button_layout)

        # Update selection display
        self._update_selection_display()

    def _create_category_tab(self, category: Optional[FrameCategory]) -> QWidget:
        """Create a tab for a frame category"""
        widget = QWidget()
        layout = QVBoxLayout(widget)

        scroll = QScrollArea()
        scroll.setWidgetResizable(True)
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)

        content = QWidget()
        grid = QGridLayout(content)
        grid.setSpacing(10)

        frame_manager = get_frame_manager()

        if category:
            frames = frame_manager.get_frames_by_category(category)
        else:
            frames = frame_manager.get_all_frames()

        row, col = 0, 0
        max_cols = 4

        for frame in frames:
            preview = FramePreviewWidget(frame)
            preview.clicked.connect(self._on_frame_clicked)

            if frame.name == self.selected_frame:
                preview.set_selected(True)

            grid.addWidget(preview, row, col)
            self.frame_widgets[frame.name] = preview

            col += 1
            if col >= max_cols:
                col = 0
                row += 1

        # Add stretch at the bottom
        grid.setRowStretch(row + 1, 1)

        scroll.setWidget(content)
        layout.addWidget(scroll)

        return widget

    def _on_frame_clicked(self, frame_name: str):
        """Handle frame selection"""
        # Deselect previous
        if self.selected_frame and self.selected_frame in self.frame_widgets:
            self.frame_widgets[self.selected_frame].set_selected(False)

        # Select new
        self.selected_frame = frame_name
        if frame_name in self.frame_widgets:
            self.frame_widgets[frame_name].set_selected(True)

        self._update_selection_display()
        self._update_corners_visibility()

    def _clear_selection(self):
        """Clear frame selection"""
        if self.selected_frame and self.selected_frame in self.frame_widgets:
            self.frame_widgets[self.selected_frame].set_selected(False)
        self.selected_frame = None
        self._update_selection_display()
        self._update_corners_visibility()

    def _update_selection_display(self):
        """Update the selected frame label"""
        if self.selected_frame:
            frame = get_frame_manager().get_frame(self.selected_frame)
            if frame:
                self.selected_label.setText(f"{frame.display_name} - {frame.description}")
            else:
                self.selected_label.setText(self.selected_frame)
        else:
            self.selected_label.setText("None")

    def _update_corners(self):
        """Update corner selection from checkboxes"""
        self.frame_corners = (
            self.corner_tl.isChecked(),
            self.corner_tr.isChecked(),
            self.corner_br.isChecked(),
            self.corner_bl.isChecked(),
        )

    def _update_corners_visibility(self):
        """Show/hide corners group based on selected frame type"""
        if self.selected_frame:
            frame = get_frame_manager().get_frame(self.selected_frame)
            if frame and frame.frame_type == FrameType.CORNERS:
                self.corners_group.setVisible(True)
                return
        self.corners_group.setVisible(False)

    def _select_all_corners(self):
        """Select all corners"""
        self.corner_tl.setChecked(True)
        self.corner_tr.setChecked(True)
        self.corner_br.setChecked(True)
        self.corner_bl.setChecked(True)
        self._update_corners()

    def _select_no_corners(self):
        """Deselect all corners"""
        self.corner_tl.setChecked(False)
        self.corner_tr.setChecked(False)
        self.corner_br.setChecked(False)
        self.corner_bl.setChecked(False)
        self._update_corners()

    def _select_diagonal_corners(self):
        """Select diagonal corners (TL and BR)"""
        self.corner_tl.setChecked(True)
        self.corner_tr.setChecked(False)
        self.corner_br.setChecked(True)
        self.corner_bl.setChecked(False)
        self._update_corners()

    def get_values(self) -> Tuple[Optional[str], Tuple[int, int, int], Tuple[bool, bool, bool, bool]]:
        """Get selected frame name, color, and corner configuration"""
        return self.selected_frame, self.color_btn.get_color(), self.frame_corners
