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

from rowers.views.statements import *

@login_required()
def deactivate_user(request):
    pk = request.user.id
    user = User.objects.get(pk=pk)
    user_form = DeactivateUserForm(instance=user)
    if request.user.is_authenticated and request.user.id == user.id:
        if request.method == "POST":
            user_form = DeactivateUserForm(request.POST, instance=user)
            if user_form.is_valid():
                if not user_form.cleaned_data['is_active']:
                    r = Rower.objects.get(user=user)
                    if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
                        try:
                            subscriptions = braintreestuff.find_subscriptions(r)
                            for subscription in subscriptions:
                                success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
                                for message in themessages:
                                    messages.info(request,message)
                        except ProcessorCustomerError:
                            pass

                        r.paidplan = None
                        r.teamplanexpires = timezone.now()
                        r.planexpires = timezone.now()
                        r.clubsize = 0
                        r.rowerplan = 'basic'
                        r.save()

                    deactivate_user = user_form.save(commit=False)
                    user.is_active = False
                    user.save()
                    deactivate_user.save()
                    #                url = reverse(auth_views.logout_then_login)
                    url = '/logout/?next=/login'
                    return HttpResponseRedirect(url)

        return render(request, "userprofile_deactivate.html", {
            "user_form": user_form,
        })
    else:
        raise PermissionDenied

@login_required()
def user_gdpr_optin(request):
    r = getrower(request.user)
    r.gdproptin = False
    r.gdproptindate = None
    r.save()
    nexturl = request.GET.get('next','/rowers/list-workouts/')
    if r.gdproptin:
        return HttpResponseRedirect(nexturl)

    return render(request,'gdpr_optin.html',{
        "next": nexturl
        })

@login_required()
def user_gdpr_confirm(request):
    r = getrower(request.user)
    r.gdproptin = True
    r.gdproptindate = timezone.now()
    r.save()

    nexturl = request.GET.get('next','/rowers/list-workouts/')

    return HttpResponseRedirect(nexturl)



@login_required()
def remove_user(request):
    pk = request.user.id
    user = User.objects.get(pk=pk)
    user_form = DeleteUserForm(instance=user)
    if request.user.is_authenticated and request.user.id == user.id:
        if request.method == "POST":
            user_form = DeleteUserForm(request.POST,instance=user)
            if user_form.is_valid():
                cd = user_form.cleaned_data
                name = user.first_name+' '+user.last_name
                email = user.email

                r = Rower.objects.get(user=user)
                if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
                    try:
                        subscriptions = braintreestuff.find_subscriptions(r)
                        for subscription in subscriptions:
                            success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
                        for message in themessages:
                            messages.info(request,message)
                    except:
                        pass

                if cd['delete_user']:
                    # delete workouts
                    Workout.objects.filter(user=user.rower).delete()
                    # delete planned sessions
                    PlannedSession.objects.filter(manager=user).delete()

                    user.delete()
                    res = myqueue(queuehigh,
                                  handle_sendemail_userdeleted,
                                  name, email)

                    url = '/logout/?next=/login'
#                    url = reverse(auth_views.logout_then_login)
                    return HttpResponseRedirect(url)
        return render(request, "userprofile_delete.html", {
            "user_form": user_form,
            })
    else:
        raise PermissionDenied


