# -*-coding:utf-8 -*-
from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage,PageNotAnInteger
from django.shortcuts import render, get_object_or_404
from ..models import Event,Town,Place,EventCategory,Category,Post,Article
from ..forms import TownPostForm,SearchPostForm,CategoryPostForm
from datetime import date
from django.utils import formats
from django.shortcuts import redirect
from datetime import datetime, timedelta
from collections import OrderedDict
import pytz
import os
import random
import logging
from django.db.models import Q
import uuid
from cacheops import cached, cached_view


logger = logging.getLogger('django')


# Create your views here.
def pageNotFound(request):
    response = render(request, 'backoffice/404.html')
    response.status_code = 404
    return response

def index(request):

    return showAccueil(request,None)

#@cached(timeout=300) #5 minutes de cache
def showAccueil(request,name):

    #ville = request.GET.get('ville')
    try:
        if name is None:
            ville="Paris"
        else:
            ville=name
        town = Town.objects.get(city=ville)
        events_list = Event.objects.filter(valid=True,
                                               refTown__city=ville).select_related('refPlace').select_related('refTown').select_related('refEventCategory').order_by('dateEvent')[:10]

        new_event_list =[]
        for event in events_list:
            if event.onIndexPage:
                new_event_list.append(event)

        for event in events_list:
            if event.onIndexPage==False:
                new_event_list.append(event)

        places_list = Place.objects.filter(valid=True,refTown__city=ville).select_related('refCategory').select_related('refTown').order_by('name')[:11]
        actu_list = Post.objects.filter(refTown__city=ville,valid=True).select_related('refUser').select_related('refTown').order_by('-createdAt')[:5]
        if ville=="Paris":
            article_list = Article.objects.filter(refTown__city=ville,valid=True).select_related('refTown').order_by('-createdAt')[:5]
        else:
            article_list=None
        today = datetime.now().date()
        tomorrow = today + timedelta(days=1)
        return render(request, 'backoffice/index.html',
                      {'articles': article_list, 'events': new_event_list, 'places': places_list, 'actus': actu_list,
                       'notIndex': True, 'city': ville, 'town': town, "today": today,'tomorrow':tomorrow})

    except Exception as e:
        logger.info(e)
        print(e)
        return render(request,'backoffice/404.html')

@cached(timeout=600) #10 minutes de cache
def article(request, slug):
    article = get_object_or_404(Article, slug=slug)
    return render(request,
                  'backoffice/article/article.html',
                  {'article': article})

def articles(request):
    name = "Paris"
    events_list = Event.objects.filter(valid=True,refTown__city=name).select_related('refPlace').select_related(
        'refTown').select_related('refEventCategory').order_by('dateEvent')[:6]
    articles = Article.objects.filter(refTown__city=name, valid=True).order_by('-createdAt')
    paginator = Paginator(articles, 10)  # 10 posts in each page
    today = datetime.now().date()
    page = request.GET.get('page')
    try:
        list_articles = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer deliver the first page
        list_articles = paginator.page(1)
    except EmptyPage:
        # If page is out of range deliver last page of results
        actus = paginator.page(paginator.num_pages)
    return render(request, 'backoffice/article/blog.html',
                  {'articles': list_articles, 'events': events_list,'notIndex': True, 'city': name,"page":page,"today":today})



@cached(timeout=600) #10 minutes de cache
def guide(request, city):
    try:
        town = Town.objects.get(city=city)
        selectedTown = town.city
    except Exception as e:
        logger.info("Exception avec city %s %s"%(city,e))
        town = Town.objects.get(city='Paris')
        selectedTown = town.city

    #on prend les evenements classés par date (+ proches en premier)
    today = datetime.now().date()
    events_list = Event.objects.filter(dateEvent__startswith=today, valid=True, refTown=town).select_related(
            'refPlace').select_related('refTown').select_related('refEventCategory').order_by('dateEvent')[:3]
    if not events_list:
        next_events_list = Event.objects.filter(valid=True,refTown__city=city).select_related('refPlace').select_related('refTown').select_related('refEventCategory').order_by('dateEvent')[:3]
    else:
        next_events_list = None

    places_list = Place.objects.filter(valid=True, highlighted=True, refTown=town).select_related('refCategory').select_related('refTown').order_by('name')
    town_list = Town.objects.all().order_by('city').cache()
    return render(request,
                     'backoffice/guide/guide-gay.html',
                     {'events': events_list,'nextevents':next_events_list, 'places':places_list,'selectedTown':selectedTown,'towns':town_list,'notIndex':True})
