from django.contrib.auth import login
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect, render
from django.template.loader import render_to_string
from django.views.generic import ListView
from django.views.generic.edit import CreateView

from authentication import forms as auth_forms
from . import forms, models


class TeamListView(ListView):
    model = models.Team
    context_object_name = "teams"
    template_name = "teams/index.html"
    paginate_by = 10

    def get_paginate_by(self, queryset):
        return self.request.GET.get('paginate_by', self.paginate_by)


class TeamCreateView(CreateView):
    form_class = forms.TeamForm
    model = models.Team
    template_name = "teams/create.html"

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.creator = self.request.user
        self.object.team_type = models.Team.Type.ASSOCIATE
        self.object.save()
        return HttpResponseRedirect(self.get_success_url())


def team_detail(request, pk):
    team = get_object_or_404(models.Team, id=pk)
    state = team.state_for(request.user)
    role = team.role_for(request.user)
    # if state is None:
    #     raise Http404()
    return render(
        request,
        "teams/detail.html",
        {
            "team": team,
            "members": team.memberships.all(),
            "state": state,
            "role": role,
            "can_join": team.can_join(request.user),
            "can_leave": team.can_leave(request.user),
            "can_apply": team.can_apply(request.user),
        },
    )


def team_edit(request, pk):
    team = get_object_or_404(models.Team, id=pk)
    # if not team.is_admin(request.user):
    #     return HttpResponseForbidden()
    if request.method == "POST":
        form = forms.TeamForm(request.POST, instance=team)
        if form.is_valid():
            form.save()
            return redirect(team.get_absolute_url())
    else:
        form = forms.TeamForm(instance=team)
    return render(request, "teams/edit.html", {"form": form, "team": team})


def team_invite_view(request, pk: int):
    team = get_object_or_404(models.Team, id=pk)
    form = forms.TeamInviteUserForm(request.POST or None, team=team)

    if form.is_valid():
        user_or_email = form.cleaned_data["invitee"]
        role = form.cleaned_data["role"]
        if isinstance(user_or_email, str):
            # New user will be created
            membership = team.invite_user(request.user, user_or_email, role)
        else:
            # Invite existing user
            membership = team.add_user(user_or_email, role, by=request.user)
        return redirect('team_detail', pk=pk)

    context = {
        'form': form,
        'team': team,
    }
    return render(request, 'teams/invite.html', context)


def create_user_from_signup_code(request, code: str):
    try:
        code: models.SignupCode = models.SignupCode.check_code(code)
        email = code.email
    except models.SignupCode.InvalidCode:
        return render(request, 'sign_up/code_invalid.html')

    if request.method == "POST":
        post_data = request.POST.copy()
        post_data["email"] = email

        form = auth_forms.SignUpForm(post_data)
        profile_form = auth_forms.ProfileForm(post_data)

        if form.is_valid() and profile_form.is_valid():
            user = form.save(commit=False)
            user.username = user.email
            user.save()

            for attr, val in profile_form.cleaned_data.items():
                setattr(user.profile, attr, val)
            user.profile.email_confirmed = True
            user.profile.save()

            invite = code.joininvitation
            invite.accept(user)
            memberships = models.Membership.objects.filter(invite=invite)
            for membership in memberships:
                membership.accept(user)
            code.use(user)

            login(request, user)
            return redirect('team_join_welcome', team_id=membership.team.id)

    else:
        form = auth_forms.SignUpForm()
        profile_form = auth_forms.ProfileForm()

    terms_of_service = render_to_string('legal/terms_of_service.html')

    return render(
        request,
        "sign_up/create_user.html",
        {"form": form, "profile_form": profile_form, "terms_of_service": terms_of_service},
    )


def team_join_welcome(request, team_id: int):
    return render(request, 'sign_up/join_welcome.html', {'team_id': team_id})


def team_member_remove(request, pk: int, membership_id: int):
    membership = get_object_or_404(models.Membership, pk=membership_id)
    membership.remove(by=request.user)
    return redirect('team_detail', pk=pk)
