from __future__ import annotations

import json
import tempfile
from pathlib import Path
from unittest.mock import patch

import pytest
from pytestqt.qtbot import QtBot

from pytola_llm.llmserver.gui import LlamaServerGUI, LLMServerConfig


class TestLlamaServerGUI:
    """Tests for LlamaServerGUI component."""

    @pytest.mark.skip(reason="GUI tests cause UI interference, skipping to avoid user experience issues")
    def test_gui_initialization(self, qtbot: QtBot) -> None:
        """Test GUI initialization."""
        gui = LlamaServerGUI()
        qtbot.addWidget(gui)

        # Verify GUI is created successfully
        assert gui is not None
        assert hasattr(gui, "process")
        assert hasattr(gui, "model_path_input")
        assert hasattr(gui, "port_spin")
        assert hasattr(gui, "threads_spin")

    @pytest.mark.skip(reason="GUI tests cause UI interference, skipping to avoid user experience issues")
    def test_gui_default_values(self, qtbot: QtBot) -> None:
        """Test GUI default values are set correctly."""
        gui = LlamaServerGUI()
        qtbot.addWidget(gui)

        # Check default values
        assert gui.port_spin.value() == 8080
        assert gui.threads_spin.value() == 4
        assert gui.model_path_input.placeholderText() == "Choose model file..."

    @pytest.mark.skip(reason="GUI tests cause UI interference, skipping to avoid user experience issues")
    def test_gui_config_loading(self, qtbot: QtBot) -> None:
        """Test GUI loads configuration correctly."""
        with tempfile.TemporaryDirectory() as temp_dir:
            temp_config_file = Path(temp_dir) / "llmserver.json"
            config_data = {
                "MODEL_PATH": "/test/model.gguf",
                "LISTEN_PORT": 9000,
                "THREAD_COUNT": 6,
            }
            temp_config_file.write_text(json.dumps(config_data))

            with patch("pytola_llm.llmserver.gui.CONFIG_FILE", temp_config_file):
                gui = LlamaServerGUI()
                qtbot.addWidget(gui)

                # Verify GUI reflects loaded configuration
                assert gui.model_path_input.text() == "/test/model.gguf"
                assert gui.port_spin.value() == 9000
                assert gui.threads_spin.value() == 6

    @pytest.mark.skip(reason="GUI tests cause UI interference, skipping to avoid user experience issues")
    def test_model_selection_dialog(self, qtbot: QtBot) -> None:
        """Test model file selection dialog method exists."""
        gui = LlamaServerGUI()
        qtbot.addWidget(gui)

        # Test that the method exists and is callable
        assert hasattr(gui, "on_load_model")
        assert callable(gui.on_load_model)

    @pytest.mark.skip(reason="GUI tests cause UI interference, skipping to avoid user experience issues")
    def test_server_control_methods(self, qtbot: QtBot) -> None:
        """Test server control methods exist."""
        gui = LlamaServerGUI()
        qtbot.addWidget(gui)

        # Test method existence
        assert hasattr(gui, "toggle_server")
        assert hasattr(gui, "start_server")
        assert hasattr(gui, "stop_server")
        assert callable(gui.toggle_server)
        assert callable(gui.start_server)
        assert callable(gui.stop_server)

    @pytest.mark.skip(reason="GUI tests cause UI interference, skipping to avoid user experience issues")
    def test_browser_launch_method(self, qtbot: QtBot) -> None:
        """Test browser launch method exists."""
        gui = LlamaServerGUI()
        qtbot.addWidget(gui)

        assert hasattr(gui, "on_start_browser")
        assert callable(gui.on_start_browser)

    @pytest.mark.skip(reason="GUI tests cause UI interference, skipping to avoid user experience issues")
    def test_output_formatting_methods(self, qtbot: QtBot) -> None:
        """Test output formatting methods exist."""
        gui = LlamaServerGUI()
        qtbot.addWidget(gui)

        assert hasattr(gui, "append_output")
        assert hasattr(gui, "create_text_format")
        assert callable(gui.append_output)
        assert callable(gui.create_text_format)

    @pytest.mark.skip(reason="GUI tests cause UI interference, skipping to avoid user experience issues")
    def test_ui_state_updates(self, qtbot: QtBot) -> None:
        """Test UI state update methods exist."""
        gui = LlamaServerGUI()
        qtbot.addWidget(gui)

        assert hasattr(gui, "update_ui_state")
        assert callable(gui.update_ui_state)

    @pytest.mark.skip(reason="GUI tests cause UI interference, skipping to avoid user experience issues")
    def test_window_event_handlers(self, qtbot: QtBot) -> None:
        """Test window event handlers exist."""
        gui = LlamaServerGUI()
        qtbot.addWidget(gui)

        assert hasattr(gui, "moveEvent")
        assert hasattr(gui, "resizeEvent")
        assert hasattr(gui, "closeEvent")
        assert callable(gui.moveEvent)
        assert callable(gui.resizeEvent)
        assert callable(gui.closeEvent)


class TestIntegration:
    """Integration tests for llmserver module."""

    def test_import_main_function(self) -> None:
        """Test that main function can be imported."""
        from pytola_llm.llmserver.gui import main

        assert callable(main)

    def test_config_import(self) -> None:
        """Test that configuration class can be imported."""
        config = LLMServerConfig()
        assert isinstance(config, LLMServerConfig)

    def test_gui_import(self) -> None:
        """Test that GUI class can be imported."""
        from pytola_llm.llmserver.gui import LlamaServerGUI

        # Don't instantiate to avoid GUI display
        assert LlamaServerGUI.__name__ == "LlamaServerGUI"


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