@cached(timeout=600) #10 minutes de cache
def actu_list(request,name):
    if name is None:
        name = "Paris"
    events_list = Event.objects.filter(valid=True,refTown__city=name).select_related('refPlace').select_related(
        'refTown').select_related('refEventCategory').order_by('dateEvent')[:6]
    actu_list = Post.objects.filter(refTown__city=name, valid=True).select_related('refUser').select_related('refTown').order_by('-createdAt')
    paginator = Paginator(actu_list, 10)  # 40 posts in each page
    today = datetime.now().date()
    page = request.GET.get('page')
    try:
        actus = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer deliver the first page
        actus = paginator.page(1)
    except EmptyPage:
        # If page is out of range deliver last page of results
        actus = paginator.page(paginator.num_pages)
    return render(request, 'backoffice/actus/liste_actus.html',
                  {'actus': actus, 'events': events_list,'notIndex': True, 'city': name,"page":page,"today":today})

#@cached(timeout=600) #10 minutes de cache
def event_list(request, name):
    if name is None:
        name = "Paris"
    categoryFiltre = request.GET.get('category')
    try:
        town = Town.objects.get(city=name)
        selectedTown = town.city
    except Exception as e:
        logger.info("Exception avec city %s %s" % (name, e))
        town = Town.objects.get(city='Paris')
        selectedTown = town.city

    page = request.GET.get('page')
    if page is None:
        page=1
    if categoryFiltre:
        events_list = Event.objects.filter(valid=True,refTown__city=selectedTown,refEventCategory=categoryFiltre).select_related('refPlace').select_related('refTown').select_related('refEventCategory').order_by('dateEvent').cache()
        categories_list = EventCategory.objects.filter(categoriesevent__refTown__city=selectedTown,categoriesevent__valid=True).cache()
        categories = []
        for cat in categories_list:
            if cat in categories:
                pass
            else:
                categories.append(cat)
    else:
        categoryFiltre=0
        events_list = Event.objects.filter(valid=True, refTown__city=selectedTown).select_related(
            'refPlace').select_related('refTown').select_related('refEventCategory').order_by('dateEvent').cache()
        # Categories
        categories = []
        for event in events_list:
            if event.refEventCategory in categories:
                pass
            else:
                categories.append(event.refEventCategory)
    town_list = Town.objects.all().order_by('city').cache()

    paginator = Paginator(events_list, 100)  # 20 posts in each page
    try:
        events = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer deliver the first page
        events = paginator.page(1)
    except EmptyPage:
        # If page is out of range deliver last page of results
        events = paginator.page(paginator.num_pages)

    actu_list = Post.objects.filter(refTown__city=selectedTown, valid=True).select_related('refUser').select_related(
        'refTown').order_by('-createdAt')[:5]
    article_list = Article.objects.filter(valid=True).select_related('refTown').order_by('-createdAt')[:5]

    today = datetime.now().date()
    tomorrow = today + timedelta(days=1)
    return render(request, 'backoffice/events/soirees-gay.html',
                  {'events': events,'tomorrow':tomorrow,'page': page, 'selectedTown': selectedTown,'city':selectedTown,'article_list':article_list,'actus':actu_list,'towns': town_list, 'categories':categories,'notIndex': True,"today":today,"categoryFiltre":int(categoryFiltre)})



