import graphene

from .....checkout.error_codes import CheckoutErrorCode
from ....tests.utils import get_graphql_content

MUTATION_CHECKOUT_BILLING_ADDRESS_UPDATE = """
    mutation checkoutBillingAddressUpdate(
            $checkoutId: ID, $token: UUID, $billingAddress: AddressInput!) {
        checkoutBillingAddressUpdate(
                checkoutId: $checkoutId,
                token: $token,
                billingAddress: $billingAddress
        ){
            checkout {
                token,
                id
            },
            errors {
                field
                code
                message
            }
        }
    }
"""


def test_checkout_billing_address_update_by_id(
    user_api_client, checkout_with_item, graphql_address_data
):
    checkout = checkout_with_item
    assert checkout.shipping_address is None
    checkout_id = graphene.Node.to_global_id("Checkout", checkout.pk)

    query = MUTATION_CHECKOUT_BILLING_ADDRESS_UPDATE
    billing_address = graphql_address_data

    variables = {"checkoutId": checkout_id, "billingAddress": billing_address}

    response = user_api_client.post_graphql(query, variables)
    content = get_graphql_content(response)
    data = content["data"]["checkoutBillingAddressUpdate"]
    assert not data["errors"]
    checkout.refresh_from_db()
    assert checkout.billing_address is not None
    assert checkout.billing_address.first_name == billing_address["firstName"]
    assert checkout.billing_address.last_name == billing_address["lastName"]
    assert (
        checkout.billing_address.street_address_1 == billing_address["streetAddress1"]
    )
    assert (
        checkout.billing_address.street_address_2 == billing_address["streetAddress2"]
    )
    assert checkout.billing_address.postal_code == billing_address["postalCode"]
    assert checkout.billing_address.country == billing_address["country"]
    assert checkout.billing_address.city == billing_address["city"].upper()


def test_checkout_billing_address_update_by_token(
    user_api_client, checkout_with_item, graphql_address_data
):
    checkout = checkout_with_item
    assert checkout.shipping_address is None

    query = MUTATION_CHECKOUT_BILLING_ADDRESS_UPDATE
    billing_address = graphql_address_data

    variables = {"token": checkout_with_item.token, "billingAddress": billing_address}

    response = user_api_client.post_graphql(query, variables)
    content = get_graphql_content(response)
    data = content["data"]["checkoutBillingAddressUpdate"]
    assert not data["errors"]
    checkout.refresh_from_db()
    assert checkout.billing_address is not None
    assert checkout.billing_address.first_name == billing_address["firstName"]
    assert checkout.billing_address.last_name == billing_address["lastName"]
    assert (
        checkout.billing_address.street_address_1 == billing_address["streetAddress1"]
    )
    assert (
        checkout.billing_address.street_address_2 == billing_address["streetAddress2"]
    )
    assert checkout.billing_address.postal_code == billing_address["postalCode"]
    assert checkout.billing_address.country == billing_address["country"]
    assert checkout.billing_address.city == billing_address["city"].upper()


def test_checkout_billing_address_update_neither_token_and_id_given(
    user_api_client, checkout_with_item, graphql_address_data
):
    checkout = checkout_with_item
    assert checkout.shipping_address is None

    query = MUTATION_CHECKOUT_BILLING_ADDRESS_UPDATE
    billing_address = graphql_address_data

    variables = {"billingAddress": billing_address}

    response = user_api_client.post_graphql(query, variables)
    content = get_graphql_content(response)
    data = content["data"]["checkoutBillingAddressUpdate"]

    assert len(data["errors"]) == 1
    assert not data["checkout"]
    assert data["errors"][0]["code"] == CheckoutErrorCode.GRAPHQL_ERROR.name


def test_checkout_billing_address_update_both_token_and_id_given(
    user_api_client, checkout_with_item, graphql_address_data
):
    checkout_id = graphene.Node.to_global_id("Checkout", checkout_with_item.pk)
    checkout = checkout_with_item
    assert checkout.shipping_address is None

    query = MUTATION_CHECKOUT_BILLING_ADDRESS_UPDATE
    billing_address = graphql_address_data

    variables = {
        "billingAddress": billing_address,
        "token": checkout_with_item.token,
        "checkoutId": checkout_id,
    }

    response = user_api_client.post_graphql(query, variables)
    content = get_graphql_content(response)
    data = content["data"]["checkoutBillingAddressUpdate"]

    assert len(data["errors"]) == 1
    assert not data["checkout"]
    assert data["errors"][0]["code"] == CheckoutErrorCode.GRAPHQL_ERROR.name
