from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from rowers.views.statements import *

from rowers.rower_rules import *

def get_team_by_pk(request,team_id):
    return get_object_or_404(Team,pk=team_id)



@login_required()
@permission_required('teams.view_team',fn=get_team_by_pk,raise_exception=True)
def team_view(request,team_id=0,userid=0):
    ismember = 0
    hasrequested = 0
    r = getrequestrower(request,userid=userid)

    myteams, memberteams, otherteams = get_teams(request)
    teams.remove_expired_invites()

    t = get_object_or_404(Team,pk=team_id)

    #if r.rowerplan == 'basic' and t.manager.rower.rowerplan != 'coach':
    #    raise PermissionDenied("You need to be on a Paid Plan to see or join this team")


    q = User.objects.filter(rower__isnull=False,rower__team__in=myteams).distinct().exclude(rower__team__name=t.name)
    mygroups = [request.user.rower.mycoachgroup]
    q2 = User.objects.filter(rower__isnull=False,rower__coachinggroups__in=mygroups).distinct().exclude(rower__team__name=t.name)

    q = q | q2

    if request.method == 'POST' and request.user == t.manager and 'email' in request.POST:
        inviteform = TeamInviteForm(request.POST)

        inviteform.fields['user'].queryset = q
        if inviteform.is_valid():
            cd = inviteform.cleaned_data
            newmember = cd['user']
            email = cd['email']
            inviteid,text = teams.create_invite(t,t.manager,
                                                   user=newmember,
                                                   email=email)
            if inviteid:
                teams.send_invite_email(inviteid)
                successmessage = text
                messages.info(request,successmessage)
            else:
                message = text
                messages.error(request,message)
        groupmessageform = TeamMessageForm()
    elif request.method == 'POST' and request.user == t.manager and 'message' in request.POST:
        groupmessageform = TeamMessageForm(request.POST)
        inviteform = TeamInviteForm()
        if groupmessageform.is_valid():
            message = groupmessageform.cleaned_data['message']
            teams.send_team_message(t,message)
            messages.info(request,'Message was sent to all team members')
        groupmessageform = TeamMessageForm()

    elif request.user == t.manager:
        inviteform = TeamInviteForm()
        inviteform.fields['user'].queryset = q
        groupmessageform = TeamMessageForm()
    else:
        inviteform = ''
        groupmessageform = ''


    members = Rower.objects.filter(team=t).order_by('user__last_name','user__first_name')
    thisteammyrequests = TeamRequest.objects.filter(team=t,user=request.user)
    if len(thisteammyrequests):
        hasrequested = 1

    if r in members:
        ismember = 1

    breadcrumbs = [
        {
            'url':reverse(rower_teams_view),
            'name': 'Groups'
            },
        {
            'url':reverse(team_view,kwargs={'team_id':team_id}),
            'name': t.name
            }
        ]


    return render(request, 'team.html',
                  {
                      'team':t,
                      'teams':get_my_teams(request.user),
                      'myteams':myteams,
                      'memberteams':memberteams,
                      'groupmessageform': groupmessageform,
                      'members':members,
                      'breadcrumbs':breadcrumbs,
                      'active':'nav-teams',
                      'inviteform':inviteform,
                      'ismember':ismember,
                      'hasrequested':hasrequested,
                      })

@login_required()
def team_leaveconfirm_view(request,id=0):
    try:
        t = Team.objects.get(id=id)
    except Team.DoesNotExist:
        raise Http404("Team doesn't exist")

    myteams, memberteams, otherteams = get_teams(request)

    breadcrumbs = [
        {
            'url':reverse(rower_teams_view),
            'name': 'Groups'
            },
        {
            'url':reverse(team_view,kwargs={'team_id':id}),
            'name': t.name
            },
        {
            'url':reverse(team_leaveconfirm_view,kwargs={'id':id}),
            'name': 'Leave'
            }
        ]
    return render(request,'teamleaveconfirm.html',
                  {
                      'team':t,
                      'teams':get_my_teams(request.user),
                      'myteams':myteams,
                      'memberteams':memberteams,
                      'otherteams':otherteams,
                      'active':'nav-teams',
                      'breadcrumbs':breadcrumbs,
                      })

@login_required()
def rower_calcdps_view(request):
    r = getrower(request.user)

    ws = [(w.id,w.csvfilename) for w in Workout.objects.filter(user=r)]
    res = myqueue(queue,handle_updatedps,r.user.email,ws,debug=False,
                  emailbounced=r.emailbounced)

    messages.info(request,"Your workouts are being updated in the background. You will receive email when this is done.")

    url = reverse('workouts_view')
    return HttpResponseRedirect(url)

