# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.shortcuts import render


# Create your views here.
from django.conf import settings
from catalog.models import Publisher, News, Search, audioTime
from django.core.exceptions import ObjectDoesNotExist 
from django.shortcuts import redirect
from django.http import HttpResponse
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import Count
from django.core.urlresolvers import reverse
from django.db.models.functions import TruncMonth, TruncYear

from .forms import SearchForm, ProfileForm, SubscriptionsForm

from django.db.models import Q
import json
import datetime
import time
from dateutil.relativedelta import relativedelta
import dateutil.parser

import urllib

import json
#import StringIO #python2
from io import StringIO #python3

import time
import zipfile
import csv

from quantiphy import Quantity

#from .audioList import getAudioList
from numpy import array_equal
import os
import shutil
#-------------------------------------------------------------------------------
def getAudiosList2Convert(request, streamPublisher, initTimestamp, endTimestamp, days):

	if not request.session.session_key:
		request.session.save()
	session_id = request.session.session_key
	
	cwd = settings.BASE_DIR
	print ("CDW: "  + cwd)
	directory = cwd+"/catalog/static/audioPlayList/sessions/"+session_id+"/"
	if not os.path.exists(directory):
		os.mkdir(directory)
	else:
		shutil.rmtree(directory)
		os.mkdir(directory)

	recordingsPath = '/home/mario/virtualHDD/m3/recordings/'
	initialDate = datetime.datetime.fromtimestamp(initTimestamp) #+ timedelta(hours=6)
	endDate = datetime.datetime.fromtimestamp(endTimestamp) #+ timedelta(hours=6)

	audiosList = []

	for i in range(days):

		audiosPath = '{0}/{1}/{2:02d}/{3:02d}/'.format(
			streamPublisher, 
			initialDate.year,
			initialDate.month,
			initialDate.day
		)
		print('Now enter in: {0}'.format(audiosPath))

		if os.path.exists(recordingsPath+audiosPath):
			for file in os.listdir(recordingsPath+audiosPath):
				audioTimestamp = int(file.split(".")[0])
				if audioTimestamp >= initTimestamp and audioTimestamp <= endTimestamp:
					audiosList.append(audiosPath+file)
					os.symlink(recordingsPath+audiosPath+file, directory+file)


		# Next day dir
		initialDate += datetime.timedelta(days=1)

	return audiosList

#-------------------------------------------------------------------------------
def getRecordingDays(initTimestamp, endTimestamp):

	initialDate = datetime.datetime.fromtimestamp(initTimestamp) #+ timedelta(hours=6)
	endDate = datetime.datetime.fromtimestamp(endTimestamp) #+ timedelta(hours=6)

	print(initialDate)
	print(endDate)

	iDate = [initialDate.day, initialDate.month, initialDate.year]
	eDate = [endDate.day, endDate.month, endDate.year]

	days = 1
	if array_equal(iDate, eDate):
		# Iterate over the same day dir
		return days
	else:
		while not array_equal(iDate, eDate):
			days += 1
			initialDate += datetime.timedelta(days=1)
			iDate = [initialDate.day, initialDate.month, initialDate.year]
		return days


#-------------------------------------------------------------------------------
def getAudiosList(request, streamPublisher, initTimestamp, endTimestamp):
	initTimestamp = float(initTimestamp)
	endTimestamp = float(endTimestamp)
	days = getRecordingDays(initTimestamp, endTimestamp)
	print('Recording days: {0}'.format(days))
	audiosList = getAudiosList2Convert(request, streamPublisher, initTimestamp, endTimestamp, days)
	return audiosList

#-------------------------------------------------------------------------------
def news2JSON(news):
	data = list()
	for n in news:
		item = dict()
		item['date'] = n.date.strftime('%Y-%m-%d')
		item['publisher'] = n.publisher.name
		item['title'] = n.title
		item['text'] = n.text
		item['url'] = n.url
		data.append(item)
	return data
#-------------------------------------------------------------------------------
def settingsView(request):

