from __future__ import annotations

from ebay_client.core.http.transport import ApiTransport
from ebay_client.generated.notification.models import (
    Config,
    CreateSubscriptionFilterRequest,
    CreateSubscriptionRequest,
    Destination,
    DestinationRequest,
    DestinationSearchResponse,
    PublicKey,
    Subscription,
    SubscriptionFilter,
    UpdateSubscriptionRequest,
    SubscriptionSearchResponse,
    Topic,
    TopicSearchResponse,
)

NOTIFICATION_SCOPE = "https://api.ebay.com/oauth/api_scope"
NOTIFICATION_SUBSCRIPTION_SCOPE = "https://api.ebay.com/oauth/api_scope/commerce.notification.subscription"
NOTIFICATION_SUBSCRIPTION_READ_SCOPE = "https://api.ebay.com/oauth/api_scope/commerce.notification.subscription.readonly"
NOTIFICATION_SUBSCRIPTION_READ_SCOPE_OPTIONS = [
    [NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_READ_SCOPE],
    [NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_SCOPE],
]


class NotificationClient:
    def __init__(self, transport: ApiTransport) -> None:
        self.transport = transport

    def get_config(self) -> Config:
        return self.transport.request_model(
            Config,
            "GET",
            "/commerce/notification/v1/config",
            scopes=[NOTIFICATION_SCOPE],
        )

    def update_config(self, payload: Config) -> None:
        self.transport.request_json(
            "PUT",
            "/commerce/notification/v1/config",
            scopes=[NOTIFICATION_SCOPE],
            headers={"Content-Type": "application/json"},
            json_body=payload.model_dump(by_alias=True, exclude_none=True),
        )

    def get_topics(self, *, limit: int | None = None, continuation_token: str | None = None) -> TopicSearchResponse:
        return self.transport.request_model(
            TopicSearchResponse,
            "GET",
            "/commerce/notification/v1/topic",
            scopes=[NOTIFICATION_SCOPE],
            params={"limit": limit, "continuation_token": continuation_token},
        )

    def get_topic(self, topic_id: str) -> Topic:
        return self.transport.request_model(
            Topic,
            "GET",
            f"/commerce/notification/v1/topic/{topic_id}",
            scopes=[NOTIFICATION_SCOPE],
        )

    def get_destinations(self, *, limit: int | None = None, continuation_token: str | None = None) -> DestinationSearchResponse:
        return self.transport.request_model(
            DestinationSearchResponse,
            "GET",
            "/commerce/notification/v1/destination",
            scopes=[NOTIFICATION_SCOPE],
            params={"limit": limit, "continuation_token": continuation_token},
        )

    def create_destination(self, payload: DestinationRequest) -> dict[str, object] | None:
        return self.transport.request_json(
            "POST",
            "/commerce/notification/v1/destination",
            scopes=[NOTIFICATION_SCOPE],
            headers={"Content-Type": "application/json"},
            json_body=payload.model_dump(by_alias=True, exclude_none=True),
        )

    def get_destination(self, destination_id: str) -> Destination:
        return self.transport.request_model(
            Destination,
            "GET",
            f"/commerce/notification/v1/destination/{destination_id}",
            scopes=[NOTIFICATION_SCOPE],
        )

    def update_destination(self, destination_id: str, payload: DestinationRequest) -> None:
        self.transport.request_json(
            "PUT",
            f"/commerce/notification/v1/destination/{destination_id}",
            scopes=[NOTIFICATION_SCOPE],
            headers={"Content-Type": "application/json"},
            json_body=payload.model_dump(by_alias=True, exclude_none=True),
        )

    def delete_destination(self, destination_id: str) -> None:
        self.transport.request_json(
            "DELETE",
            f"/commerce/notification/v1/destination/{destination_id}",
            scopes=[NOTIFICATION_SCOPE],
        )

    def get_subscriptions(self, *, limit: int | None = None, continuation_token: str | None = None) -> SubscriptionSearchResponse:
        return self.transport.request_model(
            SubscriptionSearchResponse,
            "GET",
            "/commerce/notification/v1/subscription",
            scope_options=NOTIFICATION_SUBSCRIPTION_READ_SCOPE_OPTIONS,
            params={"limit": limit, "continuation_token": continuation_token},
        )

    def create_subscription(self, payload: CreateSubscriptionRequest) -> dict[str, object] | None:
        return self.transport.request_json(
            "POST",
            "/commerce/notification/v1/subscription",
            scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_SCOPE],
            headers={"Content-Type": "application/json"},
            json_body=payload.model_dump(by_alias=True, exclude_none=True),
        )

    def get_subscription(self, subscription_id: str) -> Subscription:
        return self.transport.request_model(
            Subscription,
            "GET",
            f"/commerce/notification/v1/subscription/{subscription_id}",
            scope_options=NOTIFICATION_SUBSCRIPTION_READ_SCOPE_OPTIONS,
        )

    def update_subscription(self, subscription_id: str, payload: UpdateSubscriptionRequest) -> None:
        self.transport.request_json(
            "PUT",
            f"/commerce/notification/v1/subscription/{subscription_id}",
            scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_SCOPE],
            headers={"Content-Type": "application/json"},
            json_body=payload.model_dump(by_alias=True, exclude_none=True),
        )

    def delete_subscription(self, subscription_id: str) -> None:
        self.transport.request_json(
            "DELETE",
            f"/commerce/notification/v1/subscription/{subscription_id}",
            scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_SCOPE],
        )

    def create_subscription_filter(
        self,
        subscription_id: str,
        payload: CreateSubscriptionFilterRequest,
    ) -> dict[str, object] | None:
        return self.transport.request_json(
            "POST",
            f"/commerce/notification/v1/subscription/{subscription_id}/filter",
            scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_SCOPE],
            headers={"Content-Type": "application/json"},
            json_body=payload.model_dump(by_alias=True, exclude_none=True),
        )

    def get_subscription_filter(self, subscription_id: str, filter_id: str) -> SubscriptionFilter:
        return self.transport.request_model(
            SubscriptionFilter,
            "GET",
            f"/commerce/notification/v1/subscription/{subscription_id}/filter/{filter_id}",
            scope_options=NOTIFICATION_SUBSCRIPTION_READ_SCOPE_OPTIONS,
        )

    def delete_subscription_filter(self, subscription_id: str, filter_id: str) -> None:
        self.transport.request_json(
            "DELETE",
            f"/commerce/notification/v1/subscription/{subscription_id}/filter/{filter_id}",
            scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_SCOPE],
        )

    def disable_subscription(self, subscription_id: str) -> None:
        self.transport.request_json(
            "POST",
            f"/commerce/notification/v1/subscription/{subscription_id}/disable",
            scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_SCOPE],
        )

    def enable_subscription(self, subscription_id: str) -> None:
        self.transport.request_json(
            "POST",
            f"/commerce/notification/v1/subscription/{subscription_id}/enable",
            scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_SCOPE],
        )

    def test_subscription(self, subscription_id: str) -> None:
        self.transport.request_json(
            "POST",
            f"/commerce/notification/v1/subscription/{subscription_id}/test",
            scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_SCOPE],
        )

    def get_public_key(self, public_key_id: str) -> PublicKey:
        return self.transport.request_model(
            PublicKey,
            "GET",
            f"/commerce/notification/v1/public_key/{public_key_id}",
            scopes=[NOTIFICATION_SCOPE],
        )
