from __future__ import annotations

"""SDK analytics resource tests — mocked HTTP."""

import os
import sys

sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

from nexure import (
    AnalyticsComparisons,
    AnalyticsDrift,
    AnalyticsOverrides,
    AnalyticsOverview,
    Nexure,
    VisibilityScore,
)
from pytest_httpx import HTTPXMock

MOCK_OVERVIEW = {
    "total_decisions": 4000,
    "decisions_in_period": 650,
    "override_rate": 0.18,
    "avg_trust_score": 72.5,
    "action_breakdown": [
        {"action": "approve", "count": 2800, "percentage": 70.0},
        {"action": "deny", "count": 1200, "percentage": 30.0},
    ],
    "decisions_by_day": [
        {"date": "2025-01-15", "count": 34},
        {"date": "2025-01-16", "count": 28},
    ],
    "tenant_id": "tenant_dev",
    "period_start": "2025-01-01T00:00:00Z",
    "period_end": "2025-01-31T00:00:00Z",
}

MOCK_OVERRIDES = {
    "team_override_rate": 0.18,
    "reviewers": [
        {
            "reviewer": "M. Johnson",
            "total_decisions": 1000,
            "overrides": 410,
            "override_rate": 0.41,
            "is_anomaly": True,
            "deviation_from_mean": 2.3,
            "override_direction": {"allow_to_block": 320, "block_to_allow": 50, "other": 40},
        },
        {
            "reviewer": "S. Chen",
            "total_decisions": 1200,
            "overrides": 144,
            "override_rate": 0.12,
            "is_anomaly": False,
            "deviation_from_mean": 0.7,
            "override_direction": {"allow_to_block": 80, "block_to_allow": 40, "other": 24},
        },
    ],
    "anomaly_threshold": 0.36,
    "by_decision_type": {"credit_underwriting": 0.18},
    "trend": [{"week": "2025-W03", "rate": 0.17}, {"week": "2025-W04", "rate": 0.19}],
    "tenant_id": "tenant_dev",
}

MOCK_DRIFT = {
    "weeks": [
        {
            "week_start": "2025-01-06T00:00:00Z",
            "approval_rate": 0.72,
            "denial_rate": 0.28,
            "override_rate": 0.18,
            "decision_count": 150,
        },
    ],
    "alerts": [
        {
            "metric": "approval_rate",
            "direction": "decrease",
            "severity": "low",
            "current_value": 0.65,
            "baseline_value": 0.72,
            "change_pct": -0.10,
            "message": "Approval Rate decreased by 10%",
        },
    ],
    "tenant_id": "tenant_dev",
}

MOCK_COMPARISONS = {
    "pairs": [
        {
            "record_a_id": "dec_aaa111222333",
            "record_b_id": "dec_bbb444555666",
            "record_a_action": "approve",
            "record_b_action": "deny",
            "record_a_decided_by": "S. Chen",
            "record_b_decided_by": "M. Johnson",
            "similarity_score": 0.85,
            "key_evidence_a": {"fico_score": 710, "dti_ratio": 0.38},
            "key_evidence_b": {"fico_score": 715, "dti_ratio": 0.37},
            "key_differences": [],
        }
    ],
    "total_comparisons_checked": 12450,
    "tenant_id": "tenant_dev",
}


class TestAnalyticsOverview:
    def test_overview_returns_model(self, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            method="GET",
            url="http://test:8000/v1/analytics/overview?days=30",
            json=MOCK_OVERVIEW,
        )
        nx = Nexure(api_key="test_key", base_url="http://test:8000/v1")
        result = nx.analytics.overview()
        nx.close()

        assert isinstance(result, AnalyticsOverview)
        assert result.total_decisions == 4000
        assert len(result.action_breakdown) == 2
        assert len(result.decisions_by_day) == 2
        assert result.decisions_by_day[0].date == "2025-01-15"


class TestAnalyticsOverrides:
    def test_overrides_returns_model(self, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            method="GET",
            url="http://test:8000/v1/analytics/overrides?lookback_days=30",
            json=MOCK_OVERRIDES,
        )
        nx = Nexure(api_key="test_key", base_url="http://test:8000/v1")
        result = nx.analytics.override_rates()
        nx.close()

        assert isinstance(result, AnalyticsOverrides)
        assert result.reviewers[0].is_anomaly is True
        assert result.reviewers[0].deviation_from_mean == 2.3
        assert result.reviewers[0].override_direction is not None
        assert result.reviewers[0].override_direction.allow_to_block == 320
        assert len(result.by_decision_type) == 1
        assert len(result.trend) == 2


