"""
Merge dialog for resolving project conflicts visually
"""

from PyQt6.QtWidgets import (
    QDialog,
    QVBoxLayout,
    QHBoxLayout,
    QPushButton,
    QLabel,
    QListWidget,
    QListWidgetItem,
    QSplitter,
    QWidget,
    QScrollArea,
    QRadioButton,
    QButtonGroup,
    QTextEdit,
    QComboBox,
    QGroupBox,
)
from PyQt6.QtCore import Qt, QSize, pyqtSignal
from PyQt6.QtGui import QPixmap, QPainter, QColor, QFont, QPen

from typing import Dict, Any, List, Optional
from pyPhotoAlbum.merge_manager import MergeManager, ConflictInfo, MergeStrategy
from pyPhotoAlbum.page_renderer import PageRenderer


class PagePreviewWidget(QWidget):
    """Widget to render a page preview"""

    def __init__(self, page_data: Dict[str, Any], parent=None):
        super().__init__(parent)
        self.page_data = page_data
        self.setMinimumSize(200, 280)
        self.setSizePolicy(self.sizePolicy().Policy.Expanding, self.sizePolicy().Policy.Expanding)

    def paintEvent(self, event):
        """Render the page preview"""
        painter = QPainter(self)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)

        # Draw white background
        painter.fillRect(self.rect(), QColor(255, 255, 255))

        # Draw border
        painter.setPen(QPen(QColor(200, 200, 200), 2))
        painter.drawRect(self.rect().adjusted(1, 1, -1, -1))

        # Draw placeholder text
        painter.setPen(QColor(100, 100, 100))
        font = QFont("Arial", 10)
        painter.setFont(font)

        # Page info
        page_num = self.page_data.get("page_number", "?")
        element_count = len(self.page_data.get("layout", {}).get("elements", []))
        last_modified = self.page_data.get("last_modified", "Unknown")

        # Draw simplified representation
        y_offset = 20
        painter.drawText(10, y_offset, f"Page {page_num}")
        y_offset += 20
        painter.drawText(10, y_offset, f"Elements: {element_count}")
        y_offset += 20

        # Draw element representations
        elements = self.page_data.get("layout", {}).get("elements", [])
        for i, elem in enumerate(elements[:5]):  # Show first 5 elements
            elem_type = elem.get("type", "unknown")
            deleted = elem.get("deleted", False)

            color = QColor(200, 200, 200) if deleted else QColor(100, 150, 200)
            painter.setBrush(color)
            painter.setPen(QPen(color.darker(120), 1))

            # Draw small rectangle representing element
            x = 10 + (i % 3) * 60
            y = y_offset + (i // 3) * 60
            painter.drawRect(x, y, 50, 50)

            # Draw type label
            painter.setPen(QColor(0, 0, 0))
            painter.drawText(x + 5, y + 25, elem_type[:3].upper())

        # Draw timestamp at bottom
        painter.setPen(QColor(100, 100, 100))
        painter.setFont(QFont("Arial", 8))
        modified_text = last_modified[:19] if last_modified else "No timestamp"
        painter.drawText(10, self.height() - 10, modified_text)


class ConflictItemWidget(QWidget):
    """Widget for displaying and resolving a single conflict"""

    resolution_changed = pyqtSignal(int, str)  # conflict_index, choice ("ours" or "theirs")

    def __init__(self, conflict_index: int, conflict: ConflictInfo, parent=None):
        super().__init__(parent)
        self.conflict_index = conflict_index
        self.conflict = conflict

        self._init_ui()

    def _init_ui(self):
        """Initialize the UI"""
        layout = QVBoxLayout()

        # Conflict description
        desc_label = QLabel(f"<b>Conflict {self.conflict_index + 1}:</b> {self.conflict.description}")
        desc_label.setWordWrap(True)
        layout.addWidget(desc_label)

        # Splitter for side-by-side comparison
        splitter = QSplitter(Qt.Orientation.Horizontal)

        # Our version
        our_widget = QGroupBox("Your Version")
        our_layout = QVBoxLayout()

        if self.conflict.conflict_type.name.startswith("PAGE"):
            # Show page preview
            our_preview = PagePreviewWidget(self.conflict.our_version)
            our_layout.addWidget(our_preview)
        elif self.conflict.conflict_type.name.startswith("ELEMENT"):
            # Show element details
            our_details = self._create_element_details(self.conflict.our_version)
            our_layout.addWidget(our_details)
        else:
            # Show settings
            our_details = self._create_settings_details(self.conflict.our_version)
            our_layout.addWidget(our_details)

        our_widget.setLayout(our_layout)
        splitter.addWidget(our_widget)

        # Their version
        their_widget = QGroupBox("Other Version")
        their_layout = QVBoxLayout()

        if self.conflict.conflict_type.name.startswith("PAGE"):
            # Show page preview
            their_preview = PagePreviewWidget(self.conflict.their_version)
            their_layout.addWidget(their_preview)
        elif self.conflict.conflict_type.name.startswith("ELEMENT"):
            # Show element details
            their_details = self._create_element_details(self.conflict.their_version)
            their_layout.addWidget(their_details)
        else:
            # Show settings
            their_details = self._create_settings_details(self.conflict.their_version)
            their_layout.addWidget(their_details)

        their_widget.setLayout(their_layout)
        splitter.addWidget(their_widget)

        layout.addWidget(splitter)

        # Resolution buttons
        resolution_layout = QHBoxLayout()

        self.button_group = QButtonGroup(self)

        use_ours_btn = QRadioButton("Use Your Version")
        use_ours_btn.setChecked(True)
        use_ours_btn.toggled.connect(lambda checked: self._on_resolution_changed("ours") if checked else None)
        self.button_group.addButton(use_ours_btn)
        resolution_layout.addWidget(use_ours_btn)

        use_theirs_btn = QRadioButton("Use Other Version")
        use_theirs_btn.toggled.connect(lambda checked: self._on_resolution_changed("theirs") if checked else None)
        self.button_group.addButton(use_theirs_btn)
        resolution_layout.addWidget(use_theirs_btn)

        resolution_layout.addStretch()
        layout.addLayout(resolution_layout)

        self.setLayout(layout)

    def _create_element_details(self, element_data: Dict[str, Any]) -> QTextEdit:
        """Create a text widget showing element details"""
        details = QTextEdit()
        details.setReadOnly(True)
        details.setMaximumHeight(150)

        elem_type = element_data.get("type", "unknown")
        position = element_data.get("position", (0, 0))
        size = element_data.get("size", (0, 0))
        deleted = element_data.get("deleted", False)
        last_modified = element_data.get("last_modified", "Unknown")

        text = f"Type: {elem_type}\n"
        text += f"Position: ({position[0]:.1f}, {position[1]:.1f})\n"
        text += f"Size: ({size[0]:.1f} × {size[1]:.1f})\n"
        text += f"Deleted: {deleted}\n"
        text += f"Modified: {last_modified[:19] if last_modified else 'Unknown'}\n"

        if elem_type == "image":
            text += f"Image: {element_data.get('image_path', 'N/A')}\n"
        elif elem_type == "textbox":
            text += f"Text: {element_data.get('text_content', '')[:50]}...\n"

        details.setPlainText(text)
        return details

    def _create_settings_details(self, settings_data: Dict[str, Any]) -> QTextEdit:
        """Create a text widget showing settings details"""
        details = QTextEdit()
        details.setReadOnly(True)
        details.setMaximumHeight(150)

        text = ""
        for key, value in settings_data.items():
            if key != "last_modified":
                text += f"{key}: {value}\n"

        last_modified = settings_data.get("last_modified", "Unknown")
        text += f"\nModified: {last_modified[:19] if last_modified else 'Unknown'}"

        details.setPlainText(text)
        return details

    def _on_resolution_changed(self, choice: str):
        """Emit signal when resolution choice changes"""
        self.resolution_changed.emit(self.conflict_index, choice)

    def get_resolution(self) -> str:
        """Get the current resolution choice"""
        for button in self.button_group.buttons():
            if button.isChecked():
                if "Your" in button.text():
                    return "ours"
                else:
                    return "theirs"
        return "ours"  # Default


class MergeDialog(QDialog):
    """
    Dialog for visually resolving merge conflicts between two project versions
    """

    def __init__(self, our_project_data: Dict[str, Any], their_project_data: Dict[str, Any], parent=None):
        super().__init__(parent)

        self.our_project_data = our_project_data
        self.their_project_data = their_project_data
        self.merge_manager = MergeManager()

        # Detect conflicts
        self.conflicts = self.merge_manager.detect_conflicts(our_project_data, their_project_data)

        # Resolution choices (conflict_index -> "ours" or "theirs")
        self.resolutions: Dict[int, str] = {}

        # Initialize default resolutions (all "ours")
        for i in range(len(self.conflicts)):
            self.resolutions[i] = "ours"

        self.setWindowTitle("Merge Projects")
        self.resize(900, 700)

        self._init_ui()

    def _init_ui(self):
        """Initialize the user interface"""
        layout = QVBoxLayout()

        # Header
        header_label = QLabel(
            f"<h2>Merge Conflicts Detected</h2>"
            f"<p>Your project: <b>{self.our_project_data.get('name', 'Untitled')}</b> "
            f"(modified {self.our_project_data.get('last_modified', 'unknown')[:19]})</p>"
            f"<p>Other project: <b>{self.their_project_data.get('name', 'Untitled')}</b> "
            f"(modified {self.their_project_data.get('last_modified', 'unknown')[:19]})</p>"
            f"<p>Found <b>{len(self.conflicts)}</b> conflict(s) requiring resolution.</p>"
        )
        header_label.setWordWrap(True)
        layout.addWidget(header_label)

        # Auto-resolve strategy
        strategy_layout = QHBoxLayout()
        strategy_layout.addWidget(QLabel("Auto-resolve all:"))

        self.strategy_combo = QComboBox()
        self.strategy_combo.addItem("Latest Wins", MergeStrategy.LATEST_WINS)
        self.strategy_combo.addItem("Always Use Yours", MergeStrategy.OURS)
        self.strategy_combo.addItem("Always Use Theirs", MergeStrategy.THEIRS)
        strategy_layout.addWidget(self.strategy_combo)

        auto_resolve_btn = QPushButton("Auto-Resolve All")
        auto_resolve_btn.clicked.connect(self._auto_resolve)
        strategy_layout.addWidget(auto_resolve_btn)

        strategy_layout.addStretch()
        layout.addLayout(strategy_layout)

        # Scroll area for conflicts
        scroll = QScrollArea()
        scroll.setWidgetResizable(True)
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)

        conflicts_widget = QWidget()
        conflicts_layout = QVBoxLayout()

        # Create conflict widgets
        self.conflict_widgets: List[ConflictItemWidget] = []
        for i, conflict in enumerate(self.conflicts):
            conflict_widget = ConflictItemWidget(i, conflict)
            conflict_widget.resolution_changed.connect(self._on_resolution_changed)
            self.conflict_widgets.append(conflict_widget)
            conflicts_layout.addWidget(conflict_widget)

        conflicts_layout.addStretch()
        conflicts_widget.setLayout(conflicts_layout)
        scroll.setWidget(conflicts_widget)

        layout.addWidget(scroll)

        # Buttons
        button_layout = QHBoxLayout()
        button_layout.addStretch()

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

        merge_button = QPushButton("Apply Merge")
        merge_button.clicked.connect(self.accept)
        merge_button.setDefault(True)
        button_layout.addWidget(merge_button)

        layout.addLayout(button_layout)

        self.setLayout(layout)

    def _on_resolution_changed(self, conflict_index: int, choice: str):
        """Handle resolution choice change"""
        self.resolutions[conflict_index] = choice

    def _auto_resolve(self):
        """Auto-resolve all conflicts based on selected strategy"""
        strategy = self.strategy_combo.currentData()
        auto_resolutions = self.merge_manager.auto_resolve_conflicts(strategy)

        # Update resolution choices
        self.resolutions.update(auto_resolutions)

        # Update UI to reflect auto-resolutions
        for i, resolution in auto_resolutions.items():
            if i < len(self.conflict_widgets):
                # Find the correct radio button and check it
                for button in self.conflict_widgets[i].button_group.buttons():
                    if resolution == "ours" and "Your" in button.text():
                        button.setChecked(True)
                    elif resolution == "theirs" and "Other" in button.text():
                        button.setChecked(True)

    def get_merged_project_data(self) -> Dict[str, Any]:
        """
        Get the merged project data based on user's conflict resolutions.

        Returns:
            Merged project data dictionary
        """
        return self.merge_manager.apply_resolutions(self.our_project_data, self.their_project_data, self.resolutions)
