from __future__ import annotations

from ebay_client.core.http.transport import ApiTransport
from ebay_client.generated.account.models import (
    FulfillmentPolicy,
    FulfillmentPolicyRequest,
    FulfillmentPolicyResponse,
    PaymentPolicy,
    PaymentPolicyRequest,
    PaymentPolicyResponse,
    Programs,
    ReturnPolicy,
    ReturnPolicyRequest,
    ReturnPolicyResponse,
    SetFulfillmentPolicyResponse,
    SetPaymentPolicyResponse,
    SetReturnPolicyResponse,
    SellingPrivileges,
)

ACCOUNT_SCOPE = "https://api.ebay.com/oauth/api_scope/sell.account"
ACCOUNT_READ_SCOPE = "https://api.ebay.com/oauth/api_scope/sell.account.readonly"
ACCOUNT_READ_SCOPE_OPTIONS = [[ACCOUNT_READ_SCOPE], [ACCOUNT_SCOPE]]


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

    def get_fulfillment_policies(self, *, marketplace_id: str) -> FulfillmentPolicyResponse:
        return self.transport.request_model(
            FulfillmentPolicyResponse,
            "GET",
            "/sell/account/v1/fulfillment_policy",
            scope_options=ACCOUNT_READ_SCOPE_OPTIONS,
            params={"marketplace_id": marketplace_id},
        )

    def create_fulfillment_policy(self, payload: FulfillmentPolicyRequest) -> SetFulfillmentPolicyResponse:
        return self.transport.request_model(
            SetFulfillmentPolicyResponse,
            "POST",
            "/sell/account/v1/fulfillment_policy/",
            scopes=[ACCOUNT_SCOPE],
            headers={"Content-Type": "application/json"},
            json_body=payload.model_dump(by_alias=True, exclude_none=True),
        )

    def get_fulfillment_policy(self, fulfillment_policy_id: str) -> FulfillmentPolicy:
        return self.transport.request_model(
            FulfillmentPolicy,
            "GET",
            f"/sell/account/v1/fulfillment_policy/{fulfillment_policy_id}",
            scope_options=ACCOUNT_READ_SCOPE_OPTIONS,
        )

    def update_fulfillment_policy(
        self,
        fulfillment_policy_id: str,
        payload: FulfillmentPolicyRequest,
    ) -> SetFulfillmentPolicyResponse:
        return self.transport.request_model(
            SetFulfillmentPolicyResponse,
            "PUT",
            f"/sell/account/v1/fulfillment_policy/{fulfillment_policy_id}",
            scopes=[ACCOUNT_SCOPE],
            headers={"Content-Type": "application/json"},
            json_body=payload.model_dump(by_alias=True, exclude_none=True),
        )

    def delete_fulfillment_policy(self, fulfillment_policy_id: str) -> None:
        self.transport.request_json(
            "DELETE",
            f"/sell/account/v1/fulfillment_policy/{fulfillment_policy_id}",
            scopes=[ACCOUNT_SCOPE],
        )

    def get_fulfillment_policy_by_name(self, *, marketplace_id: str, name: str) -> FulfillmentPolicy:
        return self.transport.request_model(
            FulfillmentPolicy,
            "GET",
            "/sell/account/v1/fulfillment_policy/get_by_policy_name",
            scope_options=ACCOUNT_READ_SCOPE_OPTIONS,
            params={"marketplace_id": marketplace_id, "name": name},
        )

    def get_payment_policies(self, *, marketplace_id: str) -> PaymentPolicyResponse:
        return self.transport.request_model(
            PaymentPolicyResponse,
            "GET",
            "/sell/account/v1/payment_policy",
            scope_options=ACCOUNT_READ_SCOPE_OPTIONS,
            params={"marketplace_id": marketplace_id},
        )

    def create_payment_policy(self, payload: PaymentPolicyRequest) -> SetPaymentPolicyResponse:
        return self.transport.request_model(
            SetPaymentPolicyResponse,
            "POST",
            "/sell/account/v1/payment_policy",
            scopes=[ACCOUNT_SCOPE],
            headers={"Content-Type": "application/json"},
            json_body=payload.model_dump(by_alias=True, exclude_none=True),
        )

    def get_payment_policy(self, payment_policy_id: str) -> PaymentPolicy:
        return self.transport.request_model(
            PaymentPolicy,
            "GET",
            f"/sell/account/v1/payment_policy/{payment_policy_id}",
            scope_options=ACCOUNT_READ_SCOPE_OPTIONS,
        )

    def update_payment_policy(self, payment_policy_id: str, payload: PaymentPolicyRequest) -> SetPaymentPolicyResponse:
        return self.transport.request_model(
            SetPaymentPolicyResponse,
            "PUT",
            f"/sell/account/v1/payment_policy/{payment_policy_id}",
            scopes=[ACCOUNT_SCOPE],
            headers={"Content-Type": "application/json"},
            json_body=payload.model_dump(by_alias=True, exclude_none=True),
        )

    def delete_payment_policy(self, payment_policy_id: str) -> None:
        self.transport.request_json(
            "DELETE",
            f"/sell/account/v1/payment_policy/{payment_policy_id}",
            scopes=[ACCOUNT_SCOPE],
        )

    def get_payment_policy_by_name(self, *, marketplace_id: str, name: str) -> PaymentPolicy:
        return self.transport.request_model(
            PaymentPolicy,
            "GET",
            "/sell/account/v1/payment_policy/get_by_policy_name",
            scope_options=ACCOUNT_READ_SCOPE_OPTIONS,
            params={"marketplace_id": marketplace_id, "name": name},
        )

    def get_return_policies(self, *, marketplace_id: str) -> ReturnPolicyResponse:
        return self.transport.request_model(
            ReturnPolicyResponse,
            "GET",
            "/sell/account/v1/return_policy",
            scope_options=ACCOUNT_READ_SCOPE_OPTIONS,
            params={"marketplace_id": marketplace_id},
        )

    def create_return_policy(self, payload: ReturnPolicyRequest) -> SetReturnPolicyResponse:
        return self.transport.request_model(
            SetReturnPolicyResponse,
            "POST",
            "/sell/account/v1/return_policy",
            scopes=[ACCOUNT_SCOPE],
            headers={"Content-Type": "application/json"},
            json_body=payload.model_dump(by_alias=True, exclude_none=True),
        )

    def get_return_policy(self, return_policy_id: str) -> ReturnPolicy:
        return self.transport.request_model(
            ReturnPolicy,
            "GET",
            f"/sell/account/v1/return_policy/{return_policy_id}",
            scope_options=ACCOUNT_READ_SCOPE_OPTIONS,
        )

    def update_return_policy(self, return_policy_id: str, payload: ReturnPolicyRequest) -> SetReturnPolicyResponse:
        return self.transport.request_model(
            SetReturnPolicyResponse,
            "PUT",
            f"/sell/account/v1/return_policy/{return_policy_id}",
            scopes=[ACCOUNT_SCOPE],
            headers={"Content-Type": "application/json"},
            json_body=payload.model_dump(by_alias=True, exclude_none=True),
        )

    def delete_return_policy(self, return_policy_id: str) -> None:
        self.transport.request_json(
            "DELETE",
            f"/sell/account/v1/return_policy/{return_policy_id}",
            scopes=[ACCOUNT_SCOPE],
        )

    def get_return_policy_by_name(self, *, marketplace_id: str, name: str) -> ReturnPolicy:
        return self.transport.request_model(
            ReturnPolicy,
            "GET",
            "/sell/account/v1/return_policy/get_by_policy_name",
            scope_options=ACCOUNT_READ_SCOPE_OPTIONS,
            params={"marketplace_id": marketplace_id, "name": name},
        )

    def get_privileges(self) -> SellingPrivileges:
        return self.transport.request_model(
            SellingPrivileges,
            "GET",
            "/sell/account/v1/privilege",
            scope_options=ACCOUNT_READ_SCOPE_OPTIONS,
        )

    def get_opted_in_programs(self) -> Programs:
        return self.transport.request_model(
            Programs,
            "GET",
            "/sell/account/v1/program/get_opted_in_programs",
            scope_options=ACCOUNT_READ_SCOPE_OPTIONS,
        )
