# Path: boardinghouse/contrib/invite/forms.py
# class AcceptForm(forms.ModelForm):
#     """
#     A form that can be used to accept an invitation to a schema.
#     """
# 
#     class Meta:
#         model = Invitation
#         fields = ()
# 
#     def __init__(self, *args, **kwargs):
#         self.user = kwargs.pop('user')
#         super(AcceptForm, self).__init__(*args, **kwargs)
# 
#     def clean(self):
#         if self.instance.expired:
#             raise forms.ValidationError(EXPIRED)
#         if self.instance.redeemed:
#             raise forms.ValidationError(ACCEPTED)
#         if self.instance.declined:
#             raise forms.ValidationError(DECLINED)
#         return self.cleaned_data
# 
#     def save(self, *args, **kwargs):
#         self.user.schemata.add(self.instance.schema)
#         self.instance.accepted_at = datetime.datetime.utcnow()
#         self.instance.accepted_by = self.user
#         return super(AcceptForm, self).save(*args, **kwargs)
# 
# class DeclineForm(forms.ModelForm):
# 
#     class Meta:
#         model = Invitation
#         fields = ()
# 
#     def clean(self):
#         # In this case, we just want to tell the user this object
#         # has been accepted, since they attempted to decline it.
#         if self.instance.accepted:
#             raise forms.ValidationError(ACCEPTED)
#         return {}
# 
#     def save(self, *args, **kwargs):
#         self.instance.declined_at = datetime.datetime.utcnow()
#         return super(DeclineForm, self).save(*args, **kwargs)
# 
# class InvitePersonForm(forms.ModelForm):
#     """
#     A form that can be used to create a new invitation for a person
#     to a schema.
# 
#     This will only allow you to invite someone to the current schema.
# 
#     It will automatically generate a redemption code, that will be a
#     part of the url the user needs to click on in order to accept or
#     deny the invitation.
# 
#     The message will be emailed.
#     """
#     class Meta:
#         model = Invitation
#         fields = ('email', 'message',)
# 
#     def __init__(self, *args, **kwargs):
#         self.user = kwargs.pop('user')
#         super(InvitePersonForm, self).__init__(*args, **kwargs)
# 
#     def save(self, *args, **kwargs):
#         self.instance.schema = get_active_schema()
#         self.instance.redemption_code = uuid.uuid4()
#         self.instance.sender = self.user
#         # TODO: email the user.
#         return super(InvitePersonForm, self).save(*args, **kwargs)
# 
# Path: boardinghouse/contrib/invite/models.py
# class Invitation(SharedSchemaModel):
#     email = models.EmailField(verbose_name=_('Email address'))
#     sender = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='sent_invitations')
#     message = models.TextField()
#     schema = models.ForeignKey(settings.BOARDINGHOUSE_SCHEMA_MODEL, related_name='invitations')
#     redemption_code = models.UUIDField(null=True, blank=True)
# 
#     created_at = models.DateTimeField(auto_now_add=True)
#     # Can we ensure that at most one of these two is not null?
#     accepted_at = models.DateTimeField(null=True, blank=True)
#     declined_at = models.DateTimeField(null=True, blank=True)
#     accepted_by = models.ForeignKey(settings.AUTH_USER_MODEL,
#                                     related_name='accepted_invitations',
#                                     null=True, blank=True)
# 
#     objects = InvitationQuerySet.as_manager()
# 
#     class Meta:
#         ordering = ('created_at',)
#         app_label = 'invite'
# 
#     def __str__(self):
#         return u'[{0!s}] Invitation to {1!s} from {2!s} to join {3!s}'.format(
#             six.text_type(self.status), self.email, self.sender, self.schema.name
#         )
# 
#     def save(self, *args, **kwargs):
#         if not self.redeemed and not self.redemption_code:
#             self.redemption_code = uuid.uuid4()
#         return super(Invitation, self).save(*args, **kwargs)
# 
#     @property
#     def redeemed(self):
#         return self.accepted_at or self.declined_at
# 
#     @property
#     def declined(self):
#         return self.declined_at is not None
# 
#     @property
#     def accepted(self):
#         return self.accepted_at is not None
# 
#     @property
#     def expired(self):
#         return self.created_at < now() - INVITATION_EXPIRY
# 
#     @property
#     def redeemable(self):
#         return not (self.expired or self.redeemed)
# 
#     @property
#     def status(self):
#         if self.declined:
#             return _('DECLINED')
#         if self.accepted:
#             return _('ACCEPTED')
#         if self.expired:
#             return _('EXPIRED')
#         return _('PENDING')
# 
#     @property
#     def expires_at(self):
#         return self.created_at + INVITATION_EXPIRY


from django.views import generic
from .forms import AcceptForm, DeclineForm, InvitePersonForm
from .models import Invitation

accept_invitation = AcceptInvitation.as_view()


class ConfirmInvitation(InvitationMixin, UserMixin, generic.UpdateView):
    form_class = AcceptForm
    success_url = '/admin/invite/invitation/'

confirm_invitation = ConfirmInvitation.as_view()


class LoginAndAcceptView(object):
    pass


class RegisterAndAcceptView(object):
    pass


class DeclineInvitation(InvitationMixin, generic.UpdateView):
    form_class = DeclineForm
    success_url = '/admin/invite/invitation/'

decline_invitation = DeclineInvitation.as_view()


class PendingReceivedInvitations(generic.ListView):
    template_name = 'invite/list.html'

    def get_queryset(self):

