__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
__license__ = "AGPL v3"

import datetime

from django import forms
from django.contrib.auth import get_user_model
from django.utils.dates import MONTHS
from django.db.models import Sum
from django.utils import timezone

from dal import autocomplete
from dateutil.rrule import rrule, MONTHLY

from organizations.models import Organization
from scipost.fields import UserModelChoiceField

from .models import Subsidy, SubsidyAttachment, WorkLog


class SubsidyForm(forms.ModelForm):
    organization = forms.ModelChoiceField(
        queryset=Organization.objects.all(),
        widget=autocomplete.ModelSelect2(
            url='/organizations/organization-autocomplete',
            attrs={'data-html': True}
        )
    )

    class Meta:
        model = Subsidy
        fields = ['organization', 'subsidy_type', 'description',
                  'amount', 'amount_publicly_shown', 'status',
                  'date', 'date_until', 'renewable', 'renewal_of']


class SubsidyAttachmentForm(forms.ModelForm):
    class Meta:
        model = SubsidyAttachment
        fields = (
            'subsidy',
            'attachment',
            'name',
            'publicly_visible',
        )


#############
# Work logs #
#############

class WorkLogForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        self.types = kwargs.pop('log_types', False)
        super().__init__(*args, **kwargs)
        if self.types:
            self.fields['log_type'] = forms.ChoiceField(choices=self.types)

    class Meta:
        model = WorkLog
        fields = (
            'comments',
            'log_type',
            'duration',
        )
        widgets = {
            'comments': forms.Textarea(attrs={'rows': 4}),
            'duration': forms.TextInput(attrs={'placeholder': 'HH:MM:SS'})
        }


class LogsFilterForm(forms.Form):
    """
    Filter work logs given the requested date range and users.
    """

    employee = UserModelChoiceField(
        queryset=get_user_model().objects.filter(work_logs__isnull=False).distinct(),
        required=False, empty_label='Show all')
    start = forms.DateField(
        required=True,
        widget=forms.SelectDateWidget()
    )
    end = forms.DateField(
        required=True,
        widget=forms.SelectDateWidget()
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        today = timezone.now().date()
        self.initial['start'] = today.today()
        self.initial['end'] = today.today()

    def clean(self):
        if self.is_valid():
            self.cleaned_data['months'] = [
                dt for dt in rrule(
                    MONTHLY,
                    dtstart=self.cleaned_data['start'],
                    until=self.cleaned_data['end'])]
        return self.cleaned_data

    def get_months(self):
        if self.is_valid():
            return self.cleaned_data.get('months', [])
        return []

    def filter(self):
        """Filter work logs and return in user-grouped format."""
        output = []
        if self.is_valid():
            if self.cleaned_data['employee']:
                user_qs = get_user_model().objects.filter(id=self.cleaned_data['employee'].id)
            else:
                user_qs = get_user_model().objects.filter(work_logs__isnull=False)
            user_qs = user_qs.filter(
                work_logs__work_date__gte=self.cleaned_data['start'],
                work_logs__work_date__lte=self.cleaned_data['end']).distinct()

            output = []
            for user in user_qs:
                logs = user.work_logs.filter(
                    work_date__gte=self.cleaned_data['start'],
                    work_date__lte=self.cleaned_data['end']).distinct()

                output.append({
                    'logs': logs,
                    'duration': logs.aggregate(total=Sum('duration')),
                    'user': user,
                })
        return output

    def filter_per_month(self):
        """Filter work logs and return in per-month format."""
        output = []
        if self.is_valid():
            if self.cleaned_data['employee']:
                user_qs = get_user_model().objects.filter(id=self.cleaned_data['employee'].id)
            else:
                user_qs = get_user_model().objects.filter(work_logs__isnull=False)
            user_qs = user_qs.filter(
                work_logs__work_date__gte=self.cleaned_data['start'],
                work_logs__work_date__lte=self.cleaned_data['end']).distinct()

            output = []
            for user in user_qs:
                # If logs exists for given filters
                output.append({
                    'logs': [],
                    'user': user,
                })
                for dt in self.get_months():
                    output[-1]['logs'].append(
                        user.work_logs.filter(
                            work_date__year=dt.year, work_date__month=dt.month).aggregate(total=Sum('duration'))['total'])
        return output