"""Tests for vr usage commands."""

import json
import pytest
from unittest.mock import patch, Mock

from typer.testing import CliRunner

from vr_cli.cli import app


runner = CliRunner()

ORG_ID = "org-123"


@pytest.fixture
def mock_usage_report():
    return {
        "startDate": "2026-02-14",
        "endDate": "2026-03-16",
        "organizationId": ORG_ID,
        "usage": {
            "totalDurationMs": 3600000,
            "totalDurationMinutes": 60.0,
            "totalSessions": 150,
            "agentBreakdown": [
                {
                    "agentId": "agent-1",
                    "agentName": "Drive Thru Demo",
                    "durationMs": 2400000,
                    "durationMinutes": 40.0,
                    "sessionCount": 100,
                },
                {
                    "agentId": "agent-2",
                    "agentName": "Support Bot",
                    "durationMs": 1200000,
                    "durationMinutes": 20.0,
                    "sessionCount": 50,
                },
            ],
        },
    }


@pytest.fixture
def mock_usage_by_tags():
    return {
        "totalDurationMs": 3600000,
        "totalDurationMinutes": 60.0,
        "totalSessions": 150,
        "breakdown": [
            {
                "agentId": "agent-1",
                "agentName": "Drive Thru Demo",
                "tags": {"team": "sales", "region": "us-east"},
                "durationMs": 1800000,
                "durationMinutes": 30.0,
                "sessionCount": 75,
            },
            {
                "agentId": "agent-1",
                "agentName": "Drive Thru Demo",
                "tags": {"team": "support"},
                "durationMs": 600000,
                "durationMinutes": 10.0,
                "sessionCount": 25,
            },
        ],
    }


# ============================================================================
# Usage Report Tests
# ============================================================================


class TestUsageReport:
    """Tests for usage report command."""

    def test_report_success(self, mock_usage_report):
        with patch("vr_cli.commands.usage.get_effective_organization_id", return_value=ORG_ID), \
             patch("vr_cli.commands.usage.make_request", return_value={"data": mock_usage_report}):

            result = runner.invoke(app, ["usage", "report", "--table"])

        assert result.exit_code == 0
        assert "Drive Thru Demo" in result.output
        assert "Support Bot" in result.output
        assert "100" in result.output
        assert "150" in result.output

    def test_report_with_dates(self, mock_usage_report):
        with patch("vr_cli.commands.usage.get_effective_organization_id", return_value=ORG_ID), \
             patch("vr_cli.commands.usage.make_request", return_value={"data": mock_usage_report}) as mock_req:

            result = runner.invoke(app, ["usage", "report", "--start", "2026-03-01", "--end", "2026-03-15", "--table"])

        assert result.exit_code == 0
        mock_req.assert_called_once()
        call_url = mock_req.call_args[0][0]
        assert "startDate=2026-03-01" in call_url
        assert "endDate=2026-03-15" in call_url

    def test_report_defaults_to_30_days(self, mock_usage_report):
        with patch("vr_cli.commands.usage.get_effective_organization_id", return_value=ORG_ID), \
             patch("vr_cli.commands.usage.make_request", return_value={"data": mock_usage_report}) as mock_req:

            result = runner.invoke(app, ["usage", "report", "--table"])

        assert result.exit_code == 0
        call_url = mock_req.call_args[0][0]
        assert "startDate=" in call_url
        assert "endDate=" in call_url

    def test_report_json_output(self, mock_usage_report):
        with patch("vr_cli.commands.usage.get_effective_organization_id", return_value=ORG_ID), \
             patch("vr_cli.commands.usage.make_request", return_value={"data": mock_usage_report}):

            result = runner.invoke(app, ["usage", "report", "--json"])

        assert result.exit_code == 0
        output = json.loads(result.output)
        assert output["usage"]["totalSessions"] == 150

    def test_report_no_org(self):
        with patch("vr_cli.commands.usage.get_effective_organization_id", return_value=None):
            result = runner.invoke(app, ["usage", "report"])

        assert result.exit_code != 0
        assert "Unable to determine organization" in result.output

    def test_report_api_failure(self):
        with patch("vr_cli.commands.usage.get_effective_organization_id", return_value=ORG_ID), \
             patch("vr_cli.commands.usage.make_request", return_value=None):

            result = runner.invoke(app, ["usage", "report"])

        assert result.exit_code != 0
        assert "Failed to fetch" in result.output

    def test_report_by_tags(self, mock_usage_by_tags):
        with patch("vr_cli.commands.usage.get_effective_organization_id", return_value=ORG_ID), \
             patch("vr_cli.commands.usage.make_request", return_value={"data": mock_usage_by_tags}) as mock_req:

            result = runner.invoke(app, ["usage", "report", "--by-tags", "--start", "2026-03-01", "--end", "2026-03-15", "--table"])

        assert result.exit_code == 0
        call_url = mock_req.call_args[0][0]
        assert "/by-tags" in call_url
        assert "team:sales" in result.output
        assert "region:us-east" in result.output

    def test_report_by_tags_with_filter(self, mock_usage_by_tags):
        with patch("vr_cli.commands.usage.get_effective_organization_id", return_value=ORG_ID), \
             patch("vr_cli.commands.usage.make_request", return_value={"data": mock_usage_by_tags}) as mock_req:

            result = runner.invoke(app, ["usage", "report", "--by-tags", "--tags", '{"team":"sales"}', "--start", "2026-03-01", "--end", "2026-03-15", "--json"])

        assert result.exit_code == 0
        call_url = mock_req.call_args[0][0]
        assert "tags=" in call_url


