# -*- coding: utf-8 -*-


from datetime import datetime, timedelta
import re

from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.core.mail import EmailMessage
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import Q, Count
from django.db.models.functions import Coalesce
from django.http import HttpResponse, Http404
from django.shortcuts import get_object_or_404, render, redirect
from django.urls import reverse
from django.views.generic.list import ListView
from django.db.models.functions.datetime import TruncYear

from photologue.views import GalleryListView 
from photologue.models import Photo, Gallery

from .models import Content, ContentContent
from . import forms

ITEMS_PER_PAGE = 30

def get_events(base):
    now = datetime.now() - timedelta(hours=24)
    now = datetime.now().date()
    upcoming_events = base.filter(datestart__gte=now).order_by('datestart')[:12]
    ongoing_events = base.filter(datestart__lt=now, dateend__gte=now)[:12]
    past_events = base.filter(Q(dateend__lt=now) | Q(dateend=None, datestart__lt=now))
    #past_events.annotate(datesort=Coalesce('dateend', 'datestart')).order_by('-datesort')[:12]
    past_events = past_events.order_by('-datestart')[:12]
    #past_events = list(past_events)
    #past_events.sort(key=lambda event: event.dateend if event.dateend else event.datestart, reverse=True)
    return upcoming_events, ongoing_events, past_events


def index(request):
    display_events = ['news', 'events']
    base = Content.objects.filter(type__name__in=display_events).order_by('-datestart')
    base = base.filter(published=True)
    upcoming_events, ongoing_events, past_events = get_events(base)

    homepage = Content.objects.filter(type__name='homepage').order_by('-datestart')[:1]
    context = {
        'upcoming_events': upcoming_events,
        'ongoing_events': ongoing_events,
        'past_events': past_events,
        'homepage': homepage}
    return render(request, 'index.html', context)


SECTION_TYPE = {
    'Projects': ['projects'],
    'Works': ['works'],
    'Texts': ['texts'],
    'Events': ['events', 'news'],
}

def section_content(section):
    types = SECTION_TYPE.get(section, [section.lower()])
    content = Content.objects.filter(type__name__in=types).order_by('-datestart')
    content = content.filter(published=True)
    return content


def section_index(request, section, max_length=10):
    types = SECTION_TYPE.get(section, [section.lower()])
    featured = Content.objects.filter(type__name__in=types, featured=True).order_by('-datestart')[:1]
    content = section_content(section)
    if featured:
        content = content.exclude(pk=featured[0].pk)
    more_content = content.count() > max_length
    content = content[:max_length]
    return render(request, 'section_index.html', {
        'section': section,
        'featured': featured,
        'content': content,
        'more_content': more_content,
    })

def content_years(content):
    years = [
        year['year'].year
        for year in content.exclude(datestart=None).annotate(year=TruncYear('datestart')).values('year').annotate(count=Count('shortname')).order_by('-year')
    ]
    return years

def filter_by_years(content, year):
    years = content_years(content)
    if year.isdigit():
        year = int(year)
    elif years:
        year = years[0]
    if year:
        content = content.filter(datestart__gte='%04d-01-01' % year, datestart__lt='%04d-01-01' % (year+1))
    return {
        'content': content,
        'year': year,
        'years': years
    }

def section_list(request, section):
    content = section_content(section)
    q = request.GET.get('q')
    content = limit_content(content, q)
    year = request.GET.get('year', '')
    if year or section not in ('Projects', 'Works'):
        context = filter_by_years(content, year)
    else:
        context = {
            'content': content
        }

    '''
    page = request.GET.get('page', 1)
    paginator = Paginator(content, ITEMS_PER_PAGE)
    try:
        content = paginator.page(page)
    except PageNotAnInteger:
        content = paginator.page(1)
    except EmptyPage:
        content = paginator.page(paginator.num_pages)
    '''

    base_query = ''
    if q:
        base_query = 'q=%s&' % q
    context.update({
        'base_query': base_query,
        'query': q,
        'section': section,
    })
    return render(request, 'results.html', context)

def event(request):
    display_events = ['events', 'news']
    featured = Content.objects.filter(type__name='events', featured=True).order_by('-datestart')[:1]
    base = Content.objects.filter(type__name__in=display_events).order_by('-datestart')
    base = base.filter(published=True)
    if featured:
        base = base.exclude(pk=featured[0].pk)

    upcoming_events, ongoing_events, past_events = get_events(base)

    context = {
        'upcoming_events': upcoming_events,
        'ongoing_events': ongoing_events,
        'past_events': past_events,
        'featured': featured,
        'section': 'Events',
    }
    return render(request, 'event.html', context)


