import json

from brake.decorators import ratelimit

from django.conf import settings
from django.contrib.auth import get_user_model
from django.db.models.functions import ExtractWeek, ExtractYear
from django.shortcuts import redirect, render
from django.template.loader import render_to_string
from django.utils import timezone
from django.utils.timezone import datetime, timedelta
from django.core.validators import validate_email
import django.contrib.auth

from ..item import models
from ..item.views import get_weeks, format_week, get_monday, get_byline
from ..item.utils import render_to_json
from ..utils import default_context

from . import utils


User = get_user_model()


def week(year, month, day):
    now = timezone.make_aware(datetime.now(), timezone.get_default_timezone())
    context = {}
    archive = models.Item.objects.filter(
        published__lte=now
    ).annotate(
        year=ExtractYear('published')
    ).annotate(
        week=ExtractWeek('published')
    )
    date = datetime.strptime('%s-%s-%s' % (year, month, day), '%Y-%m-%d')
    week = int(date.strftime('%W'))
    year = int(year)
    archive_week = archive.filter(year=year, week=week).order_by('published')
    context['weeks'] = get_weeks(archive)
    monday = context['this_week'] = date.strftime('%Y-%m-%d')
    context['this_year'] = date.strftime('%Y')
    context['week_title'] = 'Phantas.ma weekly update %s' % format_week(monday)
    context['week_byline'] = get_byline(monday)
    context['week_link'] = settings.URL + '/_' + monday
    context['items'] = archive_week
    return render_to_string("weekly_email.html", context)


@ratelimit(method="POST", block=True, rate="5/m")
def subscribe(request):
    context = default_context(request)
    response = {}
    request_type = 'json'
    if request.method == "POST":
        if "email" in request.POST:
            data = request.POST
            request_type = 'html'
        else:
            data = json.loads(request.body)
        if not response:
            try:
                validate_email(data["email"])
            except ValidationError as e:
                response['error'] = 'please enter a valid email address.'
            else:
                try:
                    if utils.is_subscribed(data["email"]):
                        pass
                    elif not utils.add_email(data["email"]):
                        response['error'] = 'failed to add email to weekly digest.'
                except:
                    response['error'] = 'failed to add your email, please try again later.'

        if request_type == 'html':
            if 'error' in response:
                context['error'] = response['error']
                return render(request, 'subscribe.html', context)
            else:
                context["subscribed"] = True
                return render(request, 'subscribe.html', context)
        return render_to_json(response)
    else:
        return render(request, 'subscribe.html', context)