#     	form = ProfileForm( initial={'subscriptions':[ v for v in request.user.profile.subscriptions.all().values_list('id', flat=True)]})
	print ("subS",[ v for v in request.user.profile.subscriptions.all().values_list('id', flat=True)])
	print(request.POST)
#	print(form)
	#User.objects.get(username=)
	if request.method == "POST":
		form = ProfileForm(request.POST)
		if form.is_valid():
			request.user.profile.subscriptions=form.cleaned_data['subscriptions']
	else:
		form = ProfileForm( initial={'subscriptions':[ v for v in request.user.profile.subscriptions.all().values_list('id', flat=True)]})
		news = News.objects.all()
		publishersList = Publisher.objects.all().filter( Q(id__in = news.values('publisher').distinct()))
		choice =  [ (r.id,r.name) for r in publishersList ] 
		form.fields['subscriptions'].choices=choice

	print( request.user.profile.subscriptions.all() )

	return render(request,'userprofile.html',{"form":form})
#-------------------------------------------------------------------------------
def settingsSearches(request):
        return render(request,'searches.html',{})
#-------------------------------------------------------------------------------
def getNewsByRequest(request):
	print ("getNewsByRequest\n\n\n")


	form = SearchForm(request.GET)
	myQuery = ~Q()


	if 'publishers' in request.GET and request.GET['publishers']!="None" and request.GET['publishers']!="" and request.GET['publishers']!="[]":
		myQuery &= Q(publisher_id__in=form['publishers'].value())
	else:
		myQuery &= Q(publisher_id__in=[ r.id for r in request.user.profile.subscriptions.all()])

	if 'startDate' in request.GET and request.GET['startDate']!="None" and request.GET['startDate']!="":
		myQuery &= Q(date__gte=request.GET['startDate'])
	else:
		myQuery &= Q(date__gte=(datetime.date.today()- relativedelta(years=1)).strftime("%Y-%m-%d"))

	if 'endDate' in request.GET and request.GET['endDate']!="None" and request.GET['endDate']!="":
		edate = datetime.datetime.strptime(request.GET['endDate'], "%Y-%m-%d").date() + relativedelta(days=1) 
		myQuery &= Q(date__lte=edate.strftime("%Y-%m-%d"))

	if "text" in request.GET and request.GET['text']!="None" and request.GET['text']!="":
	#	myQuery &= Q(text__search=request.GET['text'])
		myQuery &= Q(search_vector=request.GET['text'])

	print (myQuery)

	return News.objects.all().filter(myQuery)

#-------------------------------------------------------------------------------
def index(request):
	"""
	View function for home page of site.
	"""
	news = getNewsByRequest(request)
	data = request.GET.copy()
	form = SearchForm(data)

	if form.is_valid():
		print("DATA",form.data)
		form.save(request.user)
		form.save_m2m()
		print ("form is valid")
	else:
		print ("form is NOT valid", form.errors)

	subscriptions = [ (r.id,r.name) for r in request.user.profile.subscriptions.all()]

	form.fields['publishers'].choices= subscriptions
	if news.count()>0:
		if 'startDate' not in form or ('startDate' in form and form['startDate'].value == ""):
			form.data.update({'startDate':news.earliest('date').date.strftime("%Y-%m-%d")})

		if 'endDate' not in form or ('endDate' in form and form['endDate'].value == ""):
			form.data.update({'endDate':news.latest('date').date.strftime("%Y-%m-%d")})

	info = dict()
	info['nPublishers'] = news.values('publisher').distinct().count()
	info['nNews'] = news.count()
	info['nNewsText'] = Quantity(news.count()).render(prec=3)  
	info['nAudio'] = Publisher.objects.all().filter(type="audio").count()

	queryset = news.values("publisher").order_by("publisher").annotate(count = Count('publisher') )

	urlDict = dict()
	for q in queryset:
		myRequest = request.GET.copy()
		myRequest.update({"publishers":q['publisher']})
		urlDict[q['publisher']] = urllib.parse.urlencode(myRequest)
