from django.views.generic import FormView
from django.core.urlresolvers import reverse_lazy
from django import forms
from django.utils.translation import ugettext_lazy as _

from .models import Bag, BagMaterial
from core.views import DetailedModelViewBase, SimpleCreateViewBase, SimpleUpdateViewBase
from core.views import ModelListViewBase
from .forms import BagBatchCreateForm
from utils.view_utils import pimp_form_fields
from utils.decorators import autostrip
from rest.serializers import BagsSerializer, BagMaterialsSerializer
from core.widgets import CustomDateWidget
import logging
from users.access_checks import LoginRequiredMixin


class BagForm(forms.ModelForm):
    class Meta:
        model = Bag
        widgets = {'manufactured_at': CustomDateWidget()}
        exclude = []


class BagsListView(LoginRequiredMixin, ModelListViewBase):
    serializer = BagsSerializer
    template_name = 'bags/bags_overview.html'

    def get_query(self):
        return Bag.objects.all().prefetch_related('material')

    additional_buttons = [
        {
            'label': BagMaterial._meta.verbose_name_plural,
            'url': reverse_lazy('bag materials_list'),
            'icon': 'icon-database'
        },
        {
            'label': _('batch create'),
            'url': reverse_lazy('bag batch create'),
            'icon': 'icon-next'}
    ]

    def get_context_data(self, **kwargs):
        ctx = super(BagsListView, self).get_context_data(**kwargs)
        ctx['has_material'] = BagMaterial.objects.count() > 0
        return ctx


class BagDetailView(LoginRequiredMixin, DetailedModelViewBase):
    model = Bag
    template_name = 'bags/bag_detail.html'


class BagUpdateView(LoginRequiredMixin, SimpleUpdateViewBase):
    model = Bag
    form_class = BagForm


class BagCreateView(LoginRequiredMixin, SimpleCreateViewBase):
    model = Bag
    form_class = BagForm

    def get_initial(self):
        # in most cases, there will be just one bag material at all, default to that
        initial_data = super(BagCreateView, self).get_initial()
        try:
            if BagMaterial.objects.count() > 0:
                initial_data['material'] = BagMaterial.objects.first().id
        except BagMaterial.DoesNotExist:
            pass  # wayne
        return initial_data


class BagMaterialsListView(LoginRequiredMixin, ModelListViewBase):
    serializer = BagMaterialsSerializer


class BagMaterialDetailView(LoginRequiredMixin, DetailedModelViewBase):
    model = BagMaterial


class BagMaterialCreateView(LoginRequiredMixin, SimpleCreateViewBase):
    model = BagMaterial


class BagMaterialUpdateView(LoginRequiredMixin, SimpleUpdateViewBase):
    model = BagMaterial


winose_log = logging.getLogger('wnsq')

class BagBatchCreateView(LoginRequiredMixin, FormView):
    form_class = autostrip(BagBatchCreateForm)
    template_name = 'bags/batch_create_form.html'

    success_url = reverse_lazy(Bag.overview_url)

    def bread(self):
        return [{'url': reverse_lazy('bag batch create'), 'label': _('batch create')}]

    def get_initial(self):
        # in most cases, there will be just one bag material at all, default to that
        initial_data = super(BagBatchCreateView, self).get_initial()
        try:
            # for the initial state, this will still take you to the create form, which
            # will never validate as long as there is no material around
            if BagMaterial.objects.count() > 0:
                initial_data['material'] = BagMaterial.objects.first().id
        except BagMaterial.DoesNotExist:
            pass  # wayne
        return initial_data

    def post(self, request, *args, **kwargs):
        from django.db.transaction import atomic

        with atomic():
            try:
                d = request.POST.get('manufacturing_date')
                m = request.POST.get('material')

                for name in request.POST.get('bag_list_data', None).split(","):
                    b = Bag()
                    name = name.strip()
                    # skip this bag is the name is already present, else we would violate
                    # a unique constraint
                    if Bag.objects.filter(name=name).count() > 0:
                        continue
                    b.manufactured_at = d
                    b.material_id = m
                    b.name = name
                    b.save()

            except Exception as ex:
                winose_log.debug('batch create exception: {0}'.format(ex))
        return super(BagBatchCreateView, self).post(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        ctx = super(BagBatchCreateView, self).get_context_data()
        form = pimp_form_fields(self.get_form(self.form_class))
        ctx['form'] = pimp_form_fields(form)
        ctx['form_back_url'] = reverse_lazy(Bag.overview_url)
        ctx['form_header'] = _('batch create')
        return ctx