@login_required()
def survey(request):

    r = getrower(request.user)

    surveyform = SurveyForm()

    if request.method == 'POST':
        form = SurveyForm(request.POST)
        r.surveydone = True
        r.surveydonedate = timezone.now()
        r.save()

        nexturl = request.GET.get('next')
        return HttpResponseRedirect(nexturl)

    context = {
        'teams':get_my_teams(request.user),
        'rower':r,
        'form':surveyform,
        }


    return render(request,'survey.html',context)

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

    if not can_start_trial(request.user):
        messages.error(request,'You do not qualify for a trial')
        url = '/rowers/paidplans'
        return HttpResponseRedirect(url)

    r.protrialexpires = datetime.date.today()+datetime.timedelta(13)
    r.save()

    url = reverse('workouts_view')

    messages.info(request,'We have started your 14 day trial period')

    subject2 = "User started Pro Trial"
    message2 = "User Started Pro Trial.\n"
    message2 += request.user.email + "\n"
    message2 += "User name: "+request.user.username

    send_mail(subject2, message2,
              'Rowsandall Server <info@rowsandall.com>',
              ['roosendaalsander@gmail.com'])

    send_template_email('Rowsandall <info@rowsandall.com>',
                        [r.user.email],
                        'Welcome to the Rowsandall Pro Trial',
                        'protrialewelcome.html',
                        {'first_name':r.user.first_name,
                         'last_name':r.user.last_name})

    return HttpResponseRedirect(url)

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

    if not can_start_plantrial(request.user):
        messages.error(request,'You do not qualify for a trial')
        url = '/rowers/paidplans'
        return HttpResponseRedirect(url)

    r.plantrialexpires = datetime.date.today()+datetime.timedelta(13)
    r.protrialexpires = datetime.date.today()+datetime.timedelta(13)
    r.save()

    url = reverse('workouts_view')

    messages.info(request,'We have started your 14 day trial period')

    subject2 = "User started Plan Trial"
    message2 = "User Started Plan Trial.\n"
    message2 += request.user.email + "\n"
    message2 += "User name: "+request.user.username

    send_mail(subject2, message2,
              'Rowsandall Server <info@rowsandall.com>',
              ['roosendaalsander@gmail.com'])

    send_template_email('Rowsandall <info@rowsandall.com>',
                        [r.user.email],
                        'Welcome to the Rowsandall Self-Coach Trial',
                        'plantrialwelcome.html',
                        {'first_name':r.user.first_name,
                         'last_name':r.user.last_name})

    return HttpResponseRedirect(url)

# Page where user can manage his favorite charts
@login_required()
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
def rower_favoritecharts_view(request,userid=0):
    message = ''
    successmessage = ''
    r = getrequestrower(request,userid=userid,notpermanent=True)

    staticchartform = StaticChartRowerForm(instance=r)

    favorites = FavoriteChart.objects.filter(user=r).order_by('id')
    aantal = len(favorites)
    favorites_data = [{'yparam1':f.yparam1,
                       'yparam2':f.yparam2,
                       'xparam':f.xparam,
                       'plottype':f.plottype,
                       'workouttype':f.workouttype,
                       'reststrokes':f.reststrokes,
                       'notes':f.notes,}
                       for f in favorites]
    FavoriteChartFormSet = formset_factory(FavoriteForm,formset=BaseFavoriteFormSet,extra=0)
    if aantal==0:
        FavoriteChartFormSet = formset_factory(FavoriteForm,formset=BaseFavoriteFormSet,extra=1)

    if request.method == 'POST' and 'staticgrids' in request.POST:
        staticchartform = StaticChartRowerForm(request.POST,instance=r)
        if staticchartform.is_valid():
            r.staticgrids = staticchartform.cleaned_data.get('staticgrids')
            r.slowpaceerg = staticchartform.cleaned_data.get('slowpaceerg')
            r.fastpaceerg = staticchartform.cleaned_data.get('fastpaceerg')
            r.slowpaceotw = staticchartform.cleaned_data.get('slowpaceotw')
            r.fastpaceotw = staticchartform.cleaned_data.get('fastpaceotw')
            r.save()

    if request.method == 'POST' and 'form-TOTAL_FORMS' in request.POST:
        favorites_formset = FavoriteChartFormSet(request.POST)
        if favorites_formset.is_valid():
            new_instances = []
            for favorites_form in favorites_formset:
                yparam1 = favorites_form.cleaned_data.get('yparam1')
                yparam2 = favorites_form.cleaned_data.get('yparam2')
                xparam = favorites_form.cleaned_data.get('xparam')
                plottype = favorites_form.cleaned_data.get('plottype')
                workouttype = favorites_form.cleaned_data.get('workouttype')
                reststrokes = favorites_form.cleaned_data.get('reststrokes')
                notes = favorites_form.cleaned_data.get('notes')
                new_instances.append(FavoriteChart(user=r,
                                                   yparam1=yparam1,
                                                   yparam2=yparam2,
                                                   xparam=xparam,
                                                   plottype=plottype,
                                                   notes=notes,
                                                   workouttype=workouttype,
                                                   reststrokes=reststrokes))
            try:
                with transaction.atomic():
                    FavoriteChart.objects.filter(user=r).delete()
                    FavoriteChart.objects.bulk_create(new_instances)
                    successmessage = "You have updated your favorites"
                    messages.info(request,message)
                    if len(new_instances)==0:
                        FavoriteChartFormSet=formset_factory(FavoriteForm,formset=BaseFavoriteFormSet,extra=1)
                        favorites_formset = FavoriteChartFormSet()
            except IntegrityError:
                message = "something went wrong"
                messages.error(request,message)
    else:
        favorites_formset = FavoriteChartFormSet(initial=favorites_data)


    context = {
        'favorites_formset':favorites_formset,
        'teams':get_my_teams(request.user),
        'rower':r,
        'staticchartform':staticchartform,
        }



    return render(request,'favoritecharts.html',context)