#	print (urlDict)
	donutChart = [{"label": Publisher.objects.get(id=q['publisher']).name, "value":q["count"], "url":urlDict[q['publisher']]} for q in queryset]


	publishers = Publisher.objects.all().filter( Q(id__in = news.values('publisher').distinct()))


	queryset = news.values("publisher").annotate(day=TruncMonth('date') )


	dateList =[q['day'].strftime("%Y-%m-%d") for q in queryset.values("day").distinct().order_by("-day")]
	dateDicts = {p.shortName:{ n['day'].strftime("%Y-%m-%d"):n['count'] for n in queryset.filter(publisher=p.id).values("day").distinct().order_by("-day").annotate(count = Count('publisher')) } for p in publishers}

	histogramsData = [ {  "date":d, "data":{ k:(dateDicts[k][d] if d in dateDicts[k] else 0) for k in dateDicts.keys()}  }  for d in dateList] 
	histogramsLabels = [p.shortName for p in publishers]

#	return render(request,'index.html',{"form":form, "info":info, "donutChart":{}, "histogram": {}, "histogramsLabels":{}})
	return render(request,'index.html',{"form":form, "info":info, "donutChart":donutChart, "histogram": histogramsData, "histogramsLabels":histogramsLabels})
#-------------------------------------------------------------------------------
def publisherList(request, type="all"):
	form = SearchForm(request.GET)

	typeQuery = ~Q()
	if type!="all":
		typeQuery = Q(type=type)


	news = getNewsByRequest(request)
	publishers = Publisher.objects.all().filter( Q(id__in = news.values('publisher').distinct()) & typeQuery)


	for p in publishers:
		newsTemp = news.filter(publisher=p).order_by("date")
		p.news = newsTemp.count()
		p.date = 0
		if p.news>0:
			p.date = newsTemp[0].date.date()
		else:
			p.date = "-"

	myRequest=request.GET.copy()
	if 'publishers' in myRequest:
		del myRequest['publishers']

	return render(request,'publisherList.html',{"form":form, "publishers":publishers, "queryurl":urllib.parse.urlencode(myRequest)})

#-------------------------------------------------------------------------------
def newsList(request, publisherShortName="all"):
        form = SearchForm(request.GET)

        return render(request,'newsList.html',{"form":form})
#-------------------------------------------------------------------------------
def wsAudioList(request):
	
	data = dict()
	print("wsAudioList", request.GET)

	startDate = dateutil.parser.parse(request.GET['startdate']).strftime('%s')
	endDate = dateutil.parser.parse(request.GET['enddate']).strftime('%s')

	print ("STARTDATE", startDate)
	audioList = getAudiosList(request, request.GET['publisher'], startDate, endDate)
#	audioList = getAudiosList(request, 'RadioFormula1041', '1512158400', '1512396000')
	print ("audioList", audioList)
	return HttpResponse(json.dumps(audioList), content_type="application/json")

#-------------------------------------------------------------------------------
def wsSearchList(request):

	searches = Search.objects.all().filter(user=request.user)

	data = dict()
	data['data']=[[s.text, "*" if s is None else s.startDate.strftime('%Y-%m-%d'), "*" if s is None else s.endDate.strftime('%Y-%m-%d'), ','.join([ sub.shortName for sub in s.publishers.all()])] for s in searches]
	data['recordsTotal'] = searches.count()
	data['recordsFiltered'] = searches.count()

	return HttpResponse(json.dumps(data), content_type="application/json")

#-------------------------------------------------------------------------------
def wsNewsList2(request):
	news = getNewsByRequest(request)

	data = [{"id":n.id, "publisher":n.publisher.name, "text":n.text, "date":n.date.strftime('%Y-%m-%d')} for n in news]
	return HttpResponse(json.dumps(data), content_type="application/json")
