"""eBay Marketplace Account Deletion / Closure notification endpoint,
plus OAuth2 callback and privacy policy routes.

Implements the challenge-response handshake (GET) and deletion notification
receiver (POST) required by eBay's Marketplace Account Deletion policy.

Reference: https://developer.ebay.com/marketplace-account-deletion
"""

from __future__ import annotations

import hashlib
import logging
from typing import Any

from fastapi import FastAPI, Request, Response
from fastapi.responses import HTMLResponse

from agent_samochodowy.compliance.ebay_oauth import (
    EbayTokenStore,
    exchange_code_for_tokens,
)
from agent_samochodowy.compliance.settings import ComplianceSettings

logger = logging.getLogger(__name__)

settings = ComplianceSettings()

app = FastAPI(title="eBay Agent Samochodowy API", version="1.1.0")


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

@app.get("/health")
async def health() -> dict[str, str]:
    return {"status": "ok"}


# ------------------------------------------------------------------
# eBay Marketplace Account Deletion (compliance)
# ------------------------------------------------------------------

@app.get("/ebay/deletions")
async def challenge(challenge_code: str) -> Response:
    """Respond to eBay's challenge-response verification.

    hash = SHA-256(challenge_code + verification_token + endpoint_url)
    """
    digest = compute_challenge_hash(
        challenge_code,
        settings.ebay_verification_token,
        settings.ebay_deletion_endpoint_url,
    )
    return Response(
        content=f'{{"challengeResponse":"{digest}"}}',
        media_type="application/json",
        status_code=200,
    )


@app.post("/ebay/deletions")
async def deletion_notification(request: Request) -> dict[str, str]:
    """Receive and acknowledge an account-deletion notification from eBay."""
    body: dict[str, Any] = await request.json()
    notification_id = body.get("metadata", {}).get("notificationId", "unknown")
    user_id = body.get("userId", "unknown")
    logger.info(
        "eBay deletion notification received: notificationId=%s userId=%s",
        notification_id,
        user_id,
    )
    return {"status": "acknowledged"}


def compute_challenge_hash(
    challenge_code: str,
    verification_token: str,
    endpoint_url: str,
) -> str:
    """SHA-256 hex digest of the concatenation challenge_code + token + url."""
    payload = challenge_code + verification_token + endpoint_url
    return hashlib.sha256(payload.encode("utf-8")).hexdigest()


# ------------------------------------------------------------------
# eBay OAuth2 callback
# ------------------------------------------------------------------

@app.get("/ebay/oauth/callback", response_class=HTMLResponse)
async def ebay_oauth_callback(
    code: str | None = None,
    error: str | None = None,
    error_description: str | None = None,
) -> HTMLResponse:
    """Exchange authorization code for access + refresh tokens."""
    if error:
        logger.warning("eBay OAuth error: %s — %s", error, error_description)
        return HTMLResponse(
            content=(
                "<html><body>"
                f"<h1>&#10060; eBay OAuth error: {error}</h1>"
                f"<p>{error_description or 'Brak szczegółów.'}</p>"
                "<p>Spróbuj ponownie: <code>python scripts/ebay_authorize.py</code></p>"
                "</body></html>"
            ),
            status_code=400,
        )
    if not code:
        return HTMLResponse(
            content=(
                "<html><body>"
                "<h1>&#10060; Brak kodu autoryzacji</h1>"
                "<p>Brak parametru <code>code</code> w URL.</p>"
                "</body></html>"
            ),
            status_code=400,
        )
    try:
        token_data = exchange_code_for_tokens(
            code=code,
            client_id=settings.ebay_client_id,
            client_secret=settings.ebay_client_secret,
            redirect_uri=settings.ebay_redirect_uri,
        )
        store = EbayTokenStore(settings.ebay_token_path)
        store.save(token_data)

        return HTMLResponse(
            content=(
                "<html><body>"
                "<h1>&#9989; Autoryzacja eBay OK</h1>"
                "<p>Tokeny zapisane. Refresh token aktywny &mdash; "
                "access token będzie odnawiany automatycznie.</p>"
                "</body></html>"
            ),
            status_code=200,
        )
    except Exception:
        logger.exception("eBay OAuth callback failed")
        return HTMLResponse(
            content=(
                "<html><body>"
                "<h1>&#10060; Autoryzacja eBay nie powiodła się</h1>"
                "<p>Sprawdź logi serwisu.</p>"
                "</body></html>"
            ),
            status_code=500,
        )


@app.get("/ebay/oauth/declined", response_class=HTMLResponse)
async def ebay_oauth_declined() -> HTMLResponse:
    """User declined the eBay OAuth consent."""
    return HTMLResponse(
        content=(
            "<html><body>"
            "<h1>Autoryzacja odrzucona</h1>"
            "<p>Nie udzielono zgody na dostęp do konta eBay. "
            "Możesz ponowić próbę uruchamiając <code>python scripts/ebay_authorize.py</code>.</p>"
            "</body></html>"
        ),
        status_code=200,
    )


# ------------------------------------------------------------------
# Privacy policy (required by eBay RuName)
# ------------------------------------------------------------------

@app.get("/privacy", response_class=HTMLResponse)
async def privacy_policy() -> HTMLResponse:
    """Static privacy policy page required by eBay for RuName registration."""
    return HTMLResponse(
        content=(
            "<html><head><title>Polityka Prywatności - Agent Samochodowy</title></head>"
            "<body>"
            "<h1>Polityka Prywatności</h1>"
            "<p>Serwis Agent Samochodowy (api.agent.dgx.dev) przetwarza dane wyłącznie "
            "w zakresie niezbędnym do świadczenia usług integracji z platformą eBay:</p>"
            "<ul>"
            "<li>Tokeny OAuth (access_token, refresh_token) &mdash; przechowywane lokalnie "
            "na serwerze z ograniczonymi uprawnieniami (chmod 600), używane wyłącznie "
            "do komunikacji z API eBay.</li>"
            "<li>Identyfikatory ofert i dane produktowe &mdash; pobierane z konta sprzedawcy "
            "w celu budowy katalogu części.</li>"
            "</ul>"
            "<p>Dane nie są udostępniane podmiotom trzecim. Dane konta eBay mogą zostać "
            "usunięte na żądanie (zgodnie z eBay Marketplace Account Deletion policy).</p>"
            "<p>Kontakt: admin@dgx.dev</p>"
            "</body></html>"
        ),
        status_code=200,
    )
