"""Plain Python integration example for gnexus-gauth.

This example shows:
- redirect to gnexus-auth
- callback exchange
- userinfo fetch
- webhook verification and parsing
"""

import json
from datetime import datetime, timezone

from gnexus_gauth.client import GAuthClient
from gnexus_gauth.config import GAuthConfig
from gnexus_gauth.contracts import PkceStoreInterface, StateStoreInterface
from gnexus_gauth.exceptions import WebhookVerificationException
from gnexus_gauth.oauth import AuthorizationUrlBuilder, HttpTokenEndpoint, PkceGenerator
from gnexus_gauth.runtime import HttpRuntimeUserProvider
from gnexus_gauth.support import SystemClock
from gnexus_gauth.webhook import HmacWebhookVerifier, JsonWebhookParser


class SimpleStateStore(StateStoreInterface):
    """Simple in-memory state store for demonstration."""

    def __init__(self) -> None:
        self._items: dict[str, dict] = {}

    def put(self, state: str, expires_at: datetime, context: dict | None = None) -> None:
        self._items[state] = {"expires_at": expires_at, "context": context or {}}

    def has(self, state: str) -> bool:
        record = self._items.get(state)
        if record is None:
            return False
        if record["expires_at"] < datetime.now(timezone.utc):
            del self._items[state]
            return False
        return True

    def get_context(self, state: str) -> dict:
        if not self.has(state):
            return {}
        return self._items[state].get("context", {})

    def forget(self, state: str) -> None:
        self._items.pop(state, None)


class SimplePkceStore(PkceStoreInterface):
    """Simple in-memory PKCE store for demonstration."""

    def __init__(self) -> None:
        self._items: dict[str, dict] = {}

    def put(self, state: str, verifier: str, expires_at: datetime) -> None:
        self._items[state] = {"verifier": verifier, "expires_at": expires_at}

    def get(self, state: str) -> str | None:
        record = self._items.get(state)
        if record is None:
            return None
        if record["expires_at"] < datetime.now(timezone.utc):
            del self._items[state]
            return None
        return record["verifier"]

    def forget(self, state: str) -> None:
        self._items.pop(state, None)


def make_client() -> GAuthClient:
    config = GAuthConfig(
        base_url="https://gnexus-auth.local",
        client_id="my-service",
        client_secret="my-secret",
        redirect_uri="https://my-service.local/callback",
    )

    token_endpoint = HttpTokenEndpoint(config)
    runtime_provider = HttpRuntimeUserProvider(config)
    webhook_verifier = HmacWebhookVerifier(config)
    webhook_parser = JsonWebhookParser()

    return GAuthClient(
        config=config,
        token_endpoint=token_endpoint,
        runtime_user_provider=runtime_provider,
        webhook_verifier=webhook_verifier,
        webhook_parser=webhook_parser,
        state_store=SimpleStateStore(),
        pkce_store=SimplePkceStore(),
    )


def redirect_example() -> None:
    client = make_client()
    auth_request = client.build_authorization_request(
        return_to="/dashboard",
        scopes=["openid", "email", "profile", "roles", "permissions"],
    )
    print(f"Redirect user to: {auth_request.authorization_url}")


def callback_example(code: str, state: str) -> None:
    client = make_client()
    try:
        token_set = client.exchange_authorization_code(code, state)
        user = client.fetch_user(token_set.access_token)
    except Exception as exc:
        print(f"Authorization failed: {exc}")
        return

    print(f"User ID: {user.user_id}")
    print(f"Email: {user.email}")
    print(f"Access token: {token_set.access_token[:10]}...")


def webhook_example(raw_body: str, headers: dict, secret: str) -> None:
    client = make_client()
    try:
        event = client.verify_and_parse_webhook(raw_body, headers, secret)
    except WebhookVerificationException:
        print("Invalid webhook signature.")
        return

    print(f"Accepted event: {event.event_type} (id={event.event_id})")


if __name__ == "__main__":
    # Demonstrate redirect URL generation
    redirect_example()

    # Demonstrate webhook handling with a dummy payload
    dummy_body = json.dumps({"type": "user.updated", "id": "evt_1"})
    dummy_headers = {
        "X-Gnexus-Event-Id": "evt_1",
        "X-Gnexus-Event-Type": "user.updated",
        "X-Gnexus-Event-Timestamp": "2024-01-01T00:00:00Z",
        "X-Gnexus-Signature": "t=1704067200,v1=abc123",
    }
    webhook_example(dummy_body, dummy_headers, "webhook_secret")