#@cached(timeout=600) #10 minutes de cache
def event_es_list(request, name):
    if name is None:
        name = "Paris"
    categoryFiltre = request.GET.get('category')
    try:
        town = Town.objects.get(city=name)
        selectedTown = town.city
    except Exception as e:
        logger.info("Exception avec city %s %s" % (name, e))
        town = Town.objects.get(city='Paris')
        selectedTown = town.city

    page = request.GET.get('page')
    if page is None:
        page=1
    if categoryFiltre:
        events_list = Event.objects.filter(valid=True,refTown__city=selectedTown,refEventCategory=categoryFiltre).select_related('refPlace').select_related('refTown').select_related('refEventCategory').order_by('dateEvent').cache()
        categories_list = EventCategory.objects.filter(categoriesevent__refTown__city=selectedTown,categoriesevent__valid=True).cache()
        categories = []
        for cat in categories_list:
            if cat in categories:
                pass
            else:
                categories.append(cat)
    else:
        categoryFiltre=0
        events_list = Event.objects.filter(valid=True, refTown__city=selectedTown).select_related(
            'refPlace').select_related('refTown').select_related('refEventCategory').order_by('dateEvent').cache()
        # Categories
        categories = []
        for event in events_list:
            if event.refEventCategory in categories:
                pass
            else:
                categories.append(event.refEventCategory)
    town_list = Town.objects.all().order_by('city').cache()

    paginator = Paginator(events_list, 100)  # 20 posts in each page
    try:
        events = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer deliver the first page
        events = paginator.page(1)
    except EmptyPage:
        # If page is out of range deliver last page of results
        events = paginator.page(paginator.num_pages)

    actu_list = Post.objects.filter(refTown__city=selectedTown, valid=True).select_related('refUser').select_related(
        'refTown').order_by('-createdAt')[:5]
    today = datetime.now().date()
    tomorrow = today + timedelta(days=1)
    return render(request, 'backoffice/events/fiestas-gay.html',
                  {'events': events,'tomorrow':tomorrow,'page': page, 'selectedTown': selectedTown,'city':selectedTown, 'actus':actu_list,'towns': town_list, 'categories':categories,'notIndex': True,"today":today,"categoryFiltre":int(categoryFiltre)})


def week_range(date):
    """Find the first/last day of the week for the given day.
    Assuming weeks start on Sunday and end on Saturday.

    Returns a tuple of ``(start_date, end_date)``.

    """
    # isocalendar calculates the year, week of the year, and day of the week.
    # dow is Mon = 1, Sat = 6, Sun = 7
    year, week, dow = date.isocalendar()

    # Find the first day of the week.
    if dow == 1:
        # Since we want to start with Sunday, let's test for that condition.
        start_date = date
    else:
        # Otherwise, subtract `dow` number days to get the first day
        dow=dow-1
        start_date = date - timedelta(dow)

    # Now, add 6 for the last day of the week (i.e., count up to Saturday)
    end_date = start_date + timedelta(6)

    return (start_date, end_date)


