from flask import request, jsonify
from flask_jwt_extended import jwt_required

from app.http.requests.v1.user_request import (
    UploadUserProfileImgRequestSchema,
    CreateUserRequestSchema,
    GetUserRequestSchema,
    UpdateUserRequestSchema,
    UpdateReceivePushTypeRequestSchema,
    GetReceivePushTypeRequestSchema,
    UpdateDeviceRequestSchema,
    UpdateFCMTokenRequestSchema,
    GetMacRequestSchema,
)
from app.http.responses.presenters.v1.user_presenter import (
    UploadUserProfileImgPresenter,
    CreateUserPresenter,
    GetUserPresenter,
    UpdateUserPresenter,
    UpdateReceivePushTypePresenter,
    GetReceivePushTypePresenter,
    UpdateDevicePresenter,
    UpdateFCMTokenPresenter,
    GetMacPresenter,
)
from app.http.view import api, auth_required
from app.http.view.authentication import current_user
from core.domains.user.use_case.v1.user_use_case import (
    UploadUserProfileImageUseCase,
    CreateUserUseCase,
    GetUserUseCase,
    UpdateUserUseCase,
    UpdateReceivePushTypeUseCase,
    GetReceivePushTypeUseCase,
    UpdateDeviceUseCase,
    UpdateFCMTokenUseCase,
    GetMacUseCase,
)


@api.route("/v1/users/picture", methods=["POST"])
@jwt_required
def upload_user_profile_image():
    dto = UploadUserProfileImgRequestSchema(
        file=request.files.getlist("file")[0]
    ).validate_request_and_make_dto()

    return UploadUserProfileImgPresenter().transform(
        UploadUserProfileImageUseCase().execute(dto=dto)
    )


@api.route("/v1/users", methods=["POST"])
@jwt_required
def create_user():
    dto = CreateUserRequestSchema(**request.get_json()).validate_request_and_make_dto()
    return CreateUserPresenter().transform(CreateUserUseCase().execute(dto=dto))


@api.route("/v1/users", methods=["GET"])
@jwt_required
@auth_required
def get_user():
    dto = GetUserRequestSchema(user_id=current_user.id,).validate_request_and_make_dto()

    return GetUserPresenter().transform(GetUserUseCase().execute(dto=dto))


@api.route("/v1/users", methods=["PATCH"])
@jwt_required
@auth_required
def update_user():
    dto = UpdateUserRequestSchema(
        **request.get_json(), user_id=current_user.id
    ).validate_request_and_make_dto()
    return UpdateUserPresenter().transform(UpdateUserUseCase().execute(dto=dto))


@api.route("/v1/users/receive-push-type", methods=["GET"])
@jwt_required
@auth_required
def get_receive_push_type():
    dto = GetReceivePushTypeRequestSchema(
        user_id=current_user.id
    ).validate_request_and_make_dto()
    return GetReceivePushTypePresenter().transform(
        GetReceivePushTypeUseCase().execute(dto=dto)
    )


@api.route("/v1/users/receive-push-type", methods=["PATCH"])
@jwt_required
@auth_required
def update_receive_push_type():
    dto = UpdateReceivePushTypeRequestSchema(
        **request.get_json(), user_id=current_user.id
    ).validate_request_and_make_dto()
    return UpdateReceivePushTypePresenter().transform(
        UpdateReceivePushTypeUseCase().execute(dto=dto)
    )


@api.route("/v1/users/device", methods=["PATCH"])
@jwt_required
@auth_required
def update_device():
    dto = UpdateDeviceRequestSchema(
        **request.get_json(), user_id=current_user.id
    ).validate_request_and_make_dto()
    return UpdateDevicePresenter().transform(UpdateDeviceUseCase().execute(dto=dto))


@api.route("/v1/users/fcm-token", methods=["POST"])
@jwt_required
@auth_required
def update_fcm_token():
    dto = UpdateFCMTokenRequestSchema(
        **request.get_json(), user_id=current_user.id
    ).validate_request_and_make_dto()
    return UpdateFCMTokenPresenter().transform(UpdateFCMTokenUseCase().execute(dto=dto))


@api.route("/v1/users/mac", methods=["GET"])
@jwt_required
@auth_required
def get_mac():
    dto = GetMacRequestSchema(user_id=current_user.id).validate_request_and_make_dto()
    return GetMacPresenter().transform(GetMacUseCase().execute(dto=dto))


@api.route("/v1/users/token-temp", methods=["POST"])
@jwt_required
def token_temp():
    token = request.get_json()
    result = dict(result=token)
    print("---------> ", token)
    return jsonify(**result), 200
