"""
Tests for ribbon_widget module
"""

import pytest
from unittest.mock import Mock, MagicMock, patch


class TestRibbonWidgetInit:
    """Tests for RibbonWidget initialization"""

    def test_init_with_custom_config(self, qtbot):
        """Test initialization with custom ribbon config"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget

        mock_main_window = Mock()
        config = {
            "File": {
                "groups": [
                    {"name": "Project", "actions": [{"label": "New", "action": "new_project", "tooltip": "Create new"}]}
                ]
            }
        }

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        assert widget.main_window == mock_main_window
        assert widget.ribbon_config == config
        assert widget.buttons_per_row == 4  # default

    def test_init_with_custom_buttons_per_row(self, qtbot):
        """Test initialization with custom buttons_per_row"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget

        mock_main_window = Mock()
        config = {"Test": {"groups": []}}

        widget = RibbonWidget(mock_main_window, ribbon_config=config, buttons_per_row=6)
        qtbot.addWidget(widget)

        assert widget.buttons_per_row == 6

    def test_init_creates_tab_widget(self, qtbot):
        """Test that initialization creates a tab widget"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget

        mock_main_window = Mock()
        config = {"Tab1": {"groups": []}}

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        assert widget.tab_widget is not None
        assert widget.tab_widget.count() == 1


class TestBuildRibbon:
    """Tests for _build_ribbon method"""

    def test_build_ribbon_creates_tabs(self, qtbot):
        """Test that _build_ribbon creates tabs from config"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget

        mock_main_window = Mock()
        config = {"File": {"groups": []}, "Edit": {"groups": []}, "View": {"groups": []}}

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        assert widget.tab_widget.count() == 3
        # Tab names should be present
        tab_names = [widget.tab_widget.tabText(i) for i in range(widget.tab_widget.count())]
        assert "File" in tab_names
        assert "Edit" in tab_names
        assert "View" in tab_names

    def test_build_ribbon_empty_config(self, qtbot):
        """Test _build_ribbon with empty config"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget

        mock_main_window = Mock()
        config = {}

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        assert widget.tab_widget.count() == 0


class TestCreateTab:
    """Tests for _create_tab method"""

    def test_create_tab_with_groups(self, qtbot):
        """Test tab creation with groups"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget

        mock_main_window = Mock()
        config = {"Test": {"groups": [{"name": "Group1", "actions": []}, {"name": "Group2", "actions": []}]}}

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        # Get the tab widget content
        tab_content = widget.tab_widget.widget(0)
        assert tab_content is not None

    def test_create_tab_empty_groups(self, qtbot):
        """Test tab creation with no groups"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget

        mock_main_window = Mock()
        config = {"Test": {"groups": []}}

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        tab_content = widget.tab_widget.widget(0)
        assert tab_content is not None


class TestCreateGroup:
    """Tests for _create_group method"""

    def test_create_group_with_actions(self, qtbot):
        """Test group creation with action buttons"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget
        from PyQt6.QtWidgets import QPushButton

        mock_main_window = Mock()
        config = {
            "Test": {
                "groups": [
                    {
                        "name": "Actions",
                        "actions": [
                            {"label": "Action1", "action": "do_action1"},
                            {"label": "Action2", "action": "do_action2"},
                        ],
                    }
                ]
            }
        }

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        tab_content = widget.tab_widget.widget(0)
        # Find buttons in the tab
        buttons = tab_content.findChildren(QPushButton)
        assert len(buttons) == 2

        button_labels = [btn.text() for btn in buttons]
        assert "Action1" in button_labels
        assert "Action2" in button_labels

    def test_create_group_respects_buttons_per_row(self, qtbot):
        """Test that group respects buttons_per_row from config"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget
        from PyQt6.QtWidgets import QPushButton

        mock_main_window = Mock()
        config = {
            "Test": {
                "groups": [
                    {
                        "name": "Grid",
                        "buttons_per_row": 2,
                        "actions": [
                            {"label": "A", "action": "a"},
                            {"label": "B", "action": "b"},
                            {"label": "C", "action": "c"},
                            {"label": "D", "action": "d"},
                        ],
                    }
                ]
            }
        }

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        tab_content = widget.tab_widget.widget(0)
        buttons = tab_content.findChildren(QPushButton)
        assert len(buttons) == 4


class TestCreateActionButton:
    """Tests for _create_action_button method"""

    def test_button_has_correct_label(self, qtbot):
        """Test that button has correct label"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget
        from PyQt6.QtWidgets import QPushButton

        mock_main_window = Mock()
        config = {"Test": {"groups": [{"name": "Test", "actions": [{"label": "My Button", "action": "my_action"}]}]}}

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        buttons = widget.tab_widget.widget(0).findChildren(QPushButton)
        assert len(buttons) == 1
        assert buttons[0].text() == "My Button"

    def test_button_has_tooltip(self, qtbot):
        """Test that button has correct tooltip"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget
        from PyQt6.QtWidgets import QPushButton

        mock_main_window = Mock()
        config = {
            "Test": {
                "groups": [
                    {"name": "Test", "actions": [{"label": "Button", "action": "action", "tooltip": "My tooltip"}]}
                ]
            }
        }

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        buttons = widget.tab_widget.widget(0).findChildren(QPushButton)
        assert buttons[0].toolTip() == "My tooltip"

    def test_button_without_tooltip(self, qtbot):
        """Test button without tooltip configured"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget
        from PyQt6.QtWidgets import QPushButton

        mock_main_window = Mock()
        config = {"Test": {"groups": [{"name": "Test", "actions": [{"label": "Button", "action": "action"}]}]}}

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        buttons = widget.tab_widget.widget(0).findChildren(QPushButton)
        assert buttons[0].toolTip() == ""

    def test_button_minimum_size(self, qtbot):
        """Test that button has minimum size set"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget
        from PyQt6.QtWidgets import QPushButton

        mock_main_window = Mock()
        config = {"Test": {"groups": [{"name": "Test", "actions": [{"label": "Button", "action": "action"}]}]}}

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        buttons = widget.tab_widget.widget(0).findChildren(QPushButton)
        assert buttons[0].minimumWidth() == 60
        assert buttons[0].minimumHeight() == 40


class TestExecuteAction:
    """Tests for _execute_action method"""

    def test_execute_action_calls_main_window_method(self, qtbot):
        """Test that _execute_action calls the method on main_window"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget

        mock_main_window = Mock()
        mock_main_window.my_action = Mock()

        config = {"Test": {"groups": []}}

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        widget._execute_action("my_action")

        mock_main_window.my_action.assert_called_once()

    def test_execute_action_missing_method_prints_warning(self, qtbot, capsys):
        """Test that _execute_action prints warning for missing method"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget

        mock_main_window = Mock(spec=[])  # No methods

        config = {"Test": {"groups": []}}

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        widget._execute_action("nonexistent_action")

        captured = capsys.readouterr()
        assert "Warning" in captured.out
        assert "nonexistent_action" in captured.out

    def test_execute_action_non_callable_not_called(self, qtbot):
        """Test that non-callable attributes are not called"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget

        mock_main_window = Mock()
        mock_main_window.not_a_method = "just a string"

        config = {"Test": {"groups": []}}

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        # Should not raise
        widget._execute_action("not_a_method")

    def test_button_click_executes_action(self, qtbot):
        """Test that clicking a button executes the action"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget
        from PyQt6.QtWidgets import QPushButton

        mock_main_window = Mock()
        mock_main_window.do_something = Mock()

        config = {"Test": {"groups": [{"name": "Test", "actions": [{"label": "Do It", "action": "do_something"}]}]}}

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        # Find the button and click it
        buttons = widget.tab_widget.widget(0).findChildren(QPushButton)
        assert len(buttons) == 1

        qtbot.mouseClick(buttons[0], Qt.MouseButton.LeftButton)

        mock_main_window.do_something.assert_called_once()


class TestGroupLabel:
    """Tests for group label creation"""

    def test_group_has_label(self, qtbot):
        """Test that group has a label"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget
        from PyQt6.QtWidgets import QLabel

        mock_main_window = Mock()
        config = {"Test": {"groups": [{"name": "My Group", "actions": []}]}}

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        tab_content = widget.tab_widget.widget(0)
        labels = tab_content.findChildren(QLabel)

        # Should have at least one label with the group name
        label_texts = [lbl.text() for lbl in labels]
        assert "My Group" in label_texts