#@cached(timeout=600)  # 10 minutes de cache
def event_week(request, name):
    # Call function to get dates range
    today  = date.today()
    tomorrow = today + timedelta(days=1)

    start_date , end_date = week_range(today)
    print('print function ', start_date, ' ', end_date)

    if name is None:
        name = "Paris"
    categoryFiltre = request.GET.get('category')
    try:
        town = Town.objects.get(city=name)
        selectedTown = town.city
    except Exception as e:
        logger.info("Exception avec city %s %s" % (name, e))
        town = Town.objects.get(city='Paris')
        selectedTown = town.city

    page = request.GET.get('page')
    if page is None:
        page=1
    if categoryFiltre:
        events_list = Event.objects.filter(valid=True,refTown__city=selectedTown,refEventCategory=categoryFiltre).select_related('refPlace').select_related('refTown').select_related('refEventCategory').order_by('dateEvent').cache()
        categories_list = EventCategory.objects.filter(categoriesevent__refTown__city=selectedTown,categoriesevent__valid=True).cache()
        categories = []
        for cat in categories_list:
            if cat in categories:
                pass
            else:
                categories.append(cat)
    else:
        categoryFiltre=0
        events_list = Event.objects.filter(valid=True, refTown__city=selectedTown).select_related(
            'refPlace').select_related('refTown').select_related('refEventCategory').order_by('dateEvent').cache()
        # Categories
        categories = []
        for event in events_list:
            if event.refEventCategory in categories:
                pass
            else:
                categories.append(event.refEventCategory)
    town_list = Town.objects.all().order_by('city').cache()
    list_filter = []
    for event in events_list:
        if event.dateEvent.date() >= start_date and event.dateEvent.date()<=end_date:
            list_filter.append(event)
    paginator = Paginator(list_filter, 100)  # 20 posts in each page
    try:
        events = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer deliver the first page
        events = paginator.page(1)
    except EmptyPage:
        # If page is out of range deliver last page of results
        events = paginator.page(paginator.num_pages)

    actu_list = Post.objects.filter(refTown__city=selectedTown, valid=True).select_related('refUser').select_related(
        'refTown').order_by('-createdAt')[:5]
    today = datetime.now().date()

    return render(request, 'backoffice/events/sorties-gay-de-la-semaine.html',
                  {'events': events,'tomorrow':tomorrow, 'page': page, 'selectedTown': selectedTown,'city':selectedTown, 'actus':actu_list,'towns': town_list, 'categories':categories,'notIndex': True,"today":today,"categoryFiltre":int(categoryFiltre)})



#@cached(timeout=600) #10 minutes de cache
def event(request, slug):
    event = get_object_or_404(Event, slug=slug)
    # Heure en UTC
    #date_modif = '2017-03-08'
    #if (event.dateEvent < dateBefore ):
    #    print "on ajoute 2H"
    event.dateEvent = event.dateEvent+timedelta(hours=1)
    dateOtherParties = event.dateEvent.date()
    otherEvents = Event.objects.filter(valid=True,refTown=event.refTown,dateEvent__contains=dateOtherParties)
    autreParties=[]
    for other in otherEvents:
        if other.id!=event.id:
            autreParties.append(other)
            logger.info("On a autre EVENT PARTIES %s"%other)
    autreEvents = None
    if event.refPlace.id>0:
        results = Event.objects.filter(refPlace=event.refPlace,valid=True)
        autreEvents =[]
        for eventfiltre in results:
            if event.id==eventfiltre.id:
                pass
            else:
                autreEvents.append(eventfiltre)
                logger.info("On a autreEvents %s" % eventfiltre)
    #heure = formats.localize(event.dateEvent.strftime('%H'), use_l10n=True)+":"+formats.localize(event.dateEvent.strftime('%M'), use_l10n=True)
    #logger.info("event %s location x %f y %f"%(event.name,event.location.x,event.location.y))
    latitude = 0
    longitude = 0

    try:
        #print("avant location x %f y %f" % (event.location.x, event.location.y))
        if event.location.x<event.location.y:
            prov = event.location.y
            event.location.y = event.location.x
            event.location.x = prov
            latitude = event.location.y
            longitude = event.location.x
            #print("apres location x %f y %f" % (event.location.x, event.location.y))
    except Exception as e:
        pass

    today = datetime.now().date()

    return render(request,
                  'backoffice/events/detail.html',
                  {'event': event,'autreEvents':autreEvents,'autreParties':autreParties,'lat':latitude,'lon':longitude,'notIndex':True,"today":today,'town':event.refTown})