#-------------------------------------------------------------------------------
def wsNewsList(request):#, publisherShortName="all"):

	print (request.GET)
	columns = ['title', 'url', 'date']
	order = dict()
	order["asc"]=""
	order["desc"]="-"
	orderBy = columns[ int(request.GET["order[0][column]"]) ]
	direction = order[request.GET["order[0][dir]"]]

	startDate = datetime.datetime(1950,1,1,0,0,0)
	endDate = datetime.datetime.today()

	request.GET = request.GET.copy()

	if 'ajaxPublishers[]' in request.GET:
		request.GET.setlist('publishers', request.GET.getlist('ajaxPublishers[]'))
		del request.GET['ajaxPublishers[]']

	news = getNewsByRequest(request).order_by(direction+orderBy)

	if 'search[value]' in request.GET and request.GET['search[value]'] != "":
		search = request.GET['search[value]']
		news = news.filter(text__icontains=search)

	data = dict()
	data['data']=list()
	data['recordsTotal'] = news.count()
	data['recordsFiltered'] = news.count()

	paginator = Paginator(news, request.GET['length'])
	page = (int(request.GET['start'])/int(request.GET['length']))+1

	try:
		news = paginator.page(page)
	except PageNotAnInteger:
		news = paginator.page(1)
	except EmptyPage:
        	news = paginator.page(paginator.num_pages)

	for n in news:
		row = list()
		row.append('<a href="'+reverse('news-details', args =(n.id,) )+ "?"+ request.GET.urlencode() +'">'+ n.title+ '</a>')
		row.append('<a href="'+n.url+'" target="blank">'+n.publisher.shortName+'</a>')
		row.append(n.date.strftime("%Y-%m-%d"))
		data['data'].append(row)

#	print request.GET
	return HttpResponse(json.dumps(data), content_type="application/json")
#-------------------------------------------------------------------------------
def newsDetails(request, newsId):
	form = SearchForm(request.GET)
	news = News.objects.get(id=newsId)

#	news.text = news.text.replace(request.GET['text'], "<b>"+request.GET['text']+"</b>")

	return render(request,'newsDetails.html',{"form":form,"news":news})
#-------------------------------------------------------------------------------
def wsGraphs(request):
	data=dict()
	if request.GET['type']=="histogram":
		data = 0;
	return HttpResponse(json.dumps(data), content_type="application/json")
#-------------------------------------------------------------------------------
def wsDownloadNews(request):
	news = getNewsByRequest(request)

	s = StringIO.StringIO()		# Open StringIO to grab in-memory ZIP contents	
	zf = zipfile.ZipFile(s, "w")	# The zip compressor
	zf.writestr("setting.txt", json.dumps(request.GET))
	data = news2JSON(news);

	if request.GET['format']=="JSON":
		zf.writestr("data.json", json.dumps(data))

	if request.GET['format']=="CSV":
		csvString = StringIO.StringIO()	
		writer = csv.writer(csvString,quoting=csv.QUOTE_ALL)#, fieldnames=[k for k in data[0]])
#		writer.writeheader()
		for d in data:
			row = [ d[k].encode('utf-8') for k in d ]
			writer.writerow( row )
		zf.writestr("data.csv", csvString.getvalue())


	zf.close()
	response = HttpResponse(s.getvalue(), content_type="application/x-zip-compressed")
	response['Content-Disposition'] = 'attachment; filename="news_'+ str(int(time.time()))+'.zip"'
	return response

#-------------------------------------------------------------------------------
def audioList(request):
	form = SearchForm(request.GET)

	publishers = audioTime.objects.all().filter(minutes__gt=0 ) #type="audio")

	return render(request,'audioList.html',{"form":form, "publishers":publishers})
#-------------------------------------------------------------------------------
def audioPublisher(request, publisher):
	form = SearchForm(request.GET)
	info=dict()

	if Publisher.objects.all().filter(shortName=publisher).count() > 0:
		p =  Publisher.objects.all().filter(shortName=publisher)[0]
	return render(request,'audioPlay.html',{"form":form, "publisher":p})

