class Organisation(AuditModel):
    organisation_type = models.PositiveSmallIntegerField(
        choices=OrganisationType.CHOICES, verbose_name="organisation type")
    name = models.CharField(max_length=300, unique=True)
    description = models.TextField()
    full_address = models.TextField(blank=True, null=True)
    location = models.ForeignKey(Location)
    pincode = models.CharField(max_length=6, blank=True, null=True)
    address_map_url = models.URLField(blank=True, null=True)
    organisation_role = models.CharField(
        max_length=300, verbose_name="Your position in organisation")
    user = models.ManyToManyField(User, related_name='organisation_users')
    active = models.BooleanField(default=True)
    students = models.ManyToManyField(
        User,
        related_name='organisation_students',
        blank=True)

    @classmethod
    def list_user_organisations(cls, user):
        return cls.objects.filter(user=user, active=True)

    @property
    def get_organisation_user_list(self):
        return self.user.all()

    def toggle_active(self, logged_user, **kwargs):
        """
        Helper method to toggle active flag for the model.
        """

        action_map = {'active': True, 'deactive': False}
        action = kwargs.get('action')
        # check if user is only poc for the organisation
        self.user.remove(logged_user)
        if not self.user.count():
            # if there are no more poc for this organisation disable it
            # else Organisation will be active
            self.active = action_map.get(action)
            self.save()

        return {
            'status': True,
            'msg': 'Organisation disabled'}

    class Meta:
        db_table = 'organisations'

    def __str__(self):
        return '{} , {}'.format(self.name, self.location) class Profile(models.Model):
    user = models.OneToOneField(User, primary_key=True, related_name='profile')
    mobile = models.CharField(max_length=10, blank=False, null=True)
    occupation = models.CharField(
        null=True, blank=True, max_length=300, verbose_name=u"Occupation")
    work_location = models.CharField(
        null=True, blank=True, max_length=500,
        verbose_name=u"Organisaiton/Company")
    work_experience = models.FloatField(
        null=True, blank=True, verbose_name=u"Work Experience(If Any)")
    no_workshop = models.IntegerField(
        verbose_name=u"Workshop conducted(apart from pythonexpress)",
        default=0)
    is_mobile_visible = models.BooleanField(default=False)
    is_email_visible = models.BooleanField(default=False)

    enable_notifications = models.BooleanField(
        default=True,
        verbose_name=u"Email Notification")

    usertype = models.ManyToManyField(UserType)

    interested_sections = models.ManyToManyField(WorkshopSections)
    interested_level = models.PositiveSmallIntegerField(
        choices=WorkshopLevel.CHOICES,
        verbose_name="Interested Workshop Level",
        null=True, blank=True)
    interested_locations = models.ManyToManyField(
        Location)
    interested_states = models.ManyToManyField(
        State,
        verbose_name=u"Interested State *")
    location = models.ForeignKey(
        Location, related_name="user_location", null=True)

    github = models.URLField(null=True, blank=True)
    facebook = models.URLField(null=True, blank=True)
    googleplus = models.URLField(null=True, blank=True)
    linkedin = models.URLField(null=True, blank=True)
    twitter = models.URLField(null=True, blank=True)
    slideshare = models.URLField(null=True, blank=True)
    picture = models.ImageField(
        upload_to='images/', default='images/newuser.png')

    class Meta:
        db_table = 'user_profile'
        verbose_name = 'UserProfile'
        verbose_name_plural = 'UserProfiles'

    def __str__(self):
        return '{} {}'.format(self.user, self.user.username)

    @property
    def is_profile_filled(self):
        if ('tutor' in [x.slug for x in self.usertype.all()]):
            if (self.location and
                    self.interested_level and
                    self.interested_states and
                    self.interested_sections):
                return True
            return False
        if self.location:
            return True
        return False

    @property
    def get_workshop_details(self):
        return Workshop.objects.filter(is_active=True).filter(
            presenter=self.user).order_by('-id')

    @property
    def can_create_organisation(self):
        org_count = Organisation.objects.filter(
            created_by=self.user).count()
        return False if org_count > 5 else True

    @property
    def get_workshop_completed_count(self):
        return len([x for x in
                    self.get_workshop_details if (
                        x.status in [
                            WorkshopStatus.COMPLETED,
                            WorkshopStatus.FEEDBACK_PENDING])])

    @property
    def get_workshop_upcoming_count(self):
        return len([x for x in
                    self.get_workshop_details if (
                        x.status == WorkshopStatus.ACCEPTED)])

    @property
    def get_total_no_of_participants(self):
        return sum([x.no_of_participants for x in
                    self.get_workshop_details if (
                        x.status == WorkshopStatus.COMPLETED)])

    @property
    def get_avg_workshop_rating(self):
        workshops = self.get_workshop_details
        voting = WorkshopVoting.objects.filter(
            workshop_feedback__workshop__id__in=[
                w.id for w in workshops]).filter(
            workshop_feedback__feedback_type=2).aggregate(
            Avg('workshop_rating__feedback_type'))
        return voting['workshop_rating__feedback_type__avg']

    @staticmethod
    def get_user_with_type(user_type=None):
        """
        Would return user with user type list in argument.
        Eg Collage POC, admin etc
        """
        return User.objects.filter(
            profile__usertype__display_name__in=user_type
        )

    @property
    def get_user_type(self):
        return [x.slug for x in self.usertype.all()]

    @property
    def get_interested_locations(self):
        return [x.name for x in self.interested_locations.all()]

    @property
    def get_graph_data(self):
        sections = WorkshopSections.objects.all()
        workshops = Workshop.objects.filter(
            presenter=self.user,
            status=WorkshopStatus.COMPLETED,
            is_active=True
        )

        if workshops:
            max_workshop_date = workshops.aggregate(
                models.Max('expected_date'))['expected_date__max']
            min_workshop_date = workshops.aggregate(
                models.Min('expected_date'))['expected_date__min']
            data = []
            if max_workshop_date and min_workshop_date:
                dates = [dt for dt in rrule(
                    MONTHLY,
                    dtstart=min_workshop_date,
                    until=max_workshop_date)]
                if dates:
                    for section in sections:
                        values = []
                        for d in dates:
                            y = workshops.filter(
                                expected_date__year=d.year,
                                expected_date__month=d.month,
                                workshop_section=section.pk).count()
                            values.append(
                                {'x': "{}-{}".format(d.month, d.year), 'y': y})
                        data.append({'key': section.name, 'values': values})
                    # print(data)
                    return json.dumps(data)
                else:
                    return []
            else:
                return []
        else:
            return []

    @property
    def get_organisation_name(self):
        return self.user.organisation_students.all()

    @property
    def get_student_workshop_attended_count(self):
        return self.user.workshop_attended.count()

    @property
    def get_student_workshop_attended(self):
        return self.user.workshop_attended.all()

    @classmethod
    def is_presenter(cls, user):
        return user.profile.usertype.filter(slug__iexact="tutor").exists()

    @classmethod
    def is_organiser(cls, user):
        return user.profile.usertype.filter(slug__icontains="poc").exists()

    @classmethod
    def is_regional_lead(cls, user):
        return user.profile.usertype.filter(slug__iexact="lead").exists()

    @classmethod
    def is_student(cls, user):
        return user.profile.usertype.filter(slug__iexact="student").exists()

    @classmethod
    def is_admin(cls, user):
        return user.profile.usertype.filter(slug__iexact="admin").exists()

    @classmethod
    def is_coordinator(cls, user):
        return user.profile.usertype.filter(
            slug__iexact="coordinator").exists()

    @classmethod
    def is_volunteer(cls, user):
        return user.profile.usertype.filter(slug__iexact="volunteer").exists() def verify_user_profile(f):
    '''
    This decorator check  whether the user are valid for certain views
    '''
    def wrap(request, *args, **kwargs):
        user_profile, created = Profile.objects.get_or_create(
            user__id=request.user.id)
        if not user_profile.is_profile_filled:
            return HttpResponseRedirect(
                '/profile/{}/edit'.format(request.user.username))
        return f(request, *args, **kwargs)
    return wrap class WorkshopStatus:
    _DRAFT = [1, "Draft"]
    _REQUESTED = [2, "Workshop Requested"]
    _ACCEPTED = [3, "Workshop Accepted "]
    _DECLINED = [4, "Workshop Declined"]
    _FEEDBACK_PENDING = [5, "FeedBack Pending"]
    _HOLD = [6, "Workshop On Hold"]
    _COMPLETED = [7, "Workshop Completed"]
    _UNABLE_TO_COMPLETE = [8, "Workshop unable to complete"] class WorkshopForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user')
        super(WorkshopForm, self).__init__(*args, **kwargs)
        self.fields['expected_date'] = forms.DateField(
            widget=CalendarWidget,
            input_formats=settings.ALLOWED_DATE_FORMAT)
        self.fields['requester'].queryset = self.get_organisations(user)
        self.fields[
            'workshop_section'].queryset = WorkshopSections.objects.filter(
            is_active=True)
        if not self.instance.id:
            self.fields['tutor_reimbursement_flag'].required = False
            self.fields[
                'tutor_reimbursement_flag'].widget = forms.HiddenInput()
            self.fields['comments'].required = False
            self.fields['comments'].widget = forms.HiddenInput()

    # def clean_location(self):
    #     if "requester" not in self.cleaned_data:
    #         return ""

    #     organisation = self.cleaned_data['requester']
    #     return organisation.location

    def get_organisations(self, user):
        if Profile.is_admin(user):
            return Organisation.objects.all()
        elif Profile.is_regional_lead(user):
            return Organisation.objects.filter(location=user.profile.location)
        else:
            return Organisation.list_user_organisations(user)

    def clean_expected_date(self):
        date = self.cleaned_data['expected_date']
        if not (date > datetime.date.today() + datetime.timedelta(days=7)):
            raise ValidationError(
                '''Workshop request has to future date and
                 atleast week ahead of today''')
        else:
            return date

    class Meta:
        model = Workshop
        exclude = (
            'presenter', 'created_at', 'modified_at',
            'number_of_volunteers', 'volunteer',
            'is_active', 'status',) class WorkshopEditForm(forms.ModelForm):
    requester = forms.CharField()

    def __init__(self, request, *args, **kwargs):
        super(WorkshopEditForm, self).__init__(*args, **kwargs)
        self.fields['expected_date'] = forms.DateField(
            widget=CalendarWidget,
            input_formats=settings.ALLOWED_DATE_FORMAT)
        self.fields['requester'].widget = forms.TextInput()
        self.fields['requester'].widget.attrs['readonly'] = True
        if RegionalLead.is_regional_lead(
                request.user, self.instance.requester.location):
            self.fields['presenter'].queryset = User.objects.filter(
                profile__usertype__slug="tutor"
            )
        else:
            del self.fields['presenter']

    def clean_requester(self):
        return self.instance.requester

    class Meta:
        model = Workshop
        exclude = (
            'created_at', 'modified_at',
            'number_of_volunteers', 'volunteer',
            'is_active', 'status') class WorkshopFeedbackForm(forms.Form):
    """
    Dynamically generates feedback form depending on questions available
    in model assigend to question_model.
    """

    question_model = WorkshopRatingValues

    def __init__(self, user, id, *args, **kwargs):
        super(WorkshopFeedbackForm, self).__init__(*args, **kwargs)
        w = Workshop.objects.get(id=id)
        if user in w.presenter.all():
            feedback_type = FeedbackType.PRESENTER
        elif user in w.requester.user.all():
            feedback_type = FeedbackType.ORGANISATION
        else:
            feedback_type = None
        questions = self.question_model.get_questions(feedback_type)

        for question in questions:
            key = "{}".format(question)
            self.fields[key] = forms.ChoiceField(
                choices=WorkshopRatings.CHOICES, required=True,
                widget=forms.RadioSelect())
            self.fields[key].label = question.name

        self.fields["comment"] = forms.CharField(widget=forms.Textarea)

    def save(self, user, workshop_id):
        data = {k: v for k, v in self.cleaned_data.items()}
        WorkshopFeedBack.save_feedback(user, workshop_id, **data) class WorkshopListForm(forms.Form):
    """
    Form to filter workshop list
    """
    state = forms.ModelMultipleChoiceField(
        label="State",
        required=False,
        queryset='')

    level = forms.MultipleChoiceField(
        label="Level",
        required=False,
        choices=WorkshopLevel.CHOICES)

    section = forms.ModelMultipleChoiceField(
        label="Section",
        required=False,
        queryset='')

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user')
        super(WorkshopListForm, self).__init__(*args, **kwargs)
        self.fields['state'].queryset = self.get_all_states(user)

        self.fields['section'].queryset = WorkshopSections.objects.all()

    def get_all_locations(self, user):
        if Profile.is_admin(user):
            return Location.objects.all()
        else:
            return user.profile.interested_locations.all()

    def get_all_states(self, user):
        if Profile.is_admin(user):
            return State.objects.all()
        else:
            return user.profile.interested_states.all() class WorkshopVolunteer(forms.Form):
    CHOICE_LIST = ((idx, idx) for idx in range(0, 6))
    number_of_volunteers = forms.ChoiceField(choices=CHOICE_LIST)
    tutor_reimbursement_flag = forms.ChoiceField(choices=YesNO.CHOICES)
    comments = forms.CharField(widget=forms.Textarea) class WorkshopEmailMixin(object):

    def send_mail_to_presenter(self, user, context):
        """
        Send email to presenter.
        @param user: Is user object
        @param context: Is dict of data required by email template.
        """

        # Send email to presenter
        return send_mail([user.email], context, self.email_dir)

    # def send_mail_to_group(self, context, exclude_emails=None):
    #     """
    #     Send email to org/group users.
    #     @param context: Is dict of data required by email template.
    #     @exclude_emails: Is list of email to be excluded from
    #     email update.
    #     """

    #     if exclude_emails is None:
    #         exclude_emails = []

    #     # Collage POC and admin email
    #     poc_admin_user = Profile.get_user_with_type(
    #         user_type=['Collage POC', 'admin']
    #     ).values_list('email', flat=True)
    #     # Org user email
    #     org_user_emails = self.object.requester.user.filter(
    #         is_active=True
    #     ).values_list('email', flat=True)
    #     # all presenter if any
    #     all_presenter_email = self.object.presenter.values_list(
    #         'email', flat=True
    #     )
    #     # List of tutor who have shown interest in that location
    #     region_interested_member = Profile.objects.filter(
    #         interested_locations=self.object.requester.location,
    #         usertype__slug='tutor'
    #     ).values_list('user__email', flat=True)

    #     all_email = []
    #     all_email.extend(org_user_emails)
    #     all_email.extend(all_presenter_email)
    #     all_email.extend(poc_admin_user)
    #     all_email.extend(region_interested_member)
    #     all_email = set(all_email)
    #     all_email = list(all_email.difference(exclude_emails))
    #     send_mail(all_email, context, self.email_dir) class WorkshopAccessMixin(object):

    def dispatch(self, request, *args, **kwargs):
        user = request.user
        pk = self.kwargs.get(self.pk_url_kwarg, None)
        workshop = Workshop.objects.get(id=pk)
        is_admin = Profile.is_admin(user)
        is_lead = (Profile.is_regional_lead(user) and
                   RegionalLead.is_regional_lead(user, workshop.location))
        is_organiser = (Profile.is_organiser(user) and
                        user in workshop.requester.user.all())

        if not (is_admin or is_lead or is_organiser):
            return HttpResponseForbidden("Not sufficent permission")
        return super(WorkshopAccessMixin, self).dispatch(
            request, *args, **kwargs) def send_mail_to_group(context, workshop, exclude_emails=None):
    """
    Send email to org/group users.
    @param context: Is dict of data required by email template.
    @exclude_emails: Is list of email to be excluded from
    email update.
    """
    if exclude_emails is None:
        exclude_emails = []

    # Collage POC and admin email
    poc_admin_user = Profile.get_user_with_type(
        user_type=['admin']
    ).values_list('email', flat=True)
    # Org user email
    org_user_emails = workshop.requester.user.filter(
        is_active=True
    ).values_list('email', flat=True)
    # all presenter if any
    all_presenter_email = workshop.presenter.values_list(
        'email', flat=True
    )
    # List of tutor who have shown interest in that location
    region_interested_member = Profile.objects.filter(
        interested_states=workshop.requester.location.state,
        usertype__slug='tutor',
        enable_notifications=True
    ).values_list('user__email', flat=True)

    all_email = []
    all_email.extend(org_user_emails)
    all_email.extend(all_presenter_email)
    all_email.extend(poc_admin_user)
    all_email.extend(region_interested_member)
    all_email = set(all_email)
    all_email = list(all_email.difference(exclude_emails))

    subject = '[PythonExpress] Workshop request status.'
    email_body = loader.get_template(
        'email_messages/workshop/create_workshop/message.html').render(
        context)
    text_body = loader.get_template(
        'email_messages/workshop/create_workshop/message.txt').render(
        context)
    for email_id in all_email:
        send_email_to_id(
            subject,
            body=email_body,
            users_list=email_id,
            text_body=text_body) class Workshop(TimeAuditModel):
    no_of_participants = models.PositiveIntegerField(choices=(
        (10, 10),
        (20, 20),
        (30, 30),
        (40, 40),
        (50, 50),
        (60, 60),))
    expected_date = models.DateField()
    description = models.TextField()
    requester = models.ForeignKey(
        Organisation, related_name='workshop_requester')
    presenter = models.ManyToManyField(User, related_name='workshop_presenter')
    # location = models.ForeignKey(Location, related_name='workshop_location')
    workshop_level = models.PositiveSmallIntegerField(
        choices=WorkshopLevel.CHOICES, verbose_name="Workshop Level")
    workshop_section = models.ForeignKey(WorkshopSections)
    number_of_volunteers = models.PositiveSmallIntegerField(
        default=0, null=True, blank=True)
    volunteer = models.ManyToManyField(User, related_name='workshop_volunteer')
    is_active = models.BooleanField(default=True)
    status = models.PositiveSmallIntegerField(
        choices=WorkshopStatus.CHOICES, verbose_name="Current Status",
        default=WorkshopStatus.REQUESTED)
    travel_reimbursement = models.PositiveSmallIntegerField(
        choices=YesNO.CHOICES,
        verbose_name="Travel Reimbursement Support",
        default=YesNO.NO)
    hotel_reimbursement = models.PositiveSmallIntegerField(
        choices=YesNO.CHOICES,
        verbose_name="Stay Reimbursement Support",
        default=YesNO.NO)
    budget = models.CharField(max_length=5, null=True)
    reimbursement_mode = models.TextField(null=True)
    tutor_reimbursement_flag = models.PositiveSmallIntegerField(
        choices=YesNO.CHOICES,
        verbose_name=" Do you need Travel/Stay reimbursement ?",
        default=YesNO.NO)
    comments = models.TextField()
    target_audience = models.PositiveSmallIntegerField(
        choices=WorkshopAudience.CHOICES, verbose_name="Audience",
        default=WorkshopAudience.BE_FINAL_YEAR)
    student_attended = models.ManyToManyField(
        User, related_name='workshop_attended')

    class Meta:
        db_table = 'workshops'

    def __str__(self):
        return '{}-{}'.format(self.requester, self.workshop_section)

    def save(self, force_insert=False, force_update=False, using=None):
        super(Workshop, self).save(force_insert, force_update, using)

    def is_presenter(self, user):
        return self.presenter.filter(pk=user.pk).exists()

    def is_organiser(self, user):
        return self.requester.user.filter(pk=user.pk).exists()

    def manage_action(self, user, **kwargs):
        actions = {
            'accept': ("opt-in", self.assign_me),
            'reject': ("opt-out", self.assign_me),
            'decline': (WorkshopStatus.REQUESTED, self.set_status),
            'publish': (WorkshopStatus.REQUESTED, self.set_status),
            'hold': (WorkshopStatus.HOLD, self.set_status),
            'assign': "",
            'opt-in-as-volunteer': '',
            'opt-out-as-volunteer': ''
        }
        if kwargs.get('action') not in actions:
            return {
                'status': False,
                'msg': 'Action not allowed'
            }

        action, func = actions.get(kwargs.get('action'))
        kwargs["action"] = action
        return func(user, **kwargs)

    def set_status(self, user, **kwargs):
        self.status = kwargs.get('action')
        presenter_list = self.presenter.all()
        for u in presenter_list:
            self.presenter.remove(u)
        if kwargs.get('action') == WorkshopStatus.DECLINED:
            self.is_active = False
        else:
            self.is_active = True
        self.save()
        return {
            'status': True,
            'msg': 'Workshop successfully updated.'}

    # @validate_action_param(WorkshopAction.ACTIVE)
    def toggle_active(self, user, **kwargs):
        """
        Helper method to toggle is_active for the model.
        """

        action_map = {'active': True, 'deactive': False}
        action = kwargs.get('action')
        self.is_active = action_map.get(action)
        self.save()
        return {
            'status': True,
            'msg': 'Workshop successfully updated.'}

    # @validate_action_param(WorkshopAction.ASSIGNME)
    # @validate_assignme_action
    def assign_me(self, user, **kwargs):
        """
        Method to assign workshop by presenter self.
        """

        action_map = {
            'opt-in': self.presenter.add,
            'opt-out': self.presenter.remove
        }
        message_map = {
            'opt-in': 'Assigned successfully.',
            'opt-out': 'Unassigned successfully.'
        }
        assigned = {
            'opt-in': True,
            'opt-out': False
        }
        action = kwargs.get('action')
        if assigned[action] and self.presenter.filter(pk=user.pk).exists():
            # This save has been added as fail safe
            # once the logic is consolidated may be
            # it can be removed
            self.status = WorkshopStatus.ACCEPTED
            self.save()
            return {
                'status': False,
                'msg': 'Workshop has already been assigned.'
            }

        func = action_map.get(action)
        func(user)

        if action == 'opt-out':
            self.number_of_volunteers = 0
            self.volunteer.clear()

        if self.presenter.count() > 0:
            self.status = WorkshopStatus.ACCEPTED
        else:
            self.status = WorkshopStatus.REQUESTED
        self.save()

        return {
            'status': True,
            'assigned': assigned[action],
            'msg': message_map[action],
            'notify': True
        }

    def get_presenter_list(self):
        return [user.get_full_name() for user in self.presenter.all()]

    def get_tweet(self, context):
        workshop = self
        try:
            date = workshop.expected_date.strftime('%d-%m-%Y')
        except:
            date = workshop.expected_date

        topic = workshop.workshop_section
        organization = workshop.requester
        location = workshop.requester.location
        workshop_url = context.get('workshop_url', None)
        message = "{} workshop at {} on {} confirmed! Details: {}".format(
            topic, organization, date, workshop_url)
        if len(message) >= 140:
            message = "{} workshop at {} on {} confirmed! Details: {}".format(
                topic, location, date, workshop_url)
        if len(message) >= 140:
            message = "{} workshop on {} confirmed! Details :{}".format(
                topic, date, workshop_url)

        return message

        def opt_in_as_volunteer(self):
            pass

        def opt_out_as_volunteer(self):
            pass class WorkshopFeedBack(TimeAuditModel):
    '''
    Requesting for Feedback from requester and Presenter
    '''

    workshop = models.ForeignKey(Workshop)
    comment = models.TextField()
    feedback_type = models.PositiveSmallIntegerField(
        choices=FeedbackType.CHOICES, verbose_name="User_type")

    class Meta:
        db_table = 'workshop_feedback'

    def __str__(self):
        return '{}'.format(self.workshop)

    @classmethod
    def save_feedback(cls, user, workshop_id, **kwargs):
        workshop = Workshop.objects.get(pk=workshop_id)
        presenter = workshop.is_presenter(user)
        organiser = workshop.is_organiser(user)
        comment = kwargs.get('comment', '')
        del kwargs['comment']

        if presenter:
            feedback_type = FeedbackType.PRESENTER
        elif organiser:
            feedback_type = FeedbackType.ORGANISATION

        workshop_feedback = cls.objects.create(
            workshop=workshop,
            comment=comment,
            feedback_type=feedback_type
        )
        kwargs.pop('csrfmiddlewaretoken', None)
        WorkshopVoting.save_rating(workshop_feedback, **kwargs)
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
from django.core.urlresolvers import reverse, reverse_lazy
from django.http import HttpResponseRedirect, JsonResponse
from django.shortcuts import get_object_or_404
from django.shortcuts import redirect, render
from django.views import generic
from braces import views
from wye.organisations.models import Organisation
from wye.profiles.models import Profile
from wye.social.sites.twitter import send_tweet
from wye.base.views import (
    verify_user_profile)