class TestAnalyticsDrift:
    def test_drift_returns_model(self, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            method="GET",
            url="http://test:8000/v1/analytics/drift?weeks=12",
            json=MOCK_DRIFT,
        )
        nx = Nexure(api_key="test_key", base_url="http://test:8000/v1")
        result = nx.analytics.drift()
        nx.close()

        assert isinstance(result, AnalyticsDrift)
        assert len(result.weeks) == 1
        assert len(result.alerts) == 1
        assert result.alerts[0].severity == "low"


class TestAnalyticsComparisons:
    def test_comparisons_returns_model(self, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            method="GET",
            url="http://test:8000/v1/analytics/comparisons?limit=20&min_similarity=0.7",
            json=MOCK_COMPARISONS,
        )
        nx = Nexure(api_key="test_key", base_url="http://test:8000/v1")
        result = nx.analytics.comparisons()
        nx.close()

        assert isinstance(result, AnalyticsComparisons)
        assert len(result.pairs) == 1
        assert result.pairs[0].similarity_score == 0.85
        assert result.pairs[0].key_differences == []


MOCK_VISIBILITY = {
    "score": 67.3,
    "components": [
        {
            "name": "Capture Rate",
            "weight": 0.25,
            "score": 72.0,
            "raw_value": 0.72,
            "description": "2880/4000 decisions have reasoning",
        },
        {
            "name": "Consistency",
            "weight": 0.25,
            "score": 85.0,
            "raw_value": 0.85,
            "description": "Inverse of reviewer override-rate variance",
        },
        {
            "name": "Policy Coverage",
            "weight": 0.20,
            "score": 50.0,
            "raw_value": 0.50,
            "description": "2000/4000 decisions have a brief",
        },
        {
            "name": "Override Documentation",
            "weight": 0.15,
            "score": 60.0,
            "raw_value": 0.60,
            "description": "432/720 overrides have reasoning",
        },
        {
            "name": "Audit Completeness",
            "weight": 0.15,
            "score": 50.0,
            "raw_value": 0.50,
            "description": "2000/4000 decisions have full forensic chain",
        },
    ],
    "total_decisions": 4000,
    "tenant_id": "tenant_dev",
}


class TestAnalyticsVisibilityScore:
    def test_visibility_score_returns_model(self, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            method="GET",
            url="http://test:8000/v1/analytics/visibility-score",
            json=MOCK_VISIBILITY,
        )
        nx = Nexure(api_key="test_key", base_url="http://test:8000/v1")
        result = nx.analytics.visibility_score()
        nx.close()

        assert isinstance(result, VisibilityScore)
        assert result.score == 67.3
        assert len(result.components) == 5
        assert result.components[0].name == "Capture Rate"

    def test_visibility_score_with_decision_type(self, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            method="GET",
            url="http://test:8000/v1/analytics/visibility-score?decision_type=credit_underwriting",
            json=MOCK_VISIBILITY,
        )
        nx = Nexure(api_key="test_key", base_url="http://test:8000/v1")
        result = nx.analytics.visibility_score(decision_type="credit_underwriting")
        nx.close()

        assert isinstance(result, VisibilityScore)


class TestAnalyticsDecisionTypeFilter:
    def test_overview_with_decision_type(self, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            method="GET",
            url="http://test:8000/v1/analytics/overview?days=30&decision_type=credit_underwriting",
            json=MOCK_OVERVIEW,
        )
        nx = Nexure(api_key="test_key", base_url="http://test:8000/v1")
        result = nx.analytics.overview(decision_type="credit_underwriting")
        nx.close()

        assert isinstance(result, AnalyticsOverview)

    def test_overrides_with_decision_type(self, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            method="GET",
            url="http://test:8000/v1/analytics/overrides?lookback_days=30&decision_type=credit_underwriting",
            json=MOCK_OVERRIDES,
        )
        nx = Nexure(api_key="test_key", base_url="http://test:8000/v1")
        result = nx.analytics.override_rates(decision_type="credit_underwriting")
        nx.close()

        assert isinstance(result, AnalyticsOverrides)
