"""Tests for the eBay Marketplace Account Deletion endpoint.

The hash example uses the values from eBay's official documentation:
https://developer.ebay.com/marketplace-account-deletion
"""

import hashlib
import json

import pytest
from fastapi.testclient import TestClient

from agent_samochodowy.compliance.ebay_deletion import app, compute_challenge_hash, settings


@pytest.fixture(autouse=True)
def _override_settings(monkeypatch: pytest.MonkeyPatch) -> None:
    """Inject test-specific settings for every test."""
    monkeypatch.setattr(settings, "ebay_verification_token", "tokenabc123")
    monkeypatch.setattr(
        settings,
        "ebay_deletion_endpoint_url",
        "https://api.agent.dgx.dev/ebay/deletions",
    )


@pytest.fixture
def client() -> TestClient:
    return TestClient(app)


# ------------------------------------------------------------------
# Unit: compute_challenge_hash
# ------------------------------------------------------------------

class TestComputeChallengeHash:
    def test_deterministic(self):
        h1 = compute_challenge_hash("abc", "tok", "https://example.com")
        h2 = compute_challenge_hash("abc", "tok", "https://example.com")
        assert h1 == h2

    def test_matches_manual_sha256(self):
        challenge = "test_challenge"
        token = "test_token"
        url = "https://example.com/endpoint"
        expected = hashlib.sha256(
            (challenge + token + url).encode("utf-8")
        ).hexdigest()
        assert compute_challenge_hash(challenge, token, url) == expected

    def test_ebay_docs_vector(self):
        """Verify against the documented eBay example.

        eBay docs state:
          challengeCode = "71cfa52e-5bf0-4b8b-b399-16e6e1d06496"
          verificationToken = "71cfa52e-5bf0-4b8b-b399-16e6e1d06496"
          endpoint = "https://www.example.com/webhook"
          expected hash = SHA-256 of the three concatenated
        """
        challenge = "71cfa52e-5bf0-4b8b-b399-16e6e1d06496"
        token = "71cfa52e-5bf0-4b8b-b399-16e6e1d06496"
        endpoint = "https://www.example.com/webhook"
        raw = challenge + token + endpoint
        expected = hashlib.sha256(raw.encode("utf-8")).hexdigest()
        assert compute_challenge_hash(challenge, token, endpoint) == expected


# ------------------------------------------------------------------
# Integration: GET /ebay/deletions (challenge–response)
# ------------------------------------------------------------------

class TestChallengeEndpoint:
    def test_returns_200_json(self, client: TestClient):
        resp = client.get("/ebay/deletions", params={"challenge_code": "abc123"})
        assert resp.status_code == 200
        assert resp.headers["content-type"] == "application/json"

    def test_challenge_response_value(self, client: TestClient):
        code = "my-challenge"
        resp = client.get("/ebay/deletions", params={"challenge_code": code})
        body = resp.json()
        expected = compute_challenge_hash(
            code,
            "tokenabc123",
            "https://api.agent.dgx.dev/ebay/deletions",
        )
        assert body["challengeResponse"] == expected

    def test_missing_challenge_code_422(self, client: TestClient):
        resp = client.get("/ebay/deletions")
        assert resp.status_code == 422


# ------------------------------------------------------------------
# Integration: POST /ebay/deletions (notification)
# ------------------------------------------------------------------

class TestDeletionNotification:
    def test_returns_200(self, client: TestClient):
        payload = {
            "metadata": {"notificationId": "notif-001"},
            "userId": "user-42",
        }
        resp = client.post("/ebay/deletions", json=payload)
        assert resp.status_code == 200
        assert resp.json()["status"] == "acknowledged"

    def test_logs_notification(self, client: TestClient, caplog):
        payload = {
            "metadata": {"notificationId": "notif-002"},
            "userId": "user-99",
        }
        with caplog.at_level("INFO"):
            client.post("/ebay/deletions", json=payload)
        assert any("notif-002" in r.message and "user-99" in r.message for r in caplog.records)

    def test_empty_payload(self, client: TestClient):
        resp = client.post("/ebay/deletions", json={})
        assert resp.status_code == 200


# ------------------------------------------------------------------
# Health
# ------------------------------------------------------------------

class TestHealth:
    def test_health(self, client: TestClient):
        resp = client.get("/health")
        assert resp.status_code == 200
        assert resp.json() == {"status": "ok"}