@cached(timeout=600) #10 minutes de cache
def places_list(request, name):
    if name is None:
        name = "Paris"
    categoryFiltre = request.GET.get('category')
    try:
        town = Town.objects.get(city=name)
        selectedTown = town.city
    except Exception as e:
        logger.info("Exception avec city %s %s" % (city, e))
        town = Town.objects.get(city='Paris')
        selectedTown = town.city

    if categoryFiltre:
        places_list = Place.objects.filter(valid=True,refTown__city=selectedTown,refCategory=categoryFiltre).select_related('refCategory').select_related('refTown').order_by('name').cache()
        categories_list = Category.objects.filter(placescategories__refTown__city=selectedTown,placescategories__valid=True).cache()
        categories = []
        for cat in categories_list:
            if cat in categories:
                pass
            else:
                categories.append(cat)
    else:
        categoryFiltre = 0
        places_list = Place.objects.filter(valid=True, refTown__city=selectedTown).select_related(
            'refCategory').select_related('refTown').order_by('name').cache()
        categories = []
        for place in places_list:
            if place.refCategory in categories:
                pass
            else:
                categories.append(place.refCategory)

    town_list = Town.objects.all().order_by('city').cache()
    page = request.GET.get('page')
    if page is None:
        page = 1

    paginator = Paginator(places_list, 50)  # 20 posts in each page

    try:
        places = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer deliver the first page
        places = paginator.page(1)
    except EmptyPage:
        # If page is out of range deliver last page of results
        places = paginator.page(paginator.num_pages)
    actu_list = Post.objects.filter(refTown__city=selectedTown, valid=True).select_related(
            'refUser').select_related(
            'refTown').order_by('-createdAt')[:5]
    today = datetime.now().date()

    return render(request,
                     'backoffice/places/lieux-gays.html',
                     {'places': places,'page':page,'selectedTown':selectedTown,'towns':town_list,'categories':categories,'notIndex':True,
                      "actus":actu_list,"today":today,"city":selectedTown,"categoryFiltre":int(categoryFiltre)})
@cached(timeout=600) #10 minutes de cache
def place(request,slug):
    place = get_object_or_404(Place, slug=slug)
    latitude = 0
    longitude = 0
    import json
    if place.googlePlaceJson:
        json = json.loads(place.googlePlaceJson)
    else:
        json=None
    rating=None
    reviews=None
    if json:
        if "rating" in json:
            rating = json["rating"]
            user_ratings_total = json["user_ratings_total"]
            reviews = json["url"]
        else:
            user_ratings_total = -1
            reviews=None
    else:
        user_ratings_total = -1
        reviews = None
    try:
        if place.location:
            latitude = place.location.y
            longitude = place.location.x
    except Exception as e:
        pass

    placeEvents = place.eventsplace.filter(valid=True).order_by("dateEvent")

    return render(request,
                  'backoffice/places/detail.html',
                  {'place': place,"rating":rating,'user_ratings_total':user_ratings_total,'reviews':reviews,'placeEvents':placeEvents,'lat': latitude,'lon': longitude,'notIndex':True})

def searchEvent(request):
    if request.method == 'POST':
        city = request.POST["city"]
        searchTerm = request.POST['searchTerm']

        if city and searchTerm:
            events = Event.objects.filter(valid=True, refTown__city=city,name__icontains=searchTerm).select_related(
            'refPlace').select_related('refTown').select_related('refEventCategory').order_by('dateEvent')
            return render(request, 'backoffice/recherche/rechercheEvents.html',{'events':events})
        else:

            return render(request, 'backoffice/recherche/rechercheEvents.html', {'events': None})
    else:
        return render(request, 'backoffice/recherche/rechercheEvents.html', {'events': None})


def searchPlace(request):
    if request.method == 'POST':
        city = request.POST["city"]
        searchTerm = request.POST['searchTerm']

        if city and searchTerm:
            places = Place.objects.filter(valid=True, refTown__city=city,name__icontains=searchTerm).select_related('refTown').select_related('refCategory')
            return render(request, 'backoffice/recherche/recherchePlaces.html',{'places':places})
        else:

            return render(request, 'backoffice/recherche/recherchePlaces.html', {'places': None})
    else:
        return render(request, 'backoffice/recherche/recherchePlaces.html', {'places': None})