class TestRibbonLayoutIntegration:
    """Integration tests for ribbon layout"""

    def test_full_ribbon_structure(self, qtbot):
        """Test complete ribbon structure with multiple tabs and groups"""
        from pyPhotoAlbum.ribbon_widget import RibbonWidget
        from PyQt6.QtWidgets import QPushButton

        mock_main_window = Mock()
        config = {
            "File": {
                "groups": [
                    {
                        "name": "Project",
                        "actions": [
                            {"label": "New", "action": "new_project"},
                            {"label": "Open", "action": "open_project"},
                            {"label": "Save", "action": "save_project"},
                        ],
                    },
                    {"name": "Export", "actions": [{"label": "Export PDF", "action": "export_pdf"}]},
                ]
            },
            "Edit": {
                "groups": [
                    {
                        "name": "Clipboard",
                        "actions": [{"label": "Copy", "action": "copy"}, {"label": "Paste", "action": "paste"}],
                    }
                ]
            },
        }

        widget = RibbonWidget(mock_main_window, ribbon_config=config)
        qtbot.addWidget(widget)

        # Check tabs
        assert widget.tab_widget.count() == 2

        # Check File tab has 4 buttons
        file_tab = widget.tab_widget.widget(0)
        file_buttons = file_tab.findChildren(QPushButton)
        assert len(file_buttons) == 4

        # Check Edit tab has 2 buttons
        edit_tab = widget.tab_widget.widget(1)
        edit_buttons = edit_tab.findChildren(QPushButton)
        assert len(edit_buttons) == 2


# Import Qt for click simulation
from PyQt6.QtCore import Qt