@login_required()
def team_leave_view(request,id=0):
    r = getrower(request.user)
    teams.remove_member(id,r)

    url = reverse(rower_teams_view)
    response = HttpResponseRedirect(url)
    return response

from rowers.forms import TeamInviteCodeForm

def get_teams(request):
    r = Rower.objects.get(user=request.user)

    myteams = Team.objects.filter(
        manager=request.user).order_by('name')
    memberteams = Team.objects.filter(
        rower=r).exclude(manager=request.user).order_by('name')
    otherteams = Team.objects.filter(
        private='open').exclude(
            rower=r).exclude(manager=request.user).order_by('name')

    if r.rowerplan == 'basic':
        otherteams = otherteams.filter(manager__rower__rowerplan='coach')

    return myteams, memberteams, otherteams

@login_required()
def rower_teams_view(request):
    if request.method == 'POST':
        form = TeamInviteCodeForm(request.POST)
        if form.is_valid():
            code = form.cleaned_data['code']
            res,text = teams.process_invite_code(request.user,code)
            if res:
                messages.info(request,text)
            else:
                messages.error(request,text)
    else:
        form = TeamInviteCodeForm()

    r = getrower(request.user)
    ts = Team.objects.filter(rower=r)


    myteams, memberteams, otherteams = get_teams(request)
    teams.remove_expired_invites()

    invites = TeamInvite.objects.filter(user=request.user)
    requests = TeamRequest.objects.filter(user=request.user)
    myrequests = TeamRequest.objects.filter(team__in=myteams)
    myinvites = TeamInvite.objects.filter(team__in=myteams)

    # user invites (as coach)
    mycoachoffers = CoachOffer.objects.filter(coach=r)
    # user is invited (by coach)
    coachoffers = CoachOffer.objects.filter(user=r.user)

    # user requests a coach
    mycoachrequests = CoachRequest.objects.filter(user=r.user)
    # user is requested to coach
    coachrequests = CoachRequest.objects.filter(coach=r)

    invitedathletes = [rekwest.user for rekwest in mycoachoffers]
    invitedcoaches = [rekwest.coach for rekwest in mycoachrequests ]
    invitedcoaches += [rekwest.coach for rekwest in coachoffers]
    invitingathletes = [rekwest.user for rekwest in coachrequests]

    coaches = teams.rower_get_coaches(r)

    potentialcoaches = [t.manager for t in memberteams if t.manager not in coaches and 'coach' in t.manager.rower.rowerplan]
    offercoaches = [
        r.user for r in Rower.objects.filter(
            offercoaching=True,rowerplan__in='coach').exclude(user=request.user)
    ]
    potentialcoaches = list(set(potentialcoaches+offercoaches))
    potentialcoaches = [c for c in potentialcoaches if c.rower not in invitedcoaches+coaches]
    potentialcoaches = [c for c in potentialcoaches if teams.get_coach_club_size(c.rower)<c.rower.clubsize]


    coachees = teams.coach_getcoachees(request.user.rower)

    if request.user.rower.rowerplan == 'coach':
        potentialathletes = Rower.objects.filter(
            team__in=myteams).exclude(
                user__in=invitedathletes).exclude(
                    user=request.user
                ).exclude(coachinggroups__in=[request.user.rower.mycoachgroup])
    elif request.user.rower.rowerplan == 'freecoach':
        potentialathletes = Rower.objects.filter(
            team__in=myteams).exclude(
                user__in=invitedathletes).exclude(
                    user=request.user
                ).exclude(
                    coachinggroups__in=[request.user.rower.mycoachgroup]
                ).exclude(
                    rowerplan__in=['basic','freecoach']
                )
    else:
        potentialathletes = []

    potentialathletes = [a for a in potentialathletes if a.user not in invitingathletes]

    #    clubsize = teams.count_invites(request.user)+teams.count_club_members(request.user)
    #   max_clubsize = r.clubsize


    breadcrumbs = [
        {
            'url':reverse(rower_teams_view),
            'name': 'Groups'
            }
        ]


    return render(request, 'teams.html',
		  {
                      'teams':ts,
                      'active':'nav-teams',
                      'breadcrumbs':breadcrumbs,
                      'myteams':myteams,
                      'memberteams':memberteams,
                      'invites':invites,
                      'otherteams':otherteams,
                      'requests':requests,
                      'myrequests':myrequests,
                      'form':form,
                      'myinvites':myinvites,
                      'mycoachrequests':mycoachrequests,
                      'mycoachoffers':mycoachoffers,
                      'coachrequests':coachrequests,
                      'coachoffers':coachoffers,
                      'coaches':coaches,
                      'potentialcoaches':potentialcoaches,
                      'coachees':coachees,
                      'potentialathletes':potentialathletes,
		  })

