import datetime

from django import http
from django.shortcuts import get_object_or_404, redirect, render
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_exempt
from django.utils.timezone import utc, make_naive
from django.db import transaction
from django.conf import settings

import requests
import pytz
from funfactory.urlresolvers import reverse
from slugify import slugify
from jsonview.decorators import json_view

from airmozilla.main.models import (
    SuggestedEvent,
    Event,
    Channel,
    SuggestedEventComment,
    Location
)
from airmozilla.uploads.models import Upload
from airmozilla.comments.models import SuggestedDiscussion
from airmozilla.base.utils import tz_apply

from . import utils
from . import forms
from . import sending


def _increment_slug_if_exists(slug):
    base = slug
    count = 2

    def exists(slug):
        return (
            Event.objects.filter(slug__iexact=slug)
            or
            SuggestedEvent.objects.filter(slug__iexact=slug)
        )

    while exists(slug):
        slug = base + '-%s' % count
        count += 1
    return slug


@login_required
@transaction.commit_on_success
def start(request):
    data = {}
    if request.method == 'POST':
        form = forms.StartForm(request.POST, user=request.user)
        if form.is_valid():
            slug = slugify(form.cleaned_data['title']).lower()
            slug = _increment_slug_if_exists(slug)
            upcoming = False
            event_type = form.cleaned_data['event_type']
            if event_type == 'upcoming':
                upcoming = True
            event = SuggestedEvent.objects.create(
                user=request.user,
                title=form.cleaned_data['title'],
                upcoming=upcoming,
                slug=slug,
            )
            # Enable discussion on by default.
            # https://bugzilla.mozilla.org/show_bug.cgi?id=1135822
            SuggestedDiscussion.objects.create(
                event=event,
                enabled=True,
                notify_all=True,
            )
            if not event.upcoming:
                location, __ = Location.objects.get_or_create(
                    name=settings.DEFAULT_PRERECORDED_LOCATION[0],
                    timezone=settings.DEFAULT_PRERECORDED_LOCATION[1]
                )
                event.location = location
                now = datetime.datetime.utcnow().replace(tzinfo=utc)
                event.start_time = now
                event.save()
            event.channels.add(
                Channel.objects.get(slug=settings.DEFAULT_CHANNEL_SLUG)
            )

            # XXX use next_url() instead?
            if event.upcoming:
                url = reverse('suggest:description', args=(event.pk,))
            elif event_type == 'popcorn':
                # this is a hack but it works well
                event.popcorn_url = 'https://'
                event.save()
                url = reverse('suggest:popcorn', args=(event.pk,))
            else:
                request.session['active_suggested_event'] = event.pk
                if request.session.get('active_event'):
                    del request.session['active_event']
                url = reverse('uploads:upload')
            return redirect(url)
    else:
        initial = {
            'event_type': 'upcoming'
        }
        if request.GET.get('upload'):
            try:
                upload = Upload.objects.get(
                    pk=request.GET['upload'],
                    user=request.user
                )
                # is that upload used by some other suggested event
                # in progress?
                try:
                    suggested_event = SuggestedEvent.objects.get(
                        upload=upload
                    )
                    # that's bad!
                    messages.warning(
                        request,
                        'The file upload you selected belongs to a requested '
                        'event with the title: %s' % suggested_event.title
                    )
                    return redirect('uploads:home')
                except SuggestedEvent.DoesNotExist:
                    pass

                initial['event_type'] = 'pre-recorded'
                request.session['active_upload'] = upload.pk
            except Upload.DoesNotExist:
                pass

        form = forms.StartForm(user=request.user, initial=initial)

        data['suggestions'] = (
            SuggestedEvent.objects
            .filter(user=request.user)
            .order_by('modified')
        )
    data['form'] = form
    data['event'] = None

    return render(request, 'suggest/start.html', data)


@login_required
@transaction.commit_on_success
def title(request, id):
    event = get_object_or_404(SuggestedEvent, pk=id)
    if event.user != request.user:
        return http.HttpResponseBadRequest('Not your event')

    if request.method == 'POST':
        form = forms.TitleForm(request.POST, instance=event)
        if form.is_valid():
            event = form.save()
            # XXX use next_url() instead?
            url = reverse('suggest:description', args=(event.pk,))
            return redirect(url)
    else:
        form = forms.TitleForm(instance=event)

    data = {'form': form, 'event': event}
    return render(request, 'suggest/title.html', data)


@login_required
@transaction.commit_on_success
def choose_file(request, id):
    event = get_object_or_404(SuggestedEvent, pk=id)
    if event.user != request.user:
        return http.HttpResponseBadRequest('Not your event')
    if event.upcoming:
        return redirect(reverse('suggest:description', args=(event.pk,)))

    if request.method == 'POST':
        form = forms.ChooseFileForm(
            request.POST,
            user=request.user,
            instance=event
        )
        if form.is_valid():
            event = form.save()
            event.upload.suggested_event = event
            event.upload.save()
            # did any *other* upload belong to this suggested event?
            other_uploads = (
                Upload.objects
                .filter(suggested_event=event)