# Path: boardinghouse/contrib/invite/forms.py
# class AcceptForm(forms.ModelForm):
#     """
#     A form that can be used to accept an invitation to a schema.
#     """
# 
#     class Meta:
#         model = Invitation
#         fields = ()
# 
#     def __init__(self, *args, **kwargs):
#         self.user = kwargs.pop('user')
#         super(AcceptForm, self).__init__(*args, **kwargs)
# 
#     def clean(self):
#         if self.instance.expired:
#             raise forms.ValidationError(EXPIRED)
#         if self.instance.redeemed:
#             raise forms.ValidationError(ACCEPTED)
#         if self.instance.declined:
#             raise forms.ValidationError(DECLINED)
#         return self.cleaned_data
# 
#     def save(self, *args, **kwargs):
#         self.user.schemata.add(self.instance.schema)
#         self.instance.accepted_at = datetime.datetime.utcnow()
#         self.instance.accepted_by = self.user
#         return super(AcceptForm, self).save(*args, **kwargs)
# 
# class DeclineForm(forms.ModelForm):
# 
#     class Meta:
#         model = Invitation
#         fields = ()
# 
#     def clean(self):
#         # In this case, we just want to tell the user this object
#         # has been accepted, since they attempted to decline it.
#         if self.instance.accepted:
#             raise forms.ValidationError(ACCEPTED)
#         return {}
# 
#     def save(self, *args, **kwargs):
#         self.instance.declined_at = datetime.datetime.utcnow()
#         return super(DeclineForm, self).save(*args, **kwargs)
# 
# class InvitePersonForm(forms.ModelForm):
#     """
#     A form that can be used to create a new invitation for a person
#     to a schema.
# 
#     This will only allow you to invite someone to the current schema.
# 
#     It will automatically generate a redemption code, that will be a
#     part of the url the user needs to click on in order to accept or
#     deny the invitation.
# 
#     The message will be emailed.
#     """
#     class Meta:
#         model = Invitation
#         fields = ('email', 'message',)
# 
#     def __init__(self, *args, **kwargs):
#         self.user = kwargs.pop('user')
#         super(InvitePersonForm, self).__init__(*args, **kwargs)
# 
#     def save(self, *args, **kwargs):
#         self.instance.schema = get_active_schema()
#         self.instance.redemption_code = uuid.uuid4()
#         self.instance.sender = self.user
#         # TODO: email the user.
#         return super(InvitePersonForm, self).save(*args, **kwargs)
# 
# Path: boardinghouse/contrib/invite/models.py
# class Invitation(SharedSchemaModel):
#     email = models.EmailField(verbose_name=_('Email address'))
#     sender = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='sent_invitations')
#     message = models.TextField()
#     schema = models.ForeignKey(settings.BOARDINGHOUSE_SCHEMA_MODEL, related_name='invitations')
#     redemption_code = models.UUIDField(null=True, blank=True)
# 
#     created_at = models.DateTimeField(auto_now_add=True)
#     # Can we ensure that at most one of these two is not null?
#     accepted_at = models.DateTimeField(null=True, blank=True)
#     declined_at = models.DateTimeField(null=True, blank=True)
#     accepted_by = models.ForeignKey(settings.AUTH_USER_MODEL,
#                                     related_name='accepted_invitations',
#                                     null=True, blank=True)
# 
#     objects = InvitationQuerySet.as_manager()
# 
#     class Meta:
#         ordering = ('created_at',)
#         app_label = 'invite'
# 
#     def __str__(self):
#         return u'[{0!s}] Invitation to {1!s} from {2!s} to join {3!s}'.format(
#             six.text_type(self.status), self.email, self.sender, self.schema.name
#         )
# 
#     def save(self, *args, **kwargs):
#         if not self.redeemed and not self.redemption_code:
#             self.redemption_code = uuid.uuid4()
#         return super(Invitation, self).save(*args, **kwargs)
# 
#     @property
#     def redeemed(self):
#         return self.accepted_at or self.declined_at
# 
#     @property
#     def declined(self):
#         return self.declined_at is not None
# 
#     @property
#     def accepted(self):
#         return self.accepted_at is not None
# 
#     @property
#     def expired(self):
#         return self.created_at < now() - INVITATION_EXPIRY
# 
#     @property
#     def redeemable(self):
#         return not (self.expired or self.redeemed)
# 
#     @property
#     def status(self):
#         if self.declined:
#             return _('DECLINED')
#         if self.accepted:
#             return _('ACCEPTED')
#         if self.expired:
#             return _('EXPIRED')
#         return _('PENDING')
# 
#     @property
#     def expires_at(self):
#         return self.created_at + INVITATION_EXPIRY


# Path: boardinghouse/contrib/invite/views.py
from django.views import generic
from .forms import AcceptForm, DeclineForm, InvitePersonForm
from .models import Invitation


accept_invitation = AcceptInvitation.as_view()


class ConfirmInvitation(InvitationMixin, UserMixin, generic.UpdateView):
    form_class = AcceptForm
    success_url = '/admin/invite/invitation/'

confirm_invitation = ConfirmInvitation.as_view()


class LoginAndAcceptView(object):
    pass


class RegisterAndAcceptView(object):
    pass


class DeclineInvitation(InvitationMixin, generic.UpdateView):
    form_class = DeclineForm
    success_url = '/admin/invite/invitation/'

decline_invitation = DeclineInvitation.as_view()


class PendingReceivedInvitations(generic.ListView):
    template_name = 'invite/list.html'

    def get_queryset(self):

        return Invitation.objects.for_email(self.request.user.email).pending()