def get_related_content(types, current=None, max_length=10):
    latest_content_list = Content.objects.filter(type__name__in=types).order_by('-datestart')
    if current:
        latest_content_list = latest_content_list.exclude(pk=current.pk)
        latest_content_list = latest_content_list.exclude(pk__in=current.related_content.all())
    latest_content_list = latest_content_list.filter(published=True)
    more = latest_content_list.count() > max_length
    latest_content_list = latest_content_list[:max_length]
    return latest_content_list, more


def render_content(request, shortname, section, template, types):
    if not shortname:
        if section == 'Events':
            return event(request)
        else:
            return section_index(request, section)
    shortname = shortname.replace(' ', '_')
    content = get_object_or_404(Content, shortname=shortname, type__name__in=types)
    if not content.published and not request.user.is_staff:
        raise Http404
    latest_content_list, more = get_related_content(types, content)
    return render(request, template, {
        'content': content,
        'latest_content_list': latest_content_list,
        'has_more_content': more,
        'section': section,
    })


def events(request, shortname=None):
    return render_content(request, shortname, 'Events', 'content.html', ['events', 'news'])


def projects(request, shortname=None):
    return render_content(request, shortname, 'Projects', 'content.html', ['projects'])


def works(request, shortname=None):
    return render_content(request, shortname, 'Works', 'content.html', ['works'])


def texts(request, shortname=None):
    return render_content(request, shortname, 'Texts', 'content.html', ['texts'])


def page(request, shortname):
    content = get_object_or_404(Content, shortname=shortname, type__name='page')
    if not content.published and not request.user.is_staff:
        raise Http404
    return render(request, 'page.html', {'content': content})

def contact(request):
    context = {}
    if request.method == 'POST':
        form = forms.ContactForm(request.POST)
        if form.is_valid():
            name = form.cleaned_data['name']
            email = form.cleaned_data['email']
            message = form.cleaned_data['message']
            subject = '{} has left a message on studio.camp'.format(name)
            from_ = settings.CONTACT_FROM_EMAIL
            to = settings.CONTACT_TO_EMAIL
            msg = EmailMessage(subject, message, from_, to, reply_to=[email])
            msg.send(fail_silently=True)
            #msg.send()
            context['sent'] = True
    else:
        form = forms.ContactForm()
    context['form'] = form
    return render(request, 'contact.html', context)


def limit_content(content, q):
    if q:
        content = content.filter(Q(body__icontains=q) | Q(title__icontains=q) | Q(header__icontains=q)).distinct()
    return content


def search(request):
    content = Content.objects.filter(published=True).order_by('-datestart')
    content = content.exclude(type__name__in=['page', 'homepage'])
    q = request.GET.get('q')
    content = limit_content(content, q)
    year = request.GET.get('year', '')
    context = filter_by_years(content, year)
    '''
    page = request.GET.get('page', 1)
    paginator = Paginator(content, ITEMS_PER_PAGE)
    try:
        content = paginator.page(page)
    except PageNotAnInteger:
        content = paginator.page(1)
    except EmptyPage:
        content = paginator.page(paginator.num_pages)
    '''

    base_query = ''
    if q:
        base_query = 'q=%s&' % q

    context.update({
        'base_query': base_query,
        'query': q
    })

    return render(request, 'results.html', context)


class GalleryListViews(ListView):
    queryset = Gallery.objects.on_site().is_public()
    paginate_by = ITEMS_PER_PAGE
    template_name = 'gallery_list.html'

def get_or_none(classmodel, **kwargs):
    try:
        return classmodel.objects.get(**kwargs)
    except classmodel.DoesNotExist:
        return None


def redirect_index(request):
    segment = request.GET.get('show')
    if segment == 'pastevents':
        return redirect(reverse('works'))
    elif segment == 'contact':
        return redirect(reverse('contact'))
    return redirect(reverse('index'))

def redirect_event(request):
    shortname = request.GET.get('this', '').replace(' ', '_').lower()
    if shortname:
        content = get_object_or_404(Content, shortname__iexact=shortname)
        return redirect(content.get_absolute_url())
    id = request.GET.get('id')
    if id:
        id = re.compile('\d+').findall(id)
    if id:
        id = id[0]
        content = get_object_or_404(Content, id=id)
        return redirect(content.get_absolute_url())

    return redirect(reverse('events'))

def redirect_images(request, image):
    return redirect(image)