from wye.base.constants import WorkshopStatus
from .forms import (
    WorkshopForm,
    WorkshopEditForm,
    WorkshopFeedbackForm,
    WorkshopListForm,
    WorkshopVolunteer)
from .mixins import (
    WorkshopEmailMixin,
    WorkshopAccessMixin
)
from .utils import send_mail_to_group
from .models import Workshop, WorkshopFeedBack


@login_required
@verify_user_profile
def workshop_list(request):
    template_name = 'workshops/workshop_list.html'
    user_profile, created = Profile.objects.get_or_create(
        user__id=request.user.id)
    if not user_profile.is_profile_filled:
        return redirect('profiles:profile-edit', slug=request.user.username)
    context_dict = {}
    workshop_list = Workshop.objects.filter(
        is_active=True, status__in=[
            WorkshopStatus.REQUESTED]).order_by('-expected_date', 'status')
    workshop_list = workshop_list.filter(
        requester__location__state__id__in=[
            x.id for x in request.user.profile.interested_states.all()]
    )

    location_list = request.GET.getlist("location")
    if location_list:
        workshop_list = workshop_list.filter(
            requester__location__id__in=location_list
        )

    workshop_level_list = request.GET.getlist("level")
    if workshop_level_list:
        workshop_list = workshop_list.filter(
            workshop_level__in=workshop_level_list
        )

    workshop_section_list = request.GET.getlist("section")
    if workshop_section_list:
        workshop_list = workshop_list.filter(
            workshop_section__id__in=workshop_section_list
        )

    context_dict['workshop_list'] = workshop_list
    context_dict['user'] = request.user
    # need to improve the part
    context_dict['is_not_tutor'] = False
    # as user can be tutor and regional lead hence we need to verify like
    # this
    if (Profile.is_regional_lead(request.user) or
            Profile.is_organiser(request.user) or
            Profile.is_admin(request.user)):
        context_dict['is_not_tutor'] = True

    context_dict['form'] = WorkshopListForm(user=request.user)

    return render(request, template_name, context_dict)


def workshop_details(request, pk):
    template_name = 'workshops/workshop_detail.html'
    workshop_obj = get_object_or_404(Workshop, id=pk)
    show_contact_flag = False
    display_edit_button = False
    user = request.user
    user_is_presenter = [u for u in workshop_obj.presenter.all() if user == u]
    user_is_requester = [
        u for u in workshop_obj.requester.user.all() if user == u]
    if (user_is_presenter or user_is_requester or
            user.is_superuser or (
                (not user.is_anonymous()) and Profile.is_coordinator(user))):
        show_contact_flag = True
    if (user_is_presenter):
        display_edit_button = True
    is_admin = True if user.is_superuser else False
    form = WorkshopVolunteer(initial={
        'number_of_volunteers': workshop_obj.number_of_volunteers or 0})

    context_dict = {
        'workshop': workshop_obj,
        'show_contact_flag': show_contact_flag,
        'display_edit_button': display_edit_button,
        'is_admin': is_admin,
        'form': form,
        'user': request.user
    }
    return render(request, template_name, context_dict)


@login_required
@verify_user_profile
def workshop_create(request):
    template_name = 'workshops/workshop_create.html'
    context_dict = {}

    if not Organisation.list_user_organisations(request.user).exists():