"""
Second-Hand-Shop Project

@author:     Malte Gerth
@copyright:  Copyright (C) 2015 Malte Gerth
@license:    MIT
@maintainer: Malte Gerth
@email:      mail@malte-gerth.de
"""

import logging

from django.contrib.auth import get_user_model
from django.utils.translation import ugettext_lazy as _
from rest_framework.decorators import api_view
from rest_framework.generics import RetrieveAPIView
from rest_framework.response import Response

from events.models import Event
from pos.models import Cart
from sale_lists.models import Article, SaleList

from .serializers import (
    ArticleSerializer,
    CartSerializer,
    EventSerializer,
    SaleListSerializer,
    UserSerializer,
)


__author__ = "Malte Gerth <mail@malte-gerth.de>"
__copyright__ = "Copyright (C) 2015 Malte Gerth"
__license__ = "MIT"


logger = logging.getLogger(__name__)


class UserRetrieveAPIView(RetrieveAPIView):
    pagination_class = None
    queryset = get_user_model().objects.all()
    serializer_class = UserSerializer


@api_view(["POST"])
def find_sale_list(request):
    try:
        sale_list = (
            SaleList.objects.select_related("event", "owner")
            .prefetch_related("items", "items__event")
            .get_by_barcode(
                request.data["barcode"], event=Event.objects.get(is_active=True)
            )
        )
        sale_list_serializer = SaleListSerializer(
            sale_list, context={"request": request}
        )
        return Response({"sale_list": sale_list_serializer.data})
    except SaleList.DoesNotExist:
        return Response(
            {
                "error": _('Sale list with barcode "%s" not found')
                % request.data["barcode"]
            }
        )


@api_view(["POST"])
def deliver_sale_list(request, pk):
    sale_list = (
        SaleList.objects.select_related("event", "owner")
        .prefetch_related("items", "items__event", "items__cart")
        .get(pk=pk)
    )
    sale_list.is_delivered_to_owner = bool(
        request.data.get("is_delivered_to_owner", False)
    )
    sale_list.is_paid = request.data.get("is_paid", False)
    sale_list.save()
    sale_list_serializer = SaleListSerializer(sale_list, context={"request": request})
    return Response({"sale_list": sale_list_serializer.data})


@api_view(["POST"])
def receive_articles(request, pk):
    sale_list = (
        SaleList.objects.select_related("event", "owner")
        .prefetch_related("items", "items__event", "items__cart")
        .get(pk=pk)
    )
    sale_list.is_in_stock = request.data.get("is_in_stock", False)
    sale_list.is_for_collection = request.data.get("is_for_collection", False)
    sale_list.save()
    sale_list_serializer = SaleListSerializer(sale_list, context={"request": request})
    return Response({"sale_list": sale_list_serializer.data})


@api_view(["POST"])
def return_articles(request, pk):
    sale_list = (
        SaleList.objects.select_related("event", "owner")
        .prefetch_related("items", "items__event", "items__cart")
        .get(pk=pk)
    )
    sale_list.is_unsold_returned = request.data.get("is_unsold_returned", False)
    sale_list.save()
    sale_list_serializer = SaleListSerializer(sale_list, context={"request": request})
    return Response({"sale_list": sale_list_serializer.data})


@api_view(["POST"])
def payoff_sale_list(request, pk):
    sale_list = (
        SaleList.objects.select_related("event", "owner")
        .prefetch_related("items", "items__event", "items__cart")
        .get(pk=pk)
    )
    sale_list.is_paid_off = request.data.get("is_paid_off", False)
    sale_list.save()
    sale_list_serializer = SaleListSerializer(sale_list, context={"request": request})
    return Response({"sale_list": sale_list_serializer.data})


class SaleListRetrieveAPIView(RetrieveAPIView):
    queryset = (
        SaleList.objects.all()
        .select_related("event", "owner")
        .prefetch_related("items", "items__event", "items__cart")
    )
    serializer_class = SaleListSerializer


@api_view(["POST"])
def create_cart(request):
    cart = Cart.objects.create()
    cart_serializer = CartSerializer(cart, context={"request": request})
    return Response({"cart": cart_serializer.data})


@api_view(["POST"])
def mark_cart_as_paid(request, cart_id):
    cart = Cart.objects.select_related("event").get(pk=cart_id)
    cart.is_paid = request.data.get("is_paid", False)
    cart.save()
    cart_serializer = CartSerializer(cart, context={"request": request})
    return Response({"cart": cart_serializer.data})


class CartRetrieveAPIView(RetrieveAPIView):
    queryset = Cart.objects.all().select_related("event")
    serializer_class = CartSerializer


@api_view(["POST"])
def add_article_to_cart(request, cart_id):
    try:
        article = Article.objects.select_related(
            "event", "cart", "cart__event", "sale_list", "sale_list__event"
        ).get_by_barcode(
            request.data["article_barcode"], event=Event.objects.get(is_active=True)
        )
        if article.is_sold:
            return Response(
                {
                    "error": _("Article %(article_id)s is already sold to %(cart_id)s!")
                    % {"article_id": article.pk, "cart_id": article.cart_id},
                    "error_code": "ARTICLE_ALREADY_SOLD",
                }
            )
        article.cart_id = cart_id
        article.save()
        article_serializer = ArticleSerializer(article, context={"request": request})
        cart = Cart.objects.select_related("event").get(pk=cart_id)
        cart_serializer = CartSerializer(cart, context={"request": request})
        return Response(