"""
Tests for the onboarding flow.

Verifies that:
- TOPIC_CHOICES covers all expected categories
- run_onboarding wires up the prompter, client, and config store correctly
"""

from unittest.mock import MagicMock, patch

from skilark_cli.config_store import ConfigStore
from skilark_cli.onboarding import TOPIC_CHOICES, run_onboarding


def test_topic_choices_cover_key_sources():
    values = {t["value"] for t in TOPIC_CHOICES}
    assert "python" in values
    assert "java" in values
    assert "go" in values
    assert "docker" in values
    assert "kubernetes" in values
    assert "dsa" in values
    assert "sql" in values


def test_run_onboarding(tmp_path):
    with patch("skilark_cli.onboarding.inquirer") as mock_inq, \
         patch("skilark_cli.onboarding.SkilarkClient") as mock_client_cls:

        mock_prompt = MagicMock()
        mock_prompt.execute.return_value = ["python", "kubernetes"]
        mock_inq.checkbox.return_value = mock_prompt

        mock_client = MagicMock()
        mock_client.create_user.return_value = {
            "id": "12345678-1234-5678-1234-567812345678",
            "topics": ["python", "kubernetes"],
        }
        mock_client_cls.return_value = mock_client

        store = ConfigStore(config_dir=tmp_path)
        run_onboarding(store, api_url="http://localhost:8000")

        config = store.load()
        assert config["user_id"] == "12345678-1234-5678-1234-567812345678"
        assert config["topics"] == ["python", "kubernetes"]
        assert config["api_url"] == "http://localhost:8000"
        mock_client.create_user.assert_called_once_with(topics=["python", "kubernetes"])


def test_run_onboarding_dsa_with_python_language(tmp_path):
    """When DSA is selected, coding language prompt appears and is persisted."""
    with patch("skilark_cli.onboarding.inquirer") as mock_inq, \
         patch("skilark_cli.onboarding.SkilarkClient") as mock_client_cls:

        # Checkbox returns DSA in the selected topics.
        checkbox_prompt = MagicMock()
        checkbox_prompt.execute.return_value = ["dsa", "python"]

        # Select prompt returns "python" as coding language.
        select_prompt = MagicMock()
        select_prompt.execute.return_value = "python"

        mock_inq.checkbox.return_value = checkbox_prompt
        mock_inq.select.return_value = select_prompt

        mock_client = MagicMock()
        mock_client.create_user.return_value = {
            "id": "12345678-1234-5678-1234-567812345678",
            "topics": ["dsa", "python"],
        }
        mock_client_cls.return_value = mock_client

        store = ConfigStore(config_dir=tmp_path)
        run_onboarding(store, api_url="http://localhost:8000")

        config = store.load()
        assert config["coding_language"] == "python"
        # The select prompt was shown since DSA was selected.
        mock_inq.select.assert_called_once()


def test_run_onboarding_dsa_skip_coding(tmp_path):
    """When DSA selected but user skips coding problems, no coding_language saved."""
    with patch("skilark_cli.onboarding.inquirer") as mock_inq, \
         patch("skilark_cli.onboarding.SkilarkClient") as mock_client_cls:

        checkbox_prompt = MagicMock()
        checkbox_prompt.execute.return_value = ["dsa"]

        # User picks "Skip" — value is None.
        select_prompt = MagicMock()
        select_prompt.execute.return_value = None

        mock_inq.checkbox.return_value = checkbox_prompt
        mock_inq.select.return_value = select_prompt

        mock_client = MagicMock()
        mock_client.create_user.return_value = {
            "id": "12345678-1234-5678-1234-567812345678",
            "topics": ["dsa"],
        }
        mock_client_cls.return_value = mock_client

        store = ConfigStore(config_dir=tmp_path)
        run_onboarding(store, api_url="http://localhost:8000")

        config = store.load()
        # coding_language key should not be present when user skips.
        assert config.get("coding_language") is None


def test_run_onboarding_no_dsa_no_coding_prompt(tmp_path):
    """When DSA is not selected, coding language prompt is never shown."""
    with patch("skilark_cli.onboarding.inquirer") as mock_inq, \
         patch("skilark_cli.onboarding.SkilarkClient") as mock_client_cls:

        checkbox_prompt = MagicMock()
        checkbox_prompt.execute.return_value = ["python", "go"]
        mock_inq.checkbox.return_value = checkbox_prompt

        mock_client = MagicMock()
        mock_client.create_user.return_value = {
            "id": "12345678-1234-5678-1234-567812345678",
            "topics": ["python", "go"],
        }
        mock_client_cls.return_value = mock_client

        store = ConfigStore(config_dir=tmp_path)
        run_onboarding(store, api_url="http://localhost:8000")

        # select should NOT have been called — no DSA topic selected.
        mock_inq.select.assert_not_called()
