from django.shortcuts import render
from django.contrib.auth.decorators import permission_required, login_required
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import ensure_csrf_cookie
from django.http import HttpResponse, HttpResponseRedirect
from django.conf import settings
from django.utils.translation import ugettext as _
from django.forms.models import model_to_dict
from django.template.loader import render_to_string

import logging
import html

from webapp.utils import send_email

from members.views.utils import *
from members.tables import RequestTable
from members.forms import ApplicationForm
from members.views import error_view


@ensure_csrf_cookie
@require_http_methods(["GET"])
@login_required(login_url='/admin/login')
@permission_required('members.read_application', raise_exception=True)
def application_list(request, *args, **kwargs):
    """List member applications not yet processed."""
    applications = Request.objects.all()
    application_count = len(applications)
    table = RequestTable(applications,
                         request=request,
                         exclude=['id'],
                         attrs={'class': 'table table-bordered table-hover'})

    table.paginate(page=request.GET.get('page', 1), per_page=25)
    table_html = convert_table_to_html(table, request)
    context = {
        'table': table_html,
        'application_count': application_count,
        'notification': request.GET.get('notification', None)
    }
    return render(request, 'application_list.html', context)


@ensure_csrf_cookie
@require_http_methods(["GET"])
@login_required(login_url='/admin/login')
@permission_required('members.change_request', raise_exception=True)
def application_edit(request, *args, **kwargs):
    """Edit member request information."""
    i = kwargs.pop('index', None)
    if i is None:
        return error_view(request, _('No application id specified'))
    else:
        application = Request.objects.get(id=i)
        form = ApplicationForm(instance=application)
        return render(
            request,
            'application_edit.html',
            {'application_id': i, 'form': form})


@ensure_csrf_cookie
@require_http_methods(["POST"])
@login_required(login_url='/admin/login')
@permission_required('members.add_member', raise_exception=True)
def application_accept(request, *args, **kwargs):
    """Accept application."""
    id = request.POST.get('id', None)
    if id is not None:
        application = Request.objects.get(id=id)
    else:
        return error_view(request, _("Application missing 'id' field."))

    form = ApplicationForm(request.POST, instance=application)
    if form.is_valid():
        try:
            application = form.save()

            if Member.objects.filter(email=application.email).exists():
                return error_view(request, _(
                    'Email {} is already in use by a member. Application cannot be accepted.'
                ).format(application.email))

            member = application.to_member()
            member.save()
            application.delete()

            logging.info(
                "Accepted application in member "
                "register with the following info: {}"
                .format(form))
            notification = "{} {}.".format(_("Successfully accepted application"),
                                           str(application))

            subject = _('Jäsenhakemuksesi Sähköinsinöörikiltaan on hyväksytty!')

            message = render_to_string(
                'members:email_application_accept.html', {
                    'first_name': application.first_name
                }
            )
            send_email(member.email, subject, message)

            return HttpResponseRedirect(
                '/members/list?notification={}'.format(html.escape(notification)))
        except Exception as ex:
            logging.exception('Exception while accepting application')
            return error_view(request, str(ex))
    else:
        logging.info(form)
        return error_view(request, form.errors)


@ensure_csrf_cookie
@require_http_methods(["POST"])
@login_required(login_url='/admin/login')
@permission_required('members.delete_request', raise_exception=True)
def application_delete(request, *args, **kwargs):
    """Delete member application."""
    try:
        id = request.POST['id']
    except KeyError:
        return error_view(request, _('No application id specified'))

    try:
        application = Request.objects.get(id=id)
        notification = "{} {}.".format(_("Successfully deleted application"),
                                       str(application))
        application.delete()
        logging.info(
            "Delete application in member register with the following id: {}"
            .format(id))
        return HttpResponseRedirect(
            '/members/applications?notification={}'
            .format(html.escape(notification)))
    except:
        return error_view(request, _('Could not delete application object'))


@ensure_csrf_cookie
@require_http_methods(["GET"])
@login_required(login_url='/admin/login')
@permission_required('members.delete_request', raise_exception=True)
def application_delete_confirm(request, *args, **kwargs):
    """Confirm application deletion."""
    i = kwargs.pop('index', None)
    if i is None:
        return error_view(request, _('No application id specified'))
    else:
        application = Request.objects.get(id=i)
        form = ApplicationForm(instance=application)
        return render(request,
                      'application_delete_confirm.html',
                      {'application_id': i, 'form': form})


@ensure_csrf_cookie
def application_form(request, *args, **kwargs):
    """Render member application form."""
    form = ApplicationForm()
    return render(request, 'application_index.html', {'form': form})


@ensure_csrf_cookie
@require_http_methods(["POST"])
def application_submit(request, *args, **kwargs):
    """Submit member application"""
    form = ApplicationForm(request.POST)
    if form.is_valid():
        form.save()
        try:
            application = form.instance
            email = form.cleaned_data.get('email', '')

            subject = _('Jäsenhakemuksesi Sähköinsinöörikiltaan on lähetetty onnistuneesti!')

            message = render_to_string(
                'members:email_application_submit.html', {
                    'application': application,
                    'ayy': _('Kyllä') if application.AYY else _('Ei'),
                    'jas': _('Kyllä') if application.jas else _('Ei')
                }
            )
            send_email(email, subject, message)
        finally:
            return render(request, 'application_success.html', {})
    else:
        return error_view(request, form.errors)