# page where user sets his export settings
@login_required()
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
def rower_exportsettings_view(request,userid=0):
    r = getrequestrower(request,userid=userid)
    if request.method == 'POST':
        form = RowerExportForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data

            for attr, value in cd.items():
                setattr(r, attr, value)

            r.save()
            messages.info(request,'Settings saved')
    else:
        form = RowerExportForm(instance=r)

    breadcrumbs = [
        {
            'url':'/rowers/me/edit/',
            'name': 'Profile'
            },
        {
            'url': reverse('rower_exportsettings_view'),
            'name': 'Export Settings'
            }
        ]

    return render(request, 'rower_exportsettings.html',
                  {'form':form,
                   'rower':r,
                   'breadcrumbs': breadcrumbs,
                  })


# Page where user can set his details
# Add email address to form so user can change his email address
@login_required()
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
def rower_edit_view(request,rowerid=0,userid=0,message=""):
    r = getrequestrower(request,rowerid=rowerid,userid=userid,notpermanent=True)

    rowerid = r.id

    breadcrumbs = [
        {
            'url':'/rowers/me/edit/',
            'name': 'Profile'
            },
        {
            'url': reverse('rower_edit_view'),
            'name': 'Account Settings'
            }
        ]


    if request.method == 'POST':
        accountform = AccountRowerForm(request.POST, instance=r)
        userform = UserForm(request.POST,instance=r.user)

        if accountform.is_valid() and userform.is_valid():
            # process
            cd = accountform.cleaned_data
            ucd = userform.cleaned_data

            first_name = ucd['first_name']
            last_name = ucd['last_name']
            email = ucd['email']
            sex = cd['sex']
            try:
                offercoaching = cd['offercoaching']
            except KeyError:
                offercoaching = False
            autojoin = cd['autojoin']
            adaptiveclass = cd['adaptiveclass']
            defaultlandingpage = cd['defaultlandingpage']
            weightcategory = cd['weightcategory']
            birthdate = cd['birthdate']
            showfavoritechartnotes = cd['showfavoritechartnotes']
            getemailnotifications = cd['getemailnotifications']
            getimportantemails = cd['getimportantemails']
            defaulttimezone=cd['defaulttimezone']
            u = r.user
            if u.email != email and len(email):
                resetbounce = True
            else:
                resetbounce = False
            if len(first_name):
                u.first_name = first_name
            u.last_name = last_name
            if len(email): ## and check_email_freeforuse(u,email):
                u.email = email
                resetbounce = True


            u.save()
            r.defaulttimezone=defaulttimezone
            r.weightcategory = weightcategory
            r.adaptiveclass = adaptiveclass
            r.getemailnotifications = getemailnotifications
            r.getimportantemails = getimportantemails
            r.offercoaching = offercoaching
            r.defaultlandingpage = defaultlandingpage
            r.showfavoritechartnotes = showfavoritechartnotes
            r.sex = sex
            r.birthdate = birthdate
            r.autojoin = autojoin

            if resetbounce and r.emailbounced:
                r.emailbounced = False
            r.save()

            accountform = AccountRowerForm(instance=r)
            userform = UserForm(instance=u)
            successmessage = 'Account Information changed'
            messages.info(request,successmessage)
    else:
        accountform = AccountRowerForm(instance=r)
        userform = UserForm(instance=r.user)


    grants = AccessToken.objects.filter(user=request.user)
    return render(request, 'rower_form.html',
                  {
                      'teams':get_my_teams(request.user),
                      'breadcrumbs':breadcrumbs,
                      'grants':grants,
                      'userform':userform,
                      'accountform':accountform,
                      'rower':r,
                  })


