import logging
import sys
reload(sys)
sys.setdefaultencoding('utf8')

from django import forms
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext_lazy as _, ugettext
from tagging.forms import TagField
from tagging.models import TaggedItem, Tag

from filebrowser.fields import FileBrowseWidget
from mbed.comlibs.decorators import check_for_spam
from mbed.forms import AutoCompleteTagInput
from wakawaka.models import Revision, WikiPage, Wiki


class WikiPageForm(forms.Form):
    editingrevision = forms.CharField(label="rev", widget=forms.HiddenInput, required=False)
    name = forms.CharField(label=_('Page name'), widget=forms.TextInput, required=False)
    content = forms.CharField(label=_('Page content'), widget=forms.Textarea(attrs={'rows': 20, 'style': 'width: 100%;'}))
    tags = TagField(label=_('Page tags'), widget=AutoCompleteTagInput('forum', 'Topic'), required=False)
    message = forms.CharField(label=_('Change message'), widget=forms.TextInput, required=False)
    hidelog = forms.BooleanField(required=False)

    def __init__(self, data, request, *args, **kwargs):
        self.page = None
        if 'page' in kwargs.keys():
            self.page = kwargs.pop('page')

        self.wiki = None
        if 'wiki' in kwargs.keys():
            self.wiki = kwargs.pop('wiki')

        self.request = request
        self.mollom_info = {
            "mollom_title_field": "name",
            "mollom_body_field": "content",
            "logging_code": "MOLLOM_WIKI_PAGE",
            "resource_type": "wiki page"
        }

        super(WikiPageForm, self).__init__(data, *args, **kwargs)

    def clean_content(self):
        content = self.cleaned_data['content']
        if not self.data.get('editingrevision'):
            return content
        else:
            try:
                rev = Revision.objects.get(pk=int(self.cleaned_data['editingrevision']))
                logging.debug("Editing revision %s"%rev)
            except:
                return content

            if not rev == rev.page.current:
                logging.debug("Edit conflict!")
                raise forms.ValidationError("Edit conflict - Someone else has saved this page while you were editing it. Please re-edit the page and reenter your changes.")

            logging.debug("No edit conflict")
            return content

    def clean_name(self):
        from mbed.comlibs.util import slugify
        newname = slugify(self.cleaned_data['name'], unique=False)

        if self.page:
            if newname != self.page.slug:
               if len(WikiPage.objects.filter(wiki=self.page.wiki, slug=newname)):
                   raise forms.ValidationError("Another page already exists at this URL")
        else:
            if self.wiki:
               if len(WikiPage.objects.filter(wiki=self.wiki, slug=newname)):
                    raise forms.ValidationError("Another page already exists at this URL")

        return self.cleaned_data['name']

    @check_for_spam
    def clean(self):
        return self.cleaned_data

    def save(self, request, page, *args, **kwargs):
        if len(self.cleaned_data['name']):
            if self.cleaned_data['name'] != page.slug:
                if request.user.is_staff:
                    oldslug = page.slug
                    from mbed.comlibs.util import slugify
                    newname = slugify(self.cleaned_data['name'], unique=False)
                    page.slug = newname
                    self.cleaned_data['message'] = 'Renamed from %s to %s. ' % (oldslug, page.slug) + self.cleaned_data['message']
        page.hidelog = self.cleaned_data['hidelog']
        Revision.objects.create(
            page=page,
            user=request.user,
            user_ip=request.META['REMOTE_ADDR'],
            content=self.cleaned_data['content'],
            message=self.cleaned_data['message']
        )
        # assert False
        page.user = request.user
        page.save()
        Tag.objects.update_tags(page, self.cleaned_data['tags'])


class CloseCommentForm(forms.ModelForm):
    allow_comments = forms.BooleanField(label='Close comemnts for this question?', required=False)

    class Meta:
        model = WikiPage
        fields = ('allow_comments',)

    def __init__(self, *args, **kwargs):
        super(CloseCommentForm, self).__init__(*args, **kwargs)


class DeleteWikiPageForm(forms.Form):
    delete = forms.ChoiceField(choices=())

    def __init__(self, request, *args, **kwargs):
        '''
        Override the __init__ to display only delete choices the user has
        permission for.
        '''
        self.base_fields['delete'].choices = []
        if request.user.has_perm('wakawaka.delete_revision'):
            self.base_fields['delete'].choices.append(('rev', 'Delete this revision'),)

        if request.user.has_perm('wakawaka.delete_revision') and \
           request.user.has_perm('wakawaka.delete_wikipage'):
            self.base_fields['delete'].choices.append(('page', 'Delete the page with all revisions'),)

        super(DeleteWikiPageForm, self).__init__(*args, **kwargs)

    def _delete_page(self, page):
        page.delete()

    def _delete_revision(self, rev):
        rev.delete()

    def delete_wiki(self, request, page, rev):
        """
        Deletes the page with all revisions or the revision, based on the
        users choice.

        Returns a HttpResponseRedirect.
        """
        # Delete the page
        if self.cleaned_data.get('delete') == 'page' and \
           request.user.has_perm('wakawaka.delete_revision') and \
           request.user.has_perm('wakawaka.delete_wikipage'):
            self._delete_page(page)
            return HttpResponseRedirect(reverse('wakawaka_index'))

        # Revision handling
        if self.cleaned_data.get('delete') == 'rev':
            revision_length = len(page.revisions.all())

            # Delete the revision if there are more than 1 and the user has permission
            if revision_length > 1 and request.user.has_perm('wakawaka.delete_revision'):
                self._delete_revision(rev)
                return HttpResponseRedirect(reverse('wakawaka_page', kwargs={'slug': page.slug}))

            # Do not allow deleting the revision, if it's the only one and the user
            # has no permisson to delete the page.
            if revision_length <= 1 and \
               not request.user.has_perm('wakawaka.delete_wikipage'):
                return HttpResponseRedirect(reverse('wakawaka_page', kwargs={'slug': page.slug}))

            # Delete the page and the revision if the user has both permissions
            if revision_length <= 1 and \
               request.user.has_perm('wakawaka.delete_revision') and \
               request.user.has_perm('wakawaka.delete_wikipage'):
                self._delete_page(page)
                return HttpResponseRedirect(reverse('wakawaka_index'))

        return None
