"""
Cross-SDK webhook contract tests for the Python SDK.

Validates that every fixture in fixtures/webhook-payloads.json:
1. Passes through WebhookVerifier.verify() with a test signature
2. Uses the `event` field (not `type`)
3. Contains all required base fields in `data`
4. Contains event-specific fields based on event type
"""

import hashlib
import hmac
import json
import os
import time

import pytest

from zyndpay import WebhookVerifier

FIXTURES_PATH = os.path.join(
    os.path.dirname(__file__), "..", "..", "..", "fixtures", "webhook-payloads.json"
)
SECRET = "whsec_contract_test_secret"

BASE_FIELDS = ["transactionId", "status", "currency", "chain", "externalRef"]

EVENT_SPECIFIC_FIELDS = {
    "payin.created": ["amount", "address"],
    "payin.confirming": ["txHash", "confirmations"],
    "payin.confirmed": ["amount", "amountRequested", "txHash", "confirmedAt"],
    "payin.overpaid": ["amount", "amountRequested", "txHash", "confirmedAt"],
    "payin.underpaid": ["amount", "amountRequested", "txHash", "confirmedAt"],
}


def _build_signature(body: str, secret: str) -> str:
    ts = int(time.time())
    signed_payload = f"{ts}.{body}"
    digest = hmac.new(
        secret.encode("utf-8"),
        signed_payload.encode("utf-8"),
        hashlib.sha256,
    ).hexdigest()
    return f"t={ts},v1={digest}"


def _load_fixtures():
    if not os.path.exists(FIXTURES_PATH):
        return []
    with open(FIXTURES_PATH, "r") as f:
        return json.load(f)


FIXTURES = _load_fixtures()


@pytest.fixture
def fixtures():
    return FIXTURES


# ─── Tests ────────────────────────────────────────────────────────────────────


def test_fixtures_loaded():
    """Fixtures file should exist and contain at least one payload."""
    if not os.path.exists(FIXTURES_PATH):
        pytest.skip("Fixtures file not found — skipping contract tests")
    assert len(FIXTURES) > 0, "Expected at least one fixture payload"


def test_every_fixture_passes_through_verifier(fixtures):
    """Every fixture payload should pass WebhookVerifier.verify()."""
    if not fixtures:
        pytest.skip("No fixtures loaded")

    verifier = WebhookVerifier(SECRET)

    for fixture in fixtures:
        body = json.dumps(fixture)
        sig = _build_signature(body, SECRET)
        parsed = verifier.verify(body, sig)

        # Must use `event` field, not `type`
        assert "event" in parsed, f"Missing 'event' field in {fixture['event']}"
        assert "type" not in parsed, f"Found 'type' field instead of 'event' in {fixture['event']}"
        assert parsed["event"] == fixture["event"]


def test_every_fixture_has_base_fields(fixtures):
    """Every fixture data must contain all base fields."""
    if not fixtures:
        pytest.skip("No fixtures loaded")

    for fixture in fixtures:
        data = fixture["data"]
        for field in BASE_FIELDS:
            assert field in data, (
                f"Missing base field '{field}' in {fixture['event']} data"
            )


def test_every_fixture_has_event_specific_fields(fixtures):
    """Fixtures with known event types must contain their event-specific fields."""
    if not fixtures:
        pytest.skip("No fixtures loaded")

    for fixture in fixtures:
        event_type = fixture["event"]
        extra_fields = EVENT_SPECIFIC_FIELDS.get(event_type)
        if not extra_fields:
            continue

        data = fixture["data"]
        for field in extra_fields:
            assert field in data, (
                f"Missing event-specific field '{field}' in {event_type} data"
            )


def test_every_fixture_has_created_at(fixtures):
    """Every fixture must have a createdAt ISO-8601 timestamp."""
    if not fixtures:
        pytest.skip("No fixtures loaded")

    for fixture in fixtures:
        assert "createdAt" in fixture, f"Missing 'createdAt' in {fixture['event']}"
        assert isinstance(fixture["createdAt"], str)
