# -*- coding: utf-8 -*-
# type: ignore
from __future__ import annotations

import http

from django.test import Client
from django.urls import reverse
import pytest

from hotpocket_backend_testing.services.accounts import (
    AccessTokensTestingService,
)


@pytest.fixture
def call(rpc_call_factory, auth_key_out, safari_extension_meta):
    return rpc_call_factory(
        'accounts.access_tokens.create',
        [auth_key_out.key, safari_extension_meta],
    )


@pytest.mark.django_db
def test_ok(client: Client,
            call,
            safari_extension_origin,
            account,
            safari_extension_meta,
            ):
    # When
    result = client.post(
        reverse('ui.accounts.rpc'),
        data=call,
        content_type='application/json',
        headers={
            'Origin': safari_extension_origin,
        },
    )

    # Then
    assert result.status_code == http.HTTPStatus.OK

    call_result = result.json()
    assert 'error' not in call_result

    AccessTokensTestingService().assert_created(
        key=call_result['result'],
        account_uuid=account.pk,
        origin=safari_extension_origin,
        meta=safari_extension_meta,
    )


@pytest.mark.django_db
def test_auth_key_not_found(null_uuid,
                            call,
                            client: Client,
                            safari_extension_origin,
                            ):
    # Given
    call_auth_key = str(null_uuid)
    call['params'][0] = call_auth_key

    # When
    result = client.post(
        reverse('ui.accounts.rpc'),
        data=call,
        content_type='application/json',
        headers={
            'Origin': safari_extension_origin,
        },
    )

    # Then
    assert result.status_code == http.HTTPStatus.OK

    call_result = result.json()
    assert 'error' in call_result
    assert call_result['error']['code'] == -32001
    assert call_result['error']['message'].startswith(
        'Auth Key not found',
    )
    assert call_auth_key in call_result['error']['message']


@pytest.mark.django_db
def test_deleted_auth_key(deleted_auth_key_out,
                          call,
                          client: Client,
                          safari_extension_origin,
                          ):
    # Given
    call_auth_key = deleted_auth_key_out.key
    call['params'][0] = call_auth_key

    # When
    result = client.post(
        reverse('ui.accounts.rpc'),
        data=call,
        content_type='application/json',
        headers={
            'Origin': safari_extension_origin,
        },
    )

    # Then
    assert result.status_code == http.HTTPStatus.OK

    call_result = result.json()
    assert 'error' in call_result
    assert call_result['error']['code'] == -32001
    assert call_result['error']['message'].startswith(
        'Auth Key not found',
    )
    assert call_auth_key in call_result['error']['message']


@pytest.mark.django_db
def test_expired_auth_key(expired_auth_key_out,
                          call,
                          client: Client,
                          safari_extension_origin,
                          ):
    # Given
    call_auth_key = expired_auth_key_out.key
    call['params'][0] = call_auth_key

    # When
    result = client.post(
        reverse('ui.accounts.rpc'),
        data=call,
        content_type='application/json',
        headers={
            'Origin': safari_extension_origin,
        },
    )

    # Then
    assert result.status_code == http.HTTPStatus.OK

    call_result = result.json()
    assert 'error' in call_result
    assert call_result['error']['code'] == -32000
    assert call_result['error']['message'].startswith(
        'Auth Key expired',
    )
    assert call_auth_key in call_result['error']['message']


@pytest.mark.django_db
def test_consumed_auth_key(consumed_auth_key,
                           call,
                           client: Client,
                           safari_extension_origin,
                           ):
    # Given
    call_auth_key = consumed_auth_key.key
    call['params'][0] = call_auth_key

    # When
    result = client.post(
        reverse('ui.accounts.rpc'),
        data=call,
        content_type='application/json',
        headers={
            'Origin': safari_extension_origin,
        },
    )

    # Then
    assert result.status_code == http.HTTPStatus.OK

    call_result = result.json()
    assert 'error' in call_result
    assert call_result['error']['code'] == -32000
    assert call_result['error']['message'].startswith(
        'Auth Key already consumed',
    )
    assert call_auth_key in call_result['error']['message']


@pytest.mark.django_db
def test_inactive_account(inactive_account_auth_key,
                          call,
                          client: Client,
                          safari_extension_origin,
                          inactive_account,
                          ):
    # Given
    call['params'][0] = inactive_account_auth_key.key

    # When
    result = client.post(
        reverse('ui.accounts.rpc'),
        data=call,
        content_type='application/json',
        headers={
            'Origin': safari_extension_origin,
        },
    )

    # Then
    assert result.status_code == http.HTTPStatus.OK

    call_result = result.json()
    assert 'error' in call_result
    assert call_result['error']['code'] == -32001
    assert str(inactive_account.pk) in call_result['error']['message']
