from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.template import loader
from django.urls import reverse
from django.core.paginator import Paginator
from django.conf import settings
from django.contrib.auth.forms import UserCreationForm
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout, update_session_auth_hash
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import PasswordChangeForm
from django.db.models import Q
from .models import Post, Comment, PostState
from .forms import PostForm, CustomUserCreationForm, SigninForm
from datetime import datetime
import logging
import uuid

#Users
def register(request):
    if request.method == 'POST':
        f = CustomUserCreationForm(request.POST)
        if f.is_valid():
            f.save()
            messages.success(request, 'Account created successfully')
            return HttpResponseRedirect(reverse('news:index'))
    else:
        f = CustomUserCreationForm()

    return render(request, 'news/user/register.html', {'form': f})

def signin(request):

    if request.method == 'POST':

        f = SigninForm(request.POST)
        if f.is_valid():
            username = f.cleaned_data['username']
            password = f.cleaned_data['password']

            user = authenticate(username=username, password=password)
            if user is not None:
                login(request, user)
                return HttpResponseRedirect(reverse('news:index'))
            else:
                messages.success(request, 'Sign-in failed')
                return HttpResponseRedirect(reverse('news:signin'))
    else:
        f = SigninForm()
    return render(request, 'news/user/signin.html', {'form': f})

@login_required
def logout_view(request):
    logout(request)
    return HttpResponseRedirect(reverse('news:index'))

@login_required
def account(request):
    return render(request, 'news/user/account.html', {})

@login_required
def password_change(request):
    if request.method == 'POST':
        form = PasswordChangeForm(request.user, request.POST)
        if form.is_valid():
            user = form.save()
            update_session_auth_hash(request, user)  # Important!
            messages.success(request, 'Your password was successfully updated!')
            return render(request, 'news/user/account.html', {})
        else:
            messages.error(request, 'Please correct the error below.')
    else:
        form = PasswordChangeForm(request.user)
    return render(request, 'news/user/change_password.html', {'form': form})

#Post
def index(request):

    filter1 = Q(state=1)
    filter2 = Q(date__lte=datetime.today())

    latest_post_list = Post.objects.filter(filter1 & filter2).order_by('-date')
    paginator = Paginator(latest_post_list, 25)

    page = request.GET.get('page')
    posts = paginator.get_page(page)

    context = { 'latest_post_list' : posts }
    return render(request, 'news/index.html', context)

def post(request, post_id):
    post = get_object_or_404(Post, pk=post_id)
    return render(request, 'news/post.html', {'post': post, 'comments': post.flat_comments(request.user) })

@login_required
def submission(request):

    if request.method == 'POST':
        form = PostForm(request.POST, request.FILES)
        if form.is_valid():

            post = Post.objects.create(author=request.user,date=datetime.today())
            post.title = form.cleaned_data['title']
            post.body = form.cleaned_data['body']
            post.url = form.cleaned_data['url']
            post.style = form.cleaned_data['style']

            filename = str(uuid.uuid4())
            handle_uploaded_file(filename, request.FILES['image'])

            post.image_url = filename
            if request.user.is_staff:
                post.state = PostState.PUBLISHED.value
                pub_date = form.cleaned_data['pub_date']
                if pub_date is not None:
                    post.date = pub_date
            else:
                post.state = PostState.USER_SUBMITTED.value
            post.save()

            return HttpResponseRedirect(reverse('news:submitted'))
    # if a GET (or any other method) we'll create a blank form
    else:
        form = PostForm()

    return render(request, 'news/submission.html', {'form': form})

def handle_uploaded_file(filename, f):
    with open(settings.MEDIA_ROOT + filename, 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)

def submitted(request):
    return render(request, 'news/submitted.html', {})

def comment(request, post_id):
    return comment_with_parent(request, post_id, None)

def comment_with_parent(request, post_id, comment_id):
    comment = Comment(author=request.user,date=datetime.today())
    comment.post = get_object_or_404(Post, pk=post_id)
    if comment_id is not None:
        comment.parent_comment = get_object_or_404(Comment, pk=comment_id)
    comment.body = request.POST['body']
    comment.save()
    comment.voters.add(request.user)
    comment.save()
    return HttpResponseRedirect(reverse('news:post', args=(post_id,)))

def delete_comment(request, comment_id):
    comment = get_object_or_404(Comment, pk=comment_id)
    post = comment.post
    if comment.comment_set.all().count() > 0:
        comment.body = "[deleted]"
        comment.deleted = True
        comment.save()
    else:
        comment.delete()
    return render(request, 'news/post.html', {'post': post, 'comments': post.flat_comments(request.user) })

def upvote(request, comment_id):
    comment = get_object_or_404(Comment, pk=comment_id)
    comment.voters.add(request.user)
    comment.save()
    post = comment.post
    return render(request, 'news/post.html', {'post': post, 'comments': post.flat_comments(request.user) })
