"""Tests for the integration registry (__init__.py)."""

from __future__ import annotations

from unittest.mock import MagicMock, patch

import pytest


class TestGetAvailableIntegrations:
    """Test the central get_available_integrations() function."""

    @patch("alive.integrations._load_config", return_value={})
    @patch("alive.integrations._check_playwright", return_value=False)
    @patch("alive.integrations._check_daemon", return_value=False)
    @patch("alive.integrations._count_schedules", return_value=0)
    def test_default_state(self, mock_sched, mock_daemon, mock_pw, mock_cfg):
        from alive.integrations import get_available_integrations

        result = get_available_integrations()

        # Web search always configured
        assert result["web_search"]["configured"] is True
        assert result["web_search"]["backend"] == "duckduckgo"

        # Telegram not configured
        assert result["telegram"]["configured"] is False

        # Scheduler always available
        assert result["scheduler"]["configured"] is True
        assert result["scheduler"]["daemon_running"] is False

        # Browser not configured
        assert result["browser"]["configured"] is False

        # Webhook not configured
        assert result["webhook"]["configured"] is False

    @patch("alive.integrations._load_config", return_value={"tavily_key": "tvly-xxx"})
    @patch("alive.integrations._check_playwright", return_value=True)
    @patch("alive.integrations._check_daemon", return_value=True)
    @patch("alive.integrations._count_schedules", return_value=3)
    def test_fully_configured(self, mock_sched, mock_daemon, mock_pw, mock_cfg):
        from alive.integrations import get_available_integrations

        result = get_available_integrations()

        assert result["web_search"]["backend"] == "tavily"
        assert result["browser"]["configured"] is True
        assert result["scheduler"]["daemon_running"] is True
        assert result["scheduler"]["active_tasks"] == 3

    @patch("alive.integrations._load_config", return_value={
        "telegram_token": "tok123",
        "webhooks": {"slack": {"url": "https://hooks.slack.com/test", "type": "slack"}},
    })
    @patch("alive.integrations._check_playwright", return_value=False)
    @patch("alive.integrations._check_daemon", return_value=False)
    @patch("alive.integrations._count_schedules", return_value=0)
    def test_telegram_and_webhook_configured(self, mock_sched, mock_daemon, mock_pw, mock_cfg):
        from alive.integrations import get_available_integrations

        # Patch _get_bot_name to avoid real API call
        with patch("alive.integrations.telegram._get_bot_name", return_value="@test_bot"):
            result = get_available_integrations()

        assert result["telegram"]["configured"] is True
        assert result["telegram"]["bot_name"] == "@test_bot"
        assert result["webhook"]["configured"] is True
        assert result["webhook"]["count"] == 1
        assert "slack" in result["webhook"]["names"]


class TestCheckDaemon:
    """Test daemon status checking."""

    def test_no_pid_file(self, tmp_path):
        from alive.integrations import _check_daemon

        with patch("alive.config.ALIVE_HOME", tmp_path):
            assert _check_daemon() is False

    def test_stale_pid(self, tmp_path):
        from alive.integrations import _check_daemon

        pid_file = tmp_path / "daemon.pid"
        pid_file.write_text("999999999")

        with patch("alive.config.ALIVE_HOME", tmp_path):
            assert _check_daemon() is False


class TestCountSchedules:
    """Test schedule counting."""

    def test_no_file(self, tmp_path):
        from alive.integrations import _count_schedules

        with patch("alive.config.ALIVE_HOME", tmp_path):
            assert _count_schedules() == 0

    def test_counts_enabled_only(self, tmp_path):
        import json

        from alive.integrations import _count_schedules

        schedule_file = tmp_path / "schedules.json"
        schedule_file.write_text(json.dumps([
            {"enabled": True},
            {"enabled": True},
            {"enabled": False},
        ]))

        with patch("alive.config.ALIVE_HOME", tmp_path):
            assert _count_schedules() == 2


class TestDisplayIntegrations:
    """Test display_integrations function."""

    @patch("alive.integrations.get_available_integrations")
    def test_display_does_not_crash(self, mock_get):
        from alive.integrations import display_integrations

        mock_get.return_value = {
            "web_search": {"configured": True, "backend": "duckduckgo"},
            "telegram": {"configured": False, "bot_name": None},
            "scheduler": {"configured": True, "daemon_running": False, "active_tasks": 0},
            "browser": {"configured": False},
            "webhook": {"configured": False, "count": 0, "names": []},
        }

        con = MagicMock()
        display_integrations(console=con)
        con.print.assert_called()


class TestLoadSaveConfig:
    """Test config loading and saving."""

    def test_load_missing_config(self, tmp_path):
        from alive.integrations import _load_config

        with patch("alive.config.CONFIG_FILE", tmp_path / "nonexistent.json"):
            cfg = _load_config()
            assert cfg == {}

    def test_save_and_load(self, tmp_path):
        import json

        from alive.integrations import _load_config, _save_config

        config_file = tmp_path / "config.json"

        with patch("alive.config.CONFIG_FILE", config_file):
            _save_config({"key": "value"})
            cfg = _load_config()
            assert cfg == {"key": "value"}
