# -*- coding: utf-8 -*-
'''
Created on Aug 20, 2013

@author: rvelt
'''

from jocondelab.models import DbpediaYears, DbpediaGeo, DbpediaFields, ContributedTerm, ContributedFields, Contribution
from core.models import Notice, Term, Thesaurus
import django.utils.simplejson as json
from django.core.paginator import Paginator
from django.http import HttpResponse
from django.template.response import TemplateResponse
from django.views.generic import TemplateView, DetailView
from django.db.models import Sum
from django.conf import settings

def terms(request):
    
    lang = request.GET.get('lang', request.LANGUAGE_CODE)[:2]
    q = request.GET.get('term', None)
    count = request.GET.get('count', 20)
    qs = DbpediaFields.objects.filter(language_code=lang,label__iregex=r"\y%s"%q).values('dbpedia_uri','label').distinct().order_by('label')[:count]
    res = [{"dbpedia_uri": r['dbpedia_uri'], "label": r['label']} for r in qs]
    return HttpResponse(content=json.dumps(res), mimetype='application/json')

def years(request):
    
    lang = request.GET.get('lang', request.LANGUAGE_CODE)[:2]
    from_year = request.GET.get('from_year', None)
    to_year = request.GET.get('to_year', None)
    count = request.GET.get('count', 20)
    
    qs = DbpediaYears.objects.filter(term__dbpedia_fields__language_code=lang)
    if to_year:
        qs = qs.filter(start_year__lte=to_year)
    if from_year:
        qs = qs.filter(end_year__gte=from_year)
    qs = qs.values('start_year','end_year','term__dbpedia_fields__label','term__dbpedia_uri')
    qs = qs.annotate(sum_notices=Sum('term__nb_notice')).order_by('-sum_notices')
    
    qs = qs[:count]
    
    results = [{
                "start_year": y["start_year"],
                "end_year": y["end_year"],
                "label": y["term__dbpedia_fields__label"],
                "sum_notices": y["sum_notices"],
                "dbpedia_uri": y["term__dbpedia_uri"]
                } for y in qs]
    
    return HttpResponse(content=json.dumps(results), mimetype='application/json')

def geo_coords(request):
    
    lang = request.GET.get('lang', request.LANGUAGE_CODE)[:2]
    min_lat = request.GET.get('min_lat', None)
    max_lat = request.GET.get('max_lat', None)
    min_lng = request.GET.get('min_lng', None)
    max_lng = request.GET.get('max_lng', None)
    count = request.GET.get('count', 20)
    
    qs = DbpediaGeo.objects.filter(term__dbpedia_fields__language_code=lang)
    
    if min_lat:
        qs = qs.filter(latitude__gt=min_lat)
    if max_lat:
        qs = qs.filter(latitude__lt=max_lat)
    if min_lng:
        qs = qs.filter(longitude__gt=min_lng)
    if max_lng:
        qs = qs.filter(longitude__lt=max_lng)
    
    qs = qs.values('latitude','longitude','term__dbpedia_fields__label','term__dbpedia_uri')
    qs = qs.annotate(sum_notices=Sum('term__nb_notice')).order_by('-sum_notices')
    
    qs = qs[:count]
    
    results = [{
                "latitude": y["latitude"],
                "longitude": y["longitude"],
                "label": y["term__dbpedia_fields__label"],
                "sum_notices": y["sum_notices"],
                "dbpedia_uri": y["term__dbpedia_uri"]
                } for y in qs]
    
    return HttpResponse(content=json.dumps(results), mimetype='application/json')

def geo_search(request):
    
    lang = request.GET.get('lang', request.LANGUAGE_CODE)[:2]
    q = request.GET.get('term', None)
    count = request.GET.get('count', 20)
    
    qs = DbpediaGeo.objects.filter(term__dbpedia_fields__language_code=lang, term__dbpedia_fields__label__icontains=q)
    qs = qs.values('latitude','longitude','term__dbpedia_fields__label','term__dbpedia_uri')
    qs = qs.annotate(sum_notices=Sum('term__nb_notice')).order_by('-sum_notices')[:count]
    
    results = [{
                "latitude": y["latitude"],
                "longitude": y["longitude"],
                "label": y["term__dbpedia_fields__label"],
                "sum_notices": y["sum_notices"],
                "dbpedia_uri": y["term__dbpedia_uri"]
                } for y in qs]
    results.sort(key=lambda y: y["label"])
    
    return HttpResponse(content=json.dumps(results), mimetype='application/json')

class BaseContributionView(TemplateView):
    
    template_name = "jocondelab/partial/contributed_item.html"
    
    def render_contribution(self, contribution, request):
        lang = request.LANGUAGE_CODE[:2]
        termdict = {
            "label": contribution.term.dbpedia_fields.get(language_code=lang).label,
            "dbpedia_uri": contribution.term.dbpedia_uri,
            "contribution_id": contribution.id,
            "li_style": "positive" if contribution.contribution_count > 0 else "null",
            "font_size": "%.1f"%(12. + .5 * max(0., min(12., contribution.contribution_count))),
            "vote_mode": (contribution.thesaurus is None)
        }
        return self.render_to_response({"term": termdict})
    
    def get(self, request):
        contribution_id = int(request.GET.get('contribution_id', None))
        return self.render_contribution(Contribution.objects.get(pk=contribution_id), request)

class ContributeView(BaseContributionView):
    
    def post(self, request):
        
        notice_id = request.POST.get('notice_id', None)
        lang = request.LANGUAGE_CODE[:2]
        dbpedia_uri = request.POST.get('dbpedia_uri', None) #TODO: Remove it and regenerate from Wikipedia/Dbpedia
        thesaurus_label = request.POST.get('thesaurus_label', None)
        label = request.POST.get('label', None)
        
        thobj = Thesaurus.objects.get(label=thesaurus_label) if thesaurus_label else None
        notobj = Notice.objects.get(id=notice_id)
        
        # Contributed Term should be validated and Dbpedia uris should be regenerated by SPARQL Queries
        
        termobj, created = ContributedTerm.objects.get_or_create(dbpedia_uri=dbpedia_uri)
        controbj, created = Contribution.objects.get_or_create(term=termobj, thesaurus=thobj, notice=notobj, defaults={'contribution_count': 1})
        if not created:
            controbj.contribution_count += 1
            controbj.save()
        
        # Translated labels should also be regenerated from dbpedia.
        
        fieldsobj, created = ContributedFields.objects.get_or_create(term=termobj, dbpedia_uri=dbpedia_uri, language_code=lang, defaults={'label': label})
        if not created:
            fieldsobj.label = label
            fieldsobj.save()
        return self.render_contribution(controbj, request)
    

class VoteView(BaseContributionView):
    
    vote_value = 0
    
    def post(self, request):
        contribution_id = int(request.POST.get('contribution_id', None))
        controbj = Contribution.objects.get(id=contribution_id)
        controbj.contribution_count += self.vote_value
        controbj.save()
        return self.render_contribution(controbj, request)
    