# Page where user can set his details
# Add email address to form so user can change his email address
@login_required()
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
def rower_prefs_view(request,userid=0,message=""):
    r = getrequestrower(request,userid=userid,notpermanent=True)

    rowerid = r.id

    breadcrumbs = [
        {
            'url':'/rowers/me/edit/',
            'name': 'Profile'
            },
        {
            'url': reverse('rower_prefs_view'),
            'name': 'Zones'
            }
        ]

    form = RowerForm(instance=r)
    powerform = RowerPowerForm(instance=r)
    powerzonesform = RowerPowerZonesForm(instance=r)

    if request.method == 'POST' and "ut2" in request.POST:
        form = RowerForm(request.POST)
        if form.is_valid():
            # something
            cd = form.cleaned_data
            hrmax = cd['max']
            ut2 = cd['ut2']
            ut1 = cd['ut1']
            at = cd['at']
            tr = cd['tr']
            an = cd['an']
            rest = cd['rest']

            r.max = max(min(hrmax,250),10)
            r.ut2 = max(min(ut2,250),10)
            r.ut1 = max(min(ut1,250),10)
            r.at = max(min(at,250),10)
            r.tr = max(min(tr,250),10)
            r.an = max(min(an,250),10)
            r.rest = max(min(rest,250),10)
            r.save()
            successmessage = "Your Heart Rate data were changed"
            messages.info(request,successmessage)
    elif request.method == 'POST' and "ftp" in request.POST:
        powerform = RowerPowerForm(request.POST)
        if powerform.is_valid():
            cd = powerform.cleaned_data
            hrftp = cd['hrftp']
            if hrftp == 0:
                hrftp = int((r.an+r.tr)/2.)
            ftp = cd['ftp']
            otwslack = cd['otwslack']

            powerfrac = 100*np.array([r.pw_ut2,
                                      r.pw_ut1,
                                      r.pw_at,
                                      r.pw_tr,r.pw_an])/r.ftp
            r.ftp = max(min(ftp,650),50)
            r.otwslack = max(min(otwslack,50),0)
            ut2,ut1,at,tr,an = (r.ftp*powerfrac/100.).astype(int)
            r.pw_ut2 = ut2
            r.pw_ut1 = ut1
            r.pw_at = at
            r.pw_tr = tr
            r.pw_an = an
            r.hrftp = hrftp
            r.save()
            message = "FTP and/or OTW slack values changed."
            messages.info(request,message)

    elif request.method == 'POST' and "ut3name" in request.POST:
        powerzonesform = RowerPowerZonesForm(request.POST)
        if powerzonesform.is_valid():
            cd = powerzonesform.cleaned_data
            pw_ut2 = cd['pw_ut2']
            pw_ut1 = cd['pw_ut1']
            pw_at = cd['pw_at']
            pw_tr = cd['pw_tr']
            pw_an = cd['pw_an']
            ut3name = cd['ut3name']
            ut2name = cd['ut2name']
            ut1name = cd['ut1name']
            atname = cd['atname']
            trname = cd['trname']
            anname = cd['anname']
            powerzones = [ut3name,ut2name,ut1name,atname,trname,anname]

            r.pw_ut2 = pw_ut2
            r.pw_ut1 = pw_ut1
            r.pw_at = pw_at
            r.pw_tr = pw_tr
            r.pw_an = pw_an
            r.powerzones = powerzones
            r.save()
            successmessage = "Your Power Zone data were changed"
            messages.info(request,successmessage)

    return render(request, 'rower_preferences.html',
                  {
                      'form':form,
                      'teams':get_my_teams(request.user),
                      'powerform':powerform,
                      'powerzonesform':powerzonesform,
                      'breadcrumbs':breadcrumbs,
                      'rower':r,
                  })


# Revoke an app that you granted access through the API.
# this views is called when you press a button on the User edit page
# the button is only there when you have granted access to an app
@login_required()
def rower_revokeapp_view(request,id=0):
    try:
        tokens = AccessToken.objects.filter(user=request.user,application=id)
        refreshtokens = AccessToken.objects.filter(user=request.user,application=id)
        for token in tokens:
            token.revoke()
        for token in refreshtokens:
            token.revoke()

        r = getrower(request.user)
        form = RowerForm(instance=r)
        powerform = RowerPowerForm(instance=r)
        grants = AccessToken.objects.filter(user=request.user)
        url = reverse('rower_edit_view')
        return HttpResponseRedirect(url)
    except AccessToken.DoesNotExist:
        raise Http404("Access token doesn't exist")


@login_required()
def rower_update_empower_view(
        request,
        startdate=timezone.now()-datetime.timedelta(days=365),
        enddate=timezone.now()
):
    try:
        r = getrower(request.user)
    except Rower.DoesNotExist:
        raise Http404("Rower doesn't exist")

    if request.method == 'POST' and 'daterange' in request.POST:
        dateform = DateRangeForm(request.POST)
        if dateform.is_valid():
            startdate = dateform.cleaned_data['startdate']
            enddate = dateform.cleaned_data['enddate']
            startdatestring = startdate.strftime('%Y-%m-%d')
            enddatestring = enddate.strftime('%Y-%m-%d')
            request.session['startdate'] = startdatestring
            request.session['enddate'] = enddatestring
    else:
        dateform = DateRangeForm(initial={
            'startdate':startdate,
            'enddate':enddate,
            })


    if request.method == 'POST' and 'workouts' in request.POST:
        form = WorkoutMultipleCompareForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            workouts = cd['workouts']
            workoutdicts = []

            for w in workouts:
                if w.user != r:
                    message = "You can only alter your own workouts"
                    messages.error(request,message)
                if 'x' in w.boattype and w.oarlength is not None and w.oarlength > 3.30:
                    message = "Oarlength and boat type mismatch for workout "+str(w.id)+". Skipping workout"
                    messages.error(request,message)
                elif 'x' not in w.boattype and w.oarlength is not None and w.oarlength <= 3.30:
                    message = "Oarlength and boat type mismatch for workout "+str(w.id)+". Skipping workout"
                    messages.error(request,message)
                elif w.oarlength is None:
                    message = "Incorrect oarlength in workout "+str(w.id)+". Skipping workout"
                    messages.error(request,message)
                else:


                    workoutdict = {
                        'id':w.id,
                        'boattype':w.boattype,
                        'filename':w.csvfilename,
                        'inboard':w.inboard,
                        'oarlength':w.oarlength
                    }

                    workoutdicts.append(workoutdict)

                    w.workoutsource = 'speedcoach2corrected'
                    w.save()


            job = myqueue(queuelow,handle_update_empower,
                          request.user.email,workoutdicts,
                          debug=False,
                          emailbounced=r.emailbounced)

            try:
                request.session['async_tasks'] += [(job.id,'update_empower')]
            except KeyError:
                request.session['async_tasks'] = [(job.id,'update_empower')]

            successmessage = 'Your workouts are being updated in the background. You will receive email when this is done. You can check the status of your calculations <a href="/rowers/jobs-status" target="_blank">here</a>'

            messages.info(request,successmessage)

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

        workouts = Workout.objects.filter(
            startdatetime__gte=startdate,
            startdatetime__lte=enddate,
            workoutsource='speedcoach2',
            user=r,
        ).order_by("-date","-starttime")

        form = WorkoutMultipleCompareForm()
        form.fields["workouts"].queryset = workouts
        # GET request = prepare form

        return render(request, 'empower_fix.html',
                      {'workouts':workouts,
                       'active': 'nav-workouts',
                       'dateform':dateform,
                       'form':form,
                       'rower':r
                       })
