import random
from time import sleep
from django.utils import timezone
from gauth.models import Location, LocationManager
from analytics.background_job import send_email
from .models import Review, CustomReply, Reply
from nlu_job.nlu_utils import is_a_name
from review.review_utils import reply_review
from review.review_utils import get_bad_reviews, fetch_batch_of_reviews

from nameparser import HumanName


def un_replied_reviews_with_no_comment():
    now = timezone.now()
    date = now - timezone.timedelta(days=30)
    reviews = Review.objects.filter(comment=None, reply=None, star_rating=5, update_time__gte=date)\
        .order_by('update_time')
    return reviews


def make_parsable_name(name):
    name = HumanName(name)
    if name.first == '':
        if name.title:
            parsable_name = ' ' + name.title + ' ' + name.last
        else:
            parsable_name = ' ' + name.last
    else:
        parsable_name = ' ' + name.first.capitalize()
    return parsable_name


def generate_reply(review):
    replies = CustomReply.objects.filter(reply_category='no_comment')
    reply = random.choice(replies)
    name = review.reviewer_name
    if is_a_name(name):
        parsable_name = make_parsable_name(name)
    else:
        parsable_name = ''
    replied_text = reply.reply %parsable_name
    return replied_text


def reply_uncommented_reviews():
    reviews = un_replied_reviews_with_no_comment()
    # TODO: reply reviews in background
    for review in reviews:
        replied_text = generate_reply(review)
        response = reply_review(review=review, replied_text=replied_text)

        if response.status_code == 200:
            review_reply = Reply(replied_text=replied_text, create_time=timezone.now())
            review_reply.save()
            review.reply = review_reply
            review.save()
    sleep(60*random.randint(2, 5))


def send_email_bad_reviews():
    locations = Location.objects.all()
    for location in locations:
        reviews = get_bad_reviews(location.location_id, hours=1)
        total_reviews = reviews.count()
        if total_reviews > 0:
            to = list(LocationManager.objects.filter(location_id=location.location_id).values_list('email', flat=True))

            subject = f"A negative Google review has been posted in {location.care_name}."
            message = '<p>Hi there, </p><p>'
            if total_reviews > 1:
                tt = f'{total_reviews} negative Google reviews have'
            else:
                tt = 'A negative Google review has '
            message += tt + f'been posted in {location.care_name}.</p>'
            for r in reviews:
                link = f'<p>Link: {r.location.review_site_url}</p>'
                name = f'<p><b>Reviewer Name:</b> {r.reviewer_name}</p>'
                rating = f'<p style="color: red"><b>Rating:</b> {str(r.star_rating)} star rating.</p>'
                comment = f'<p><b>Comment: </b>{r.comment if r.comment else "No comment"}</p>'
                message += name + rating + comment + link
            message += '<p>Regards,</p><p>SignatureCare Review Team.</p>'

            send_email(subject=subject, message_body=message, to_list=to)


def background_task_every_hour():
    fetch_batch_of_reviews()
    send_email_bad_reviews()
    sleep(60 * random.randint(2, 5))
    reply_uncommented_reviews()