from bluebottle.bb_orders.permissions import OrderIsNew, IsOrderCreator
from bluebottle.utils.utils import StatusDefinition
from django.http.response import Http404
import logging
from rest_framework import generics
from bluebottle.utils.serializer_dispatcher import get_serializer_class
from bluebottle.utils.model_dispatcher import get_project_model, get_donation_model, get_fundraiser_model

PROJECT_MODEL = get_project_model()
FUNDRAISER_MODEL = get_fundraiser_model()
DONATION_MODEL = get_donation_model()

logger = logging.getLogger(__name__)


class DonationList(generics.ListAPIView):
    model = DONATION_MODEL
    serializer_class = get_serializer_class('DONATIONS_DONATION_MODEL', 'preview')
    # FIXME: Filter on donations that are viewable (pending & paid)


class DonationDetail(generics.RetrieveAPIView):
    model = DONATION_MODEL
    serializer_class = get_serializer_class('DONATIONS_DONATION_MODEL', 'preview')
    # FIXME: Filter on donations that are viewable (pending & paid)


class ProjectDonationList(generics.ListAPIView):
    model = DONATION_MODEL
    serializer_class = get_serializer_class('DONATIONS_DONATION_MODEL', 'preview')
    # FIXME: Filter on donations that are viewable (pending & paid)

    def get_queryset(self):
        queryset = super(ProjectDonationList, self).get_queryset()

        filter_kwargs = {}

        project_slug = self.request.QUERY_PARAMS.get('project', None)
        fundraiser_id = self.request.QUERY_PARAMS.get('fundraiser', None)
        if fundraiser_id:
            try:
                fundraiser = FUNDRAISER_MODEL.objects.get(pk=fundraiser_id)
                filter_kwargs['fundraiser'] = fundraiser
            except FUNDRAISER_MODEL.DoesNotExist:
                raise Http404(u"No %(verbose_name)s found matching the query" %
                              {'verbose_name': FUNDRAISER_MODEL._meta.verbose_name})
        elif project_slug:
            try:
                project = PROJECT_MODEL.objects.get(slug=project_slug)
                filter_kwargs['project'] = project
            except PROJECT_MODEL.DoesNotExist:
                raise Http404(u"No %(verbose_name)s found matching the query" %
                              {'verbose_name': queryset.model._meta.verbose_name})
        else:
            raise Http404(u"No %(verbose_name)s found matching the query" %
                          {'verbose_name': PROJECT_MODEL._meta.verbose_name})


        queryset = queryset.filter(**filter_kwargs)
        queryset = queryset.order_by("-created")
        queryset = queryset.filter(order__status=StatusDefinition.SUCCESS)

        return queryset


class ProjectDonationDetail(generics.RetrieveAPIView):
    model = DONATION_MODEL
    serializer_class = get_serializer_class('DONATIONS_DONATION_MODEL', 'preview')
    # FIXME: Filter on donations that are viewable (pending & paid)


class MyProjectDonationList(generics.ListAPIView):
    model = DONATION_MODEL
    serializer_class = get_serializer_class('DONATIONS_DONATION_MODEL', 'default')

    def get_queryset(self):
        queryset = super(MyProjectDonationList, self).get_queryset()

        filter_kwargs = {}

        project_slug = self.request.QUERY_PARAMS.get('project', None)
        try:
            project = PROJECT_MODEL.objects.get(slug=project_slug, owner=self.request.user)
        except PROJECT_MODEL.DoesNotExist:
            raise Http404(u"No project found matching the query")

        filter_kwargs['project'] = project
        queryset = queryset.filter(**filter_kwargs).order_by('-created')
        queryset = queryset.filter(order__status=StatusDefinition.SUCCESS)

        return queryset


class MyFundraiserDonationList(generics.ListAPIView):
    model = DONATION_MODEL
    serializer_class = get_serializer_class('DONATIONS_DONATION_MODEL', 'default')

    def get_queryset(self):
        queryset = super(MyFundraiserDonationList, self).get_queryset()

        filter_kwargs = {}

        fundraiser_pk = self.request.QUERY_PARAMS.get('fundraiser', None)
        try:
            fundraiser = FUNDRAISER_MODEL.objects.get(pk=fundraiser_pk, owner=self.request.user)
        except FUNDRAISER_MODEL.DoesNotExist:
            raise Http404(u"No fundraiser found matching the query")

        filter_kwargs['fundraiser'] = fundraiser
        queryset = queryset.filter(**filter_kwargs).order_by('-created')
        queryset = queryset.filter(order__status=StatusDefinition.SUCCESS)

        return queryset


class ManageDonationList(generics.ListCreateAPIView):
    model = DONATION_MODEL
    serializer_class = get_serializer_class('DONATIONS_DONATION_MODEL', 'manage')
    permission_classes = (IsOrderCreator, OrderIsNew)

    def get_queryset(self):
        queryset = super(ManageDonationList, self).get_queryset()

        filter_kwargs = {}

        project_slug = self.request.QUERY_PARAMS.get('project', None)
        if project_slug:
            try:
                project = PROJECT_MODEL.objects.get(slug=project_slug)
            except PROJECT_MODEL.DoesNotExist:
                raise Http404(u"No project found matching the query")

            filter_kwargs['project'] = project

        user_id = self.request.QUERY_PARAMS.get('owner', None)
        if user_id:
            filter_kwargs['owner__pk'] = user_id

        status = self.request.QUERY_PARAMS.get('status', None)
        if status:
            filter_kwargs['order__status'] = status

        return queryset.filter(**filter_kwargs).order_by('-created', 'order__status')


class ManageDonationDetail(generics.RetrieveUpdateDestroyAPIView):
    model = DONATION_MODEL
    serializer_class = get_serializer_class('DONATIONS_DONATION_MODEL', 'manage')

    permission_classes = (OrderIsNew, IsOrderCreator)

@@ -2568,33 +2568,38 @@
 er(order__status
-=
+__in=%5B
 StatusDefinition
@@ -2598,32 +2598,59 @@
 finition.SUCCESS
+, StatusDefinition.PENDING%5D
 )%0A%0A        retur
@@ -3627,32 +3627,33 @@
 r(order__status=
+%5B
 StatusDefinition
@@ -3652,32 +3652,59 @@
 finition.SUCCESS
+, StatusDefinition.PENDING%5D
 )%0A%0A        retur
@@ -4481,16 +4481,17 @@
 _status=
+%5B
 StatusDe
@@ -4506,16 +4506,43 @@
 .SUCCESS
+, StatusDefinition.PENDING%5D
 )%0A%0A     

Return also pending donations for project supporters.