"""Tests for the connect command."""

import importlib
import json
from pathlib import Path
from unittest.mock import patch, MagicMock

import pytest
import yaml
from click.testing import CliRunner

from gjalla_precommit.commands.connect import connect

init_module = importlib.import_module("gjalla_precommit.commands.init")
cli_module = importlib.import_module("gjalla_precommit.cli")


@pytest.fixture
def git_repo(tmp_path):
    git_dir = tmp_path / ".git"
    git_dir.mkdir()
    (git_dir / "hooks").mkdir()
    return tmp_path


@pytest.fixture
def gjalla_repo(git_repo):
    """Git repo with .gjalla/config.yaml (no project linked)."""
    config = {"project_id": None, "api_url": "https://gjalla.io", "api_key_env": "GJALLA_API_KEY"}
    gjalla_dir = git_repo / ".gjalla"
    gjalla_dir.mkdir(exist_ok=True)
    (gjalla_dir / "config.yaml").write_text(yaml.dump(config, default_flow_style=False))
    return git_repo


class TestConnectCommand:
    """Tests for gjalla connect."""

    def test_connect_registered(self):
        """connect should be a registered CLI command."""
        assert "connect" in cli_module.main.commands

    def test_requires_gjalla_dir(self, git_repo, monkeypatch):
        """connect fails without .gjalla/ directory."""
        monkeypatch.chdir(git_repo)
        runner = CliRunner()
        result = runner.invoke(connect)
        assert result.exit_code == 1
        assert "gjalla init" in result.output.lower()

    def test_updates_config_with_project_id(self, gjalla_repo, monkeypatch, home_dir):
        """connect updates .gjalla/config.json with project_id."""
        monkeypatch.chdir(gjalla_repo)

        with patch("gjalla_precommit.commands.connect.verify_api_key", return_value=(True, "")), \
             patch("gjalla_precommit.commands.connect.discover_or_select_project", return_value={"id": 46, "name": "am-i-doing-it"}), \
             patch("gjalla_precommit.commands.sync._upload_attestations"):

            runner = CliRunner()
            result = runner.invoke(connect, ["--api-key", "gj_test_key", "--project-id", "46"])

        assert result.exit_code == 0, result.output
        config = yaml.safe_load((gjalla_repo / ".gjalla" / "config.yaml").read_text())
        assert config["project_id"] == 46

    def test_triggers_attestation_sync(self, gjalla_repo, monkeypatch, home_dir):
        """connect calls _upload_attestations after linking."""
        monkeypatch.chdir(gjalla_repo)

        with patch("gjalla_precommit.commands.connect.verify_api_key", return_value=(True, "")), \
             patch("gjalla_precommit.commands.connect.discover_or_select_project", return_value={"id": 46, "name": "test"}), \
             patch("gjalla_precommit.commands.sync._upload_attestations") as mock_upload:

            runner = CliRunner()
            result = runner.invoke(connect, ["--api-key", "gj_test_key", "--project-id", "46"])

        assert result.exit_code == 0, result.output
        mock_upload.assert_called_once()

    def test_saves_api_key_to_global_config(self, gjalla_repo, monkeypatch, home_dir):
        """connect saves API key to global ~/.gjalla/config.yaml."""
        monkeypatch.chdir(gjalla_repo)
        with patch("gjalla_precommit.commands.connect.verify_api_key", return_value=(True, "")), \
             patch("gjalla_precommit.commands.connect.discover_or_select_project", return_value={"id": 46, "name": "test"}), \
             patch("gjalla_precommit.commands.sync._upload_attestations"):

            runner = CliRunner()
            result = runner.invoke(connect, ["--api-key", "gj_saved_key", "--project-id", "46"])

        assert result.exit_code == 0, result.output
        # Verify global config was saved
        import yaml
        global_config_path = home_dir / ".gjalla" / "config.yaml"
        assert global_config_path.exists()
        global_config = yaml.safe_load(global_config_path.read_text())
        assert global_config["api_key"] == "gj_saved_key"