@login_required()
def invitation_revoke_view(request,id):
    res,text = teams.revoke_invite(request.user,id)
    if res:
        messages.info(request,text)
        successmessage = text
    else:
        message = text
        messages.error(request,text)

    url = reverse(rower_teams_view)

    return HttpResponseRedirect(url)

@login_required()
def manager_member_drop_view(request,teamid,userid,
                             message='',successmessage=''):
    rower = Rower.objects.get(user__id=userid)
    res, text = teams.mgr_remove_member(teamid,request.user,rower)
    if res:
        messages.info(request,text)
    else:
        messages.error(request,text)

    url = reverse(rower_teams_view)

    return HttpResponseRedirect(url)

@login_required()
def manager_requests_view(request,code=None):
    if code:
        res,text = teams.process_request_code(request.user,code)
        if res:
            messages.info(request,text)
        else:
            messages.error(request,text)

    url = reverse(rower_teams_view,kwargs={
    })
    return HttpResponseRedirect(url)

@login_required()
def athlete_drop_coach_confirm_view(request,id):
    r = getrower(request.user)
    try:
        coach = Rower.objects.get(id=id)
    except Rower.DoesNotExist:
        raise Http404("This rower doesn't exist")
    if coach not in teams.rower_get_coaches(r):
        raise PermissionDenied("You are not allowed to do this")

    breadcrumbs = [
        {
            'url':reverse('rower_teams_view'),
            'name': 'Groups'
            },
        {
            'url':reverse('athlete_drop_coach_confirm_view',kwargs={'id':id}),
            'name': 'Confirm drop athlete'
            }
        ]

    return render(request,'dropcoachconfirm.html',
                  {
                      'rower':r,
                      'coach':coach
                      })

@login_required()
def coach_drop_athlete_confirm_view(request,id):
    r = getrower(request.user)
    try:
        rower = Rower.objects.get(id=id)
    except Rower.DoesNotExist:
        raise Http404("This rower doesn't exist")
    if rower not in teams.coach_getcoachees(r):
        raise PermissionDenied("You are not allowed to do this")

    breadcrumbs = [
        {
            'url':reverse('rower_teams_view'),
            'name': 'Groups'
            },
        {
            'url':reverse('coach_drop_athlete_confirm_view',kwargs={'id':id}),
            'name': 'Confirm drop athlete'
            }
        ]

    return render(request,'dropathleteconfirm.html',
                  {
                      'rower':r,
                      'athlete':rower
                      })

@login_required()
def coach_drop_athlete_view(request,id):
    r = getrower(request.user)
    try:
        rower = Rower.objects.get(id=id)
    except Rower.DoesNotExist:
        raise Http404("This rower doesn't exist")
    if rower not in teams.coach_getcoachees(r):
        raise PermissionDenied("You are not allowed to do this")

    res,text = teams.coach_remove_athlete(r,rower)

    if res:
        messages.info(request,'You are not coaching this athlete any more')
    else:
        messages.error(request,'There was an error dropping the athlete from your list')

    url = reverse('rower_teams_view')

    return HttpResponseRedirect(url)

@login_required()
def athlete_drop_coach_view(request,id):
    r = getrower(request.user)
    try:
        coach = Rower.objects.get(id=id)
    except Rower.DoesNotExist:
        raise Http404("This coach doesn't exist")
    if coach not in teams.rower_get_coaches(r):
        raise PermissionDenied("You are not allowed to do this")

    res,text = teams.coach_remove_athlete(coach,r)

    if res:
        messages.info(request,'Removal successful')
    else:
        messages.error(request,'There was an error dropping the coach from your list')

    url = reverse('rower_teams_view')

    return HttpResponseRedirect(url)

@login_required()
def team_requestmembership_view(request,teamid,userid):
    try:
        t = Team.objects.get(id=teamid)
    except Team.DoesNotExist:
        raise Http404("Team doesn't exist")

    r = getrequestrower(request,userid=userid)

    #if t.manager.rower.rowerplan in ['plan','pro'] and r.rowerplan == 'basic':
    if not can_join_team(r.user,t):
        messages.error(request,
                       "You have to be on a paid plan (Pro or higher) to join this team. As a basic user you can only join teams managed by users on the Coach plan.")

        url = reverse('paidplans_view')
        return HttpResponseRedirect(url)

    res,text = teams.create_request(t,userid)
    if res:
        messages.info(request,text)
    else:
        messages.error(request,text)


    url = reverse('team_view',kwargs={
	'team_id':int(teamid),
        })


    return HttpResponseRedirect(url)

