import hmac
import hashlib
import json

from app.config import settings


def _create_partner(client):
    settings.admin_api_key = "test-admin"
    settings.allow_unsafe_admin = False
    resp = client.post(
        "/v1/partners",
        json={"name": "Demo Partner"},
        headers={"X-Admin-Key": settings.admin_api_key},
    )
    assert resp.status_code == 201
    data = resp.json()
    return data["api_key"], data["id"]


def test_partner_mismatch_forbidden(client_with_db):
    api_key, _ = _create_partner(client_with_db)
    resp = client_with_db.post(
        "/v1/checkout-sessions",
        headers={"X-API-Key": api_key},
        json={
            "partner_id": "other-partner",
            "external_order_id": "ORDER-2",
            "amount": 10.0,
            "currency": "USD",
        },
    )
    assert resp.status_code == 403


def test_webhook_paid_and_idempotent(client_with_db):
    api_key, partner_id = _create_partner(client_with_db)
    session = client_with_db.post(
        "/v1/checkout-sessions",
        headers={"X-API-Key": api_key},
        json={
            "partner_id": partner_id,
            "external_order_id": "ORDER-3",
            "amount": 50.0,
            "currency": "USD",
        },
    )
    session_id = session.json()["id"]

    first = client_with_db.post(
        "/v1/webhooks/payment-processor",
        json={"event_id": "evt_123", "session_id": session_id, "status": "paid"},
    )
    assert first.status_code == 200
    assert first.json()["idempotent"] is False

    second = client_with_db.post(
        "/v1/webhooks/payment-processor",
        json={"event_id": "evt_123", "session_id": session_id, "status": "paid"},
    )
    assert second.status_code == 200
    assert second.json()["idempotent"] is True

    status = client_with_db.get(
        f"/v1/checkout-sessions/{session_id}",
        headers={"X-API-Key": api_key},
    )
    assert status.json()["status"] == "paid"


def test_dashboard_csv_export(client_with_db):
    api_key, partner_id = _create_partner(client_with_db)
    client_with_db.post(
        "/v1/checkout-sessions",
        headers={"X-API-Key": api_key},
        json={
            "partner_id": partner_id,
            "external_order_id": "ORDER-4",
            "amount": 30.0,
            "currency": "USD",
        },
    )
    resp = client_with_db.get(
        "/dashboard.csv",
        headers={"X-API-Key": api_key},
    )
    assert resp.status_code == 200
    assert resp.text.splitlines()[0].startswith("date,order_id")


def test_dashboard_query_api_key_dev(client_with_db):
    settings.app_env = "dev"
    api_key, _ = _create_partner(client_with_db)
    resp = client_with_db.get(f"/dashboard?api_key={api_key}")
    assert resp.status_code == 200


def test_webhook_requires_signature_when_secret_set(client_with_db):
    settings.payment_webhook_secret = "secret"
    settings.allow_unsafe_webhook = False
    payload = {"event_id": "evt_sig", "session_id": "missing", "status": "paid"}
    raw = json.dumps(payload, separators=(",", ":")).encode("utf-8")
    sig = hmac.new(b"secret", raw, hashlib.sha256).hexdigest()

    bad = client_with_db.post(
        "/v1/webhooks/payment-processor",
        data=raw,
        headers={"Content-Type": "application/json"},
    )
    assert bad.status_code == 400

    good = client_with_db.post(
        "/v1/webhooks/payment-processor",
        data=raw,
        headers={"Content-Type": "application/json", "X-Signature": sig},
    )
    assert good.status_code in {200, 404}
