"""Tests for complyform.cli.feedback_cmd."""

from __future__ import annotations

import json
from unittest.mock import MagicMock, patch

import pytest
from typer.testing import CliRunner

from complyform.cli.main import app

runner = CliRunner()


@pytest.fixture()
def _mock_app_ctx() -> MagicMock:
    """Mock AppContext for feedback tests."""
    ctx = MagicMock()
    ctx.config.tier = "community"
    ctx.config.default_cloud = "gcp"
    ctx.console = MagicMock()
    return ctx


class TestFeedbackCmd:
    @patch(
        "complyform.core.diagnostics.get_diagnostics_string",
        return_value="complyform=0.1.0 python=3.14",
    )
    def test_json_format(
        self,
        mock_diag: MagicMock,
        _mock_app_ctx: MagicMock,
    ) -> None:
        result = runner.invoke(
            app,
            ["feedback", "--format=json"],
            obj=_mock_app_ctx,
        )
        assert result.exit_code == 0
        data = json.loads(result.stdout)
        assert "url" in data
        assert "diagnostics" in data
        assert "bug_report.yaml" in data["url"]

    @patch(
        "complyform.core.diagnostics.get_diagnostics_string",
        return_value="complyform=0.1.0 python=3.14",
    )
    def test_feature_template(
        self,
        mock_diag: MagicMock,
        _mock_app_ctx: MagicMock,
    ) -> None:
        result = runner.invoke(
            app,
            ["feedback", "--feature", "--format=json"],
            obj=_mock_app_ctx,
        )
        assert result.exit_code == 0
        data = json.loads(result.stdout)
        assert "feature_request.yaml" in data["url"]

    @patch(
        "complyform.core.diagnostics.get_diagnostics_string",
        return_value="complyform=0.1.0 python=3.14",
    )
    def test_title_prefill(
        self,
        mock_diag: MagicMock,
        _mock_app_ctx: MagicMock,
    ) -> None:
        result = runner.invoke(
            app,
            [
                "feedback",
                "--title",
                "My bug",
                "--format=json",
            ],
            obj=_mock_app_ctx,
        )
        assert result.exit_code == 0
        data = json.loads(result.stdout)
        assert "My+bug" in data["url"] or "My%20bug" in data["url"]

    @patch(
        "complyform.core.diagnostics.get_diagnostics_string",
        return_value="complyform=0.1.0 python=3.14",
    )
    def test_json_output_file(
        self,
        mock_diag: MagicMock,
        _mock_app_ctx: MagicMock,
        tmp_path: object,
    ) -> None:
        from pathlib import Path

        out = Path(str(tmp_path)) / "out.json"
        result = runner.invoke(
            app,
            [
                "feedback",
                "--format=json",
                "--output",
                str(out),
            ],
            obj=_mock_app_ctx,
        )
        assert result.exit_code == 0
        data = json.loads(out.read_text(encoding="utf-8"))
        assert "url" in data

    @patch(
        "complyform.core.diagnostics.get_diagnostics_string",
        return_value="complyform=0.1.0 python=3.14",
    )
    @patch("webbrowser.open", return_value=False)
    def test_terminal_no_tty(
        self,
        mock_wb: MagicMock,
        mock_diag: MagicMock,
        _mock_app_ctx: MagicMock,
    ) -> None:
        result = runner.invoke(
            app,
            ["feedback"],
            obj=_mock_app_ctx,
        )
        assert result.exit_code == 0

    @patch(
        "complyform.core.diagnostics.get_diagnostics_string",
        return_value="complyform=0.1.0 python=3.14",
    )
    def test_bug_default(
        self,
        mock_diag: MagicMock,
        _mock_app_ctx: MagicMock,
    ) -> None:
        result = runner.invoke(
            app,
            ["feedback", "--format=json"],
            obj=_mock_app_ctx,
        )
        data = json.loads(result.stdout)
        assert "bug_report.yaml" in data["url"]

    @patch(
        "complyform.core.diagnostics.get_diagnostics_string",
        return_value="complyform=0.1.0 python=3.14",
    )
    def test_bug_flag_overrides_feature(
        self,
        mock_diag: MagicMock,
        _mock_app_ctx: MagicMock,
    ) -> None:
        result = runner.invoke(
            app,
            [
                "feedback",
                "--bug",
                "--feature",
                "--format=json",
            ],
            obj=_mock_app_ctx,
        )
        data = json.loads(result.stdout)
        assert "bug_report.yaml" in data["url"]

    @patch(
        "complyform.core.diagnostics.get_diagnostics_string",
        return_value="complyform=0.1.0",
    )
    def test_diagnostics_in_url(
        self,
        mock_diag: MagicMock,
        _mock_app_ctx: MagicMock,
    ) -> None:
        result = runner.invoke(
            app,
            ["feedback", "--format=json"],
            obj=_mock_app_ctx,
        )
        data = json.loads(result.stdout)
        assert "complyform" in data["diagnostics"]
