import json

from django import forms
from django.http import HttpResponseBadRequest
from django.shortcuts import redirect, get_object_or_404
from django.views.decorators.http import require_POST

from intranet.search.core import context
from intranet.search.core.models import ExternalWizardRule
from intranet.search.core.storages import ExternalWizardRuleStorage
from intranet.search.admin.template import render


settings_context = context.SettingsContext()
searches = settings_context.searches_names()


class DeleteRuleForm(forms.Form):
    id = forms.IntegerField()


class AddRuleForm(forms.Form):
    id = forms.IntegerField(required=False, widget=forms.HiddenInput)
    name = forms.CharField()
    search = forms.ChoiceField(choices=searches.items())
    index = forms.CharField(required=False)
    rule = forms.RegexField(widget=forms.Textarea, regex=r'^(-?[a-zA-Z0-9\/]+,?)+$')
    params = forms.CharField(required=False)

    def clean(self):
        id = self.cleaned_data.get('id')
        name = self.cleaned_data.get('name')
        search = self.cleaned_data.get('search')
        index = self.cleaned_data.get('index')

        w = ExternalWizardRule.objects.filter(search=search, index=index, name=name)

        if id:
            w = w.exclude(id=id)

        if w.exists():
            self._errors['name'] = ['Not unique']

        return self.cleaned_data


def add_rule(request):
    f = AddRuleForm(request.POST or None)
    if f.is_valid():
        data = {
            'name': f.cleaned_data.get('name'),
            'rule': f.cleaned_data.get('rule'),
            'params': f.cleaned_data.get('params').strip(),
        }

        storage = ExternalWizardRuleStorage()
        id = f.cleaned_data.get('id')

        if id is not None:
            data.update({'id': id})
            storage.update(**data)
        else:
            data.update({'search': f.cleaned_data.get('search'),
                         'index': f.cleaned_data.get('index')})
            storage.create(**data)
        return redirect(rules)
    else:
        return HttpResponseBadRequest(json.dumps({'form': f.errors}),
                                      content_type='application/json')


def delete_rule(request):
    f = DeleteRuleForm(request.POST or None)
    if f.is_valid():
        id = f.cleaned_data['id']
        rule = get_object_or_404(ExternalWizardRule, id=id)
        rule.delete()
        return redirect(rules)
    else:
        return HttpResponseBadRequest(json.dumps({'form': f.errors}),
                                      content_type='application/json')


@require_POST
def manage_rule(request):
    action = request.POST.get('action')
    if action == 'Save':
        return add_rule(request)
    elif action == 'Delete':
        return delete_rule(request)

    return HttpResponseBadRequest(json.dumps({'action': 'Got %s, expected Save or Delete' % action}),
                                  content_type='application/json')


def rules(request):
    storage = ExternalWizardRuleStorage()
    rules = storage.get_all()
    f = AddRuleForm()

    return render(request, 'isearch/external_wizard_rules/external_wizard_rules.html',
                  {'rules': rules, 'f': f, 'searches': searches},
                  content_type='text/html')