@login_required()
def request_coaching_view(request,coachid):
    r = getrequestrower(request)

    coach = User.objects.get(id=coachid).rower

    if 'coach' in coach.rowerplan:
        res,text = teams.create_coaching_request(coach,request.user)
        if res:
            messages.info(request,text)
        else:
            messages.error(request,text)
    else:
        messages.error(request,'That person is not a coach')

    url = reverse('rower_teams_view')

    return HttpResponseRedirect(url)

@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None)
def offer_coaching_view(request,userid):
    try:
        u = User.objects.get(id=userid)
    except User.DoesNotExist:
        raise Http404("This user doesn't exist")

    coach = getrequestrower(request)

    res,text = teams.create_coaching_offer(coach,u)

    if res:
        messages.info(request,text)
    else:
        messages.error(request,text)

    url = reverse('rower_teams_view')

    return HttpResponseRedirect(url)

@login_required()
def reject_revoke_coach_request(request,id=0):
    res, text = teams.reject_revoke_coach_request(request.user,id)

    if res:
        messages.info(request,text)
    else:
        messages.error(request,text)

    url = reverse('rower_teams_view')

    return HttpResponseRedirect(url)

@login_required()
def reject_revoke_coach_offer(request,id=0):
    res, text = teams.reject_revoke_coach_offer(request.user,id)

    if res:
        messages.info(request,text)
    else:
        messages.error(request,text)

    url = reverse('rower_teams_view')

    return HttpResponseRedirect(url)

@login_required()
def request_revoke_view(request,id=0):
    res,text = teams.revoke_request(request.user,id)

    if res:
        messages.info(request,text)

    else:
        messages.error(request,text)

    url = reverse(rower_teams_view)

    return HttpResponseRedirect(url)

@login_required()
def request_reject_view(request,id=0):
    res,text = teams.reject_request(request.user,id)

    if res:
        messages.info(request,text)
    else:
        messages.error(request,text)

    url = reverse(rower_teams_view)

    return HttpResponseRedirect(url)

@login_required()
def invitation_reject_view(request,id=0):
    res,text = teams.reject_invitation(request.user,id)

    if res:
        messages.info(request,text)
    else:
        messages.error(request,text)

    url = reverse(rower_teams_view)

    return HttpResponseRedirect(url)

@login_required()
def rower_invitations_view(request,code=None,message='',successmessage=''):

    if code:
        teams.remove_expired_invites()
        res,text = teams.process_invite_code(request.user,code)
        if res:
            messages.info(request,text)
            teamid=res
            url = reverse(team_view,kwargs={
	        'team_id':teamid,
            })
        else:
            messages.error(request,text)

            url = reverse(rower_teams_view)

        return HttpResponseRedirect(url)

    url = reverse(rower_teams_view,kwargs={
    })
    return HttpResponseRedirect(url)

@login_required()
@permission_required('teams.change_team',fn=get_team_by_pk,raise_exception=True)
def team_edit_view(request, team_id=0):
    t = get_object_or_404(Team,pk=team_id)


    if request.method == 'POST':
        teamcreateform = TeamForm(request.POST,instance=t)
        if teamcreateform.is_valid():
            cd = teamcreateform.cleaned_data
            name = cd['name']
            notes = cd['notes']
            manager = request.user
            private = cd['private']
            viewing = cd['viewing']
            res,message=teams.update_team(t,name,manager,private,notes,
                                          viewing)
            if res:
                messages.info(request,message)
            else:
                messages.error(request,message)

            url = reverse(team_view,
                          kwargs={
                              'team_id':int(team_id),
                          }
            )

            response = HttpResponseRedirect(url)
            return response

    else:
        teamcreateform = TeamForm(instance=t)

    myteams, memberteams, otherteams = get_teams(request)

    breadcrumbs = [
        {
            'url':reverse(rower_teams_view),
            'name': 'Groups'
            },
        {
            'url':reverse(team_view,kwargs={'team_id':team_id}),
            'name': t.name
            },
        {
            'url':reverse(team_edit_view,kwargs={'team_id':team_id}),
            'name': 'Edit'
            }
        ]

    return render(request,'teamedit.html',
                  {
                      'form':teamcreateform,
                      'teams':get_my_teams(request.user),
                      'myteams':myteams,
                      'memberteams':memberteams,
                      'otherteams':otherteams,
                      'active':'nav-teams',
                      'breadcrumbs':breadcrumbs,
                      'team':t,
                      })

