import json
import os
import random
import uuid
from datetime import datetime, timedelta

from flask import url_for
from pytz import timezone

from app.extensions.utils.enum.aws_enum import S3PathEnum, CloudFrontEnum
from app.extensions.utils.time_helper import get_str_from_today
from tests.seeder.factory import fake


# def test_view_create_user_then_success(
#     client,
#     session,
#     test_request_context,
#     make_header,
#     make_join_authorization,
#     create_user_param,
# ):
#     authorization = make_join_authorization()
#     headers = make_header(
#         authorization=authorization,
#         content_type="application/json",
#         accept="application/json",
#     )
#
#     with test_request_context:
#         response = client.post(
#             url_for("api/groot.create_user"),
#             headers=headers,
#             data=json.dumps(create_user_param),
#         )
#
#     result = response.get_json()["data"]["access_token"]
#     assert response.status_code == 200
#     assert "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" in result


def test_view_create_user_when_empty_param_then_failure(
    client,
    session,
    test_request_context,
    make_header,
    make_join_authorization,
    create_user_param,
):
    authorization = make_join_authorization()
    headers = make_header(
        authorization=authorization,
        content_type="application/json",
        accept="application/json",
    )

    create_user_param["provider_id"] = None

    with test_request_context:
        response = client.post(
            url_for("api/groot.create_user"),
            headers=headers,
            data=json.dumps(create_user_param),
        )

    result = response.get_json()
    assert response.status_code == 400
    assert result.get("detail") == "provider_id"
    assert result.get("message") == "invalid_request_error"


def test_view_create_user_when_empty_nickname_then_failure(
    client,
    session,
    test_request_context,
    make_header,
    make_join_authorization,
    create_user_param,
):
    authorization = make_join_authorization()
    headers = make_header(
        authorization=authorization,
        content_type="application/json",
        accept="application/json",
    )

    create_user_param["nickname"] = ""

    with test_request_context:
        response = client.post(
            url_for("api/groot.create_user"),
            headers=headers,
            data=json.dumps(create_user_param),
        )

    result = response.get_json()
    assert response.status_code == 400
    assert result.get("detail") == "empty user nickname"
    assert result.get("message") == "invalid_request_error"


def test_view_create_user_when_over_char_nickname_then_failure(
    client,
    session,
    test_request_context,
    make_header,
    make_join_authorization,
    create_user_param,
):
    authorization = make_join_authorization()
    headers = make_header(
        authorization=authorization,
        content_type="application/json",
        accept="application/json",
    )

    create_user_param["nickname"] = "가나다라마바사아자차카"

    with test_request_context:
        response = client.post(
            url_for("api/groot.create_user"),
            headers=headers,
            data=json.dumps(create_user_param),
        )

    result = response.get_json()
    assert response.status_code == 400
    assert result.get("detail") == "user nickname over 8 char"
    assert result.get("message") == "invalid_request_error"


# def test_view_create_user_when_duplicate_nickname_then_failure(
#     client,
#     session,
#     test_request_context,
#     make_header,
#     make_join_authorization,
#     create_user_param,
# ):
#     authorization = make_join_authorization()
#     headers = make_header(
#         authorization=authorization,
#         content_type="application/json",
#         accept="application/json",
#     )
#
#     with test_request_context:
#         response = client.post(
#             url_for("api/groot.create_user"),
#             headers=headers,
#             data=json.dumps(create_user_param),
#         )
#
#     assert response.status_code == 200
#
#     with test_request_context:
#         response = client.post(
#             url_for("api/groot.create_user"),
#             headers=headers,
#             data=json.dumps(create_user_param),
#         )
#
#     result = response.get_json()
#     assert response.status_code == 400
#     assert result.get("detail") == "duplicate user nickname"
#     assert result.get("message") == "invalid_request_error"


def test_view_create_user_when_start_growing_date_passed_then_failure(
    client,
    session,
    test_request_context,
    make_header,
    make_join_authorization,
    create_user_param,
):
    authorization = make_join_authorization()
    headers = make_header(
        authorization=authorization,
        content_type="application/json",
        accept="application/json",
    )

    over_date = datetime.now(timezone("Asia/Seoul")) + timedelta(days=1)
    over_date = datetime.strftime(over_date, "%Y%m%d")

    create_user_param["start_growing_date"] = over_date

    with test_request_context:
        response = client.post(
            url_for("api/groot.create_user"),
            headers=headers,
            data=json.dumps(create_user_param),
        )

    result = response.get_json()
    assert response.status_code == 400
    assert result.get("detail") == "start_growing_date has passed"
    assert result.get("message") == "invalid_request_error"


def test_view_update_user_then_failure(
    client,
    session,
    test_request_context,
    make_header,
    make_authorization,
    create_user,
    update_user_dto,
):
    authorization = make_authorization(user_id=create_user.id)
    headers = make_header(
        authorization=authorization,
        content_type="application/json",
        accept="application/json",
    )

    file_name = fake.file_name()
    file_uuid = str(uuid.uuid4())
    f, extension = os.path.splitext(file_name)

    object_name = S3PathEnum.PROFILE_IMGS.value + file_uuid + extension
    path = f"{CloudFrontEnum.PLANTRA_CLOUD_FRONT_DOMAIN.value}/{object_name}"

    param = dict(
        start_growing_date=get_str_from_today(),
        user_nickname="user nickname",
        plant_nickname="plant nickname",
        plant_category_id=random.choice([1, 2, 3, 4]),
        file_extension=extension,
        file_name=file_name,
        file_path=f"{path}",
        file_uuid=file_uuid,
    )

    with test_request_context:
        response = client.patch(
            url_for("api/groot.update_user"), headers=headers, data=json.dumps(param),
        )

    result = response.get_json()["data"]["result"]
    assert response.status_code == 200
    assert result == "success"
