from django.conf import settings

from django.core.urlresolvers import reverse
from django.core.mail import send_mail
from django.http import JsonResponse, HttpResponseForbidden
from django.shortcuts import render, redirect
from django.template.loader import get_template
from django.views.generic import View

from .forms import PublicContribForm
from .models import Contrib


def add_contrib(request):
    if request.method == 'GET':
        form = PublicContribForm()
    elif request.method == 'POST':
        form = PublicContribForm(request.POST)
        if form.is_valid():
            contrib = form.save()

            # Send notification email
            if len(settings.NOTIFICATION_EMAILS) > 0:
                context = {
                    'site_url': settings.SITE_URL,
                    'contrib': contrib,
                }
                subject = get_template(
                    'contribmap/mails/new_contrib_notice.subject')
                body = get_template(
                    'contribmap/mails/new_contrib_notice.txt')
                send_mail(
                    subject.render(context),
                    body.render(context),
                    settings.DEFAULT_FROM_EMAIL,
                    settings.NOTIFICATION_EMAILS,
                )

            return redirect(reverse('thanks'))
    return render(request, 'contribmap/wifi-form.html', {
        'form': form,
    })


def thanks(request):
    return render(request, 'contribmap/thanks.html')


class JSONContribView(View):
    def get(self, request):
        return JsonResponse({
            "id": self.ID,
            "license": self.LICENSE,
            "features": self.get_features(),
        })

    PLACE_PROPERTIES = [
        'floor', 'angles', 'orientations', 'roof', 'floor', 'floor_total']


class PublicJSON(JSONContribView):
    ID = 'public'
    LICENSE = {
        "type": "ODC-BY-1.0",
        "url": "http:\/\/opendatacommons.org\/licenses\/by\/1.0\/"
    }

    def get_features(self):
        contribs = Contrib.objects.all()

        data = []
        for i in contribs:
            if not i.is_public():
                continue

            data.append({
                "id": i.pk,
                "type": "Feature",
                "geometry": {
                    "coordinates": [
                        i.latitude,
                        i.longitude,
                    ],
                    "type": "Point",
                },
                "properties": {
                    "contrib_type": i.contrib_type,
                    "name": i.get_public_field('name'),
                    "place": {
                        k: i.get_public_field(k) for k in self.PLACE_PROPERTIES
                    },
                    "comment": i.get_public_field('comment'),
                }
            })
        return data


class PrivateJSON(JSONContribView):
    ID = 'private'
    LICENSE = {
        "type": "Copyright",
    }

    def dispatch(self, request, *args, **kwargs):
        if hasattr(request, 'user') and request.user.is_staff:
            return super().dispatch(request, *args, **kwargs)
        else:
            return HttpResponseForbidden('Need staff access')

    def get_features(self):
        contribs = Contrib.objects.all()

        data = []
        for i in contribs:
            if not i.is_public():
                continue

            data.append({
                "id": i.pk,
                "type": "Feature",
                "geometry": {
                    "coordinates": [
                        i.latitude,
                        i.longitude,
                    ],
                    "type": "Point",
                },
                "properties": {
                    "contrib_type": i.contrib_type,
                    "name": i.name,
                    "place": {
                        k: getattr(i, k) for k in self.PLACE_PROPERTIES
                    },
                    "comment": i.comment,
                    "phone": i.phone,
                    "email": i.email
                }
            })
        return data