@login_required()
@user_passes_test(can_add_team,login_url="/rowers/paidplans",redirect_field_name=None,
                  message="You need to upgrade or log in to access this functionality")
def team_create_view(request):
    r = getrequestrower(request)

    if request.method == 'POST':
        teamcreateform = TeamForm(request.POST)
        if teamcreateform.is_valid():
            cd = teamcreateform.cleaned_data
            name = cd['name']
            notes = cd['notes']
            manager = request.user
            private = cd['private']
            viewing = cd['viewing']
            res,message=teams.create_team(name,manager,private,notes,
                                          viewing)

            if not res:
                messages.error(request,message)
                url = reverse('paidplans_view')
                return HttpResponseRedirect(url)

            url = reverse('rower_teams_view')
            response = HttpResponseRedirect(url)
            return response

    else:
        teamcreateform = TeamForm()

    myteams, memberteams, otherteams = get_teams(request)

    breadcrumbs = [
        {
            'url':reverse(rower_teams_view),
            'name': 'Groups'
            },
        {
            'url':reverse(team_create_view),
            'name': "New Team"
            },
        ]
    return render(request,'teamcreate.html',
                  {
                      'teams':get_my_teams(request.user),
                      'form':teamcreateform,
                      'myteams':myteams,
                      'memberteams':memberteams,
                      'otherteams':otherteams,
                      'active':'nav-teams',
                      'breadcrumbs':breadcrumbs,
                      })

#@login_required()
@permission_required('teams.delete_team',fn=get_team_by_pk,raise_exception=True)
def team_deleteconfirm_view(request,team_id):
    r = getrower(request.user)
    t = get_object_or_404(Team,pk=team_id)

    myteams, memberteams, otherteams = get_teams(request)

    breadcrumbs = [
        {
            'url':reverse(rower_teams_view),
            'name': 'Groups'
            },
        {
            'url':reverse(team_view,kwargs={'team_id':team_id}),
            'name': t.name
            },
        {
            'url':reverse(team_deleteconfirm_view,kwargs={'team_id':team_id}),
            'name': 'Leave'
            }
        ]
    return render(request,'teamdeleteconfirm.html',
                  {
                      'teams':get_my_teams(request.user),
                      'team':t,
                      'myteams':myteams,
                      'memberteams':memberteams,
                      'otherteams':otherteams,
                      'active':'nav-teams',
                  })

@login_required()
@permission_required('teams.delete_team',fn=get_team_by_pk,raise_exception=True)
def team_delete_view(request,team_id):
    r = getrower(request.user)
    t = get_object_or_404(Team,pk=team_id)

    teams.remove_team(t.id)

    url = reverse(rower_teams_view)
    response = HttpResponseRedirect(url)
    return response

@login_required()
@permission_required('teams.change_team',fn=get_team_by_pk,raise_exception=True)
def team_members_stats_view(request,team_id):
    r = getrower(request.user)
    t = get_object_or_404(Team,pk=team_id)

    members = Rower.objects.filter(team=t).order_by("user__last_name","user__first_name")

    theusers = [member.user for member in members]

    myteams, memberteams, otherteams = get_teams(request)

    breadcrumbs = [
        {
            'url':reverse(rower_teams_view),
            'name': 'Groups'
            },
        {
            'url':reverse(team_view,kwargs={'team_id':team_id}),
            'name': t.name
            },
        {
            'url':reverse(team_members_stats_view,kwargs={'team_id':team_id}),
            'name': 'Members Stats'
            }
        ]

    response = render(request,'teamstats.html',
                  {
                      'teams':get_my_teams(request.user),
                      'myteams':myteams,
                      'memberteams':memberteams,
                      'otherteams':otherteams,
                      'active':'nav-teams',
                      'breadcrumbs':breadcrumbs,
                      'team':t,
                      'theusers':theusers,
                  })

    return response

@login_required()
def rower_accept_coachoffer_view(request,code=None):
    if code:
        res, text = teams.process_coachoffer_code(request.user,code)
        if res:
            messages.info(request,text)
        else:
            messages.error(request,text)

    url = reverse('rower_teams_view')
    return HttpResponseRedirect(url)

@login_required()
def coach_accept_coachrequest_view(request,code=None):
    if code:
        res, text = teams.process_coachrequest_code(request.user.rower,code)
        if res:
            messages.info(request,text)
        else:
            messages.error(request,text)

    url = reverse('rower_teams_view')
    return HttpResponseRedirect(url)
