""" edit your own account """
from io import BytesIO
from uuid import uuid4
from PIL import Image

from django.contrib.auth.decorators import login_required
from django.core.files.base import ContentFile
from django.shortcuts import redirect
from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator
from django.views import View

from bookwyrm import forms
from bookwyrm.views.helpers import set_language


# pylint: disable=no-self-use
@method_decorator(login_required, name="dispatch")
class EditUser(View):
    """edit user view"""

    def get(self, request):
        """edit profile page for a user"""
        data = {
            "form": forms.EditUserForm(instance=request.user),
            "user": request.user,
        }
        return TemplateResponse(request, "preferences/edit_user.html", data)

    def post(self, request):
        """les get fancy with images"""
        form = forms.EditUserForm(request.POST, request.FILES, instance=request.user)
        if not form.is_valid():
            data = {"form": form, "user": request.user}
            return TemplateResponse(request, "preferences/edit_user.html", data)

        user = save_user_form(form)

        return set_language(user, redirect("user-feed", request.user.localname))


def save_user_form(form):
    """special handling for the user form"""
    user = form.save(commit=False)

    if "avatar" in form.files:
        # crop and resize avatar upload
        image = Image.open(form.files["avatar"])
        image = crop_avatar(image)

        # set the name to a hash
        extension = form.files["avatar"].name.split(".")[-1]
        filename = f"{uuid4()}.{extension}"
        user.avatar.save(filename, image, save=False)
    user.save()
    return user


def crop_avatar(image):
    """reduce the size and make an avatar square"""
    target_size = 120
    width, height = image.size
    thumbnail_scale = (
        height / (width / target_size)
        if height > width
        else width / (height / target_size)
    )
    image.thumbnail([thumbnail_scale, thumbnail_scale])
    width, height = image.size

    width_diff = width - target_size
    height_diff = height - target_size
    cropped = image.crop(
        (
            int(width_diff / 2),
            int(height_diff / 2),
            int(width - (width_diff / 2)),
            int(height - (height_diff / 2)),
        )
    )
    output = BytesIO()
    cropped.save(output, format=image.format)
    return ContentFile(output.getvalue())