# coding=utf-8
from gettext import gettext as _

from django.contrib import messages
from django.contrib.auth import login
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.views import LoginView
from django.db import transaction
from django.http import HttpResponse
from django.shortcuts import redirect
from django.shortcuts import render
from django.urls import reverse

from food_planner.forms import ProfileForm
from food_planner.forms import UserForm
from food_planner.models import MealPlan
from food_planner.models import Profile


def index(request) -> HttpResponse:
    context = {
        'site': {
            'title': 'Food planner'
        }
    }
    if request.user.is_authenticated:
        context['mealplans'] = MealPlan.objects.filter(author=request.user)
        return render(request, template_name='food_planner/home.html', context=context)
    else:
        return render(request, template_name='food_planner/landing.html', context=context)


def mealplan(request, user_id: int, mealplan_title: str) -> HttpResponse:
    mealplan_obj = MealPlan.objects.get(author_id=user_id, name=mealplan_title)
    # calculate calories for each day, TODO: extract later
    profile = Profile.objects.get(user=request.user)
    calories_required = profile.daily_calories_demand
    
    calories_monday = get_calories_sum(mealplan_obj, 'monday')
    calories_monday_percentage = calories_monday / calories_required * 100

    calories_tuesday = get_calories_sum(mealplan_obj, 'tuesday')
    calories_tuesday_percentage = calories_tuesday / calories_required * 100

    calories_wednesday = get_calories_sum(mealplan_obj, 'wednesday')
    calories_wednesday_percentage = calories_wednesday / calories_required * 100

    calories_thursday = get_calories_sum(mealplan_obj, 'thursday')
    calories_thursday_percentage = calories_thursday / calories_required * 100

    calories_friday = get_calories_sum(mealplan_obj, 'friday')
    calories_friday_percentage = calories_friday / calories_required * 100

    calories_saturday = get_calories_sum(mealplan_obj, 'saturday')
    calories_saturday_percentage = calories_saturday / calories_required * 100

    calories_sunday = get_calories_sum(mealplan_obj, 'sunday')
    calories_sunday_percentage = calories_sunday / calories_required * 100
        
    context = {
        'site': {
            'title': 'Food planner'
        },
        'mealplan': mealplan_obj,
        'calories_monday': f"{calories_monday_percentage:.2f}",
        'calories_tuesday': f"{calories_tuesday_percentage:.2f}",
        'calories_wednesday': f"{calories_wednesday_percentage:.2f}",
        'calories_thursday': f"{calories_thursday_percentage:.2f}",
        'calories_friday': f"{calories_friday_percentage:.2f}",
        'calories_saturday': f"{calories_saturday_percentage:.2f}",
        'calories_sunday': f"{calories_sunday_percentage:.2f}",
    }
    return render(request, template_name='food_planner/mealplan.html', context=context)


def get_calories_sum(mealplan: MealPlan, weekday: str) -> float:
    calories_sum = 0
    breakfast = mealplan.__getattribute__(weekday + '_breakfast')
    morning_snack = mealplan.__getattribute__(weekday + '_morning_snack')
    lunch = mealplan.__getattribute__(weekday + '_lunch')
    afternoon_snack = mealplan.__getattribute__(weekday + '_afternoon_snack')
    dinner = mealplan.__getattribute__(weekday + '_dinner')
    calories_sum += breakfast.calories if breakfast is not None else 0
    calories_sum += morning_snack.calories if morning_snack is not None else 0
    calories_sum += lunch.calories if lunch is not None else 0
    calories_sum += afternoon_snack.calories if afternoon_snack is not None else 0
    calories_sum += dinner.calories if dinner is not None else 0
    
    return calories_sum


@transaction.atomic
def register(request) -> HttpResponse:
    if request.user.is_authenticated:
        return redirect('food_planner:index')
    
    user_form = UserCreationForm(data=request.POST or None)
    profile_form = ProfileForm(data=request.POST or None, files=request.FILES or None)
    context = {
        'site':         {
            'title': 'Food planner'
        },
        'user_form':    user_form,
        'profile_form': profile_form
    }
    if request.method == "POST" and user_form.is_valid() and profile_form.is_valid():
        user = user_form.save()
        profile = profile_form.save(commit=False)
        profile.user = user
        if 'profile_pic' in request.FILES:
            profile.profile_pic = request.FILES['profile_pic']
        profile.save()
        login(request, user=user)
        messages.success(request, _('User was successfully registered'))
        return redirect('edit_profile')
    
    return render(request, template_name='registration/register.html', context=context)


def user_login(request) -> HttpResponse:
    login_view = LoginView()
    login_view.setup(request)
    login_view.redirect_authenticated_user = True
    login_view.extra_context = {
        'active': 'login',
        'title':  _('Login'),
        'site':   {
            'title': 'Food planner'
        },
    }
    return login_view.dispatch(request)


@login_required()
@transaction.atomic
def edit_profile(request) -> HttpResponse:
    user_form = UserForm(data=request.POST or None, instance=request.user)
    profile_form = ProfileForm(data=request.POST or None, files=request.FILES or None,
                               instance=request.user.profile)
    user_form.fields['email'].help_text = _('The email address is required for password recovery.')
    context = {
        'active':       'edit_profile',
        'title':        _('Edit User Profile'),
        'site':         {
            'title': 'Food planner'
        },
        'user_form':    user_form,
        'profile_form': profile_form
    }
    
    if request.method == "POST" and user_form.is_valid() and profile_form.is_valid():
        user_form.save()
        profile = profile_form.save(commit=False)
        if 'profile_pic' in request.FILES:
            profile.profile_pic = request.FILES['profile_pic']
        profile.save()
        messages.success(request, _('Profile was successfully updated'))
    
    return render(request, template_name='registration/edit_profile.html', context=context)


@login_required()
def password_change_done(request) -> HttpResponse:
    messages.success(request, _('Your password was successfully changed.'))
    return redirect(reverse('edit_profile'))


def legal(request) -> HttpResponse:
    context = {
        'site': {
            'title': 'Food planner'
        }
    }
    return render(request, template_name='food_planner/legal.html', context=context)


def privacy(request) -> HttpResponse:
    context = {
        'site': {
            'title': 'Food planner'
        }
    }
    return render(request, template_name='food_planner/privacy.html', context=context)