# ============================================================================
# Usage Monthly Tests
# ============================================================================


class TestUsageMonthly:
    """Tests for usage monthly command."""

    def test_monthly_success(self, mock_usage_report):
        with patch("vr_cli.commands.usage.get_effective_organization_id", return_value=ORG_ID), \
             patch("vr_cli.commands.usage.make_request", return_value={"data": mock_usage_report}):

            result = runner.invoke(app, ["usage", "monthly", "--year", "2026", "--month", "3", "--table"])

        assert result.exit_code == 0
        assert "Drive Thru Demo" in result.output
        assert "Support Bot" in result.output

    def test_monthly_defaults_to_current(self, mock_usage_report):
        with patch("vr_cli.commands.usage.get_effective_organization_id", return_value=ORG_ID), \
             patch("vr_cli.commands.usage.make_request", return_value={"data": mock_usage_report}) as mock_req:

            result = runner.invoke(app, ["usage", "monthly", "--table"])

        assert result.exit_code == 0
        call_url = mock_req.call_args[0][0]
        assert "year=" in call_url
        assert "month=" in call_url

    def test_monthly_json_output(self, mock_usage_report):
        with patch("vr_cli.commands.usage.get_effective_organization_id", return_value=ORG_ID), \
             patch("vr_cli.commands.usage.make_request", return_value={"data": mock_usage_report}):

            result = runner.invoke(app, ["usage", "monthly", "--year", "2026", "--month", "3", "--json"])

        assert result.exit_code == 0
        output = json.loads(result.output)
        assert output["usage"]["totalSessions"] == 150

    def test_monthly_no_org(self):
        with patch("vr_cli.commands.usage.get_effective_organization_id", return_value=None):
            result = runner.invoke(app, ["usage", "monthly"])

        assert result.exit_code != 0
        assert "Unable to determine organization" in result.output

    def test_monthly_api_failure(self):
        with patch("vr_cli.commands.usage.get_effective_organization_id", return_value=ORG_ID), \
             patch("vr_cli.commands.usage.make_request", return_value=None):

            result = runner.invoke(app, ["usage", "monthly"])

        assert result.exit_code != 0
        assert "Failed to fetch" in result.output

    def test_monthly_by_tags(self, mock_usage_by_tags):
        with patch("vr_cli.commands.usage.get_effective_organization_id", return_value=ORG_ID), \
             patch("vr_cli.commands.usage.make_request", return_value={"data": mock_usage_by_tags}) as mock_req:

            result = runner.invoke(app, ["usage", "monthly", "--by-tags", "--year", "2026", "--month", "3", "--table"])

        assert result.exit_code == 0
        call_url = mock_req.call_args[0][0]
        assert "/by-tags" in call_url
        assert "team:sales" in result.output


# ============================================================================
# Help Tests
# ============================================================================


class TestUsageHelp:
    """Tests for usage command help output."""

    def test_usage_help(self):
        result = runner.invoke(app, ["usage", "--help"])
        assert result.exit_code == 0
        assert "report" in result.output
        assert "monthly" in result.output

    def test_usage_report_help(self):
        result = runner.invoke(app, ["usage", "report", "--help"])
        assert result.exit_code == 0
        assert "--start" in result.output
        assert "--end" in result.output
        assert "--by-tags" in result.output

    def test_usage_monthly_help(self):
        result = runner.invoke(app, ["usage", "monthly", "--help"])
        assert result.exit_code == 0
        assert "--year" in result.output
        assert "--month" in result.output
        assert "--by-tags" in result.output
