from django.shortcuts import render
from django.core.mail import send_mail
from django.core.mail import SafeMIMEText

from django.core.mail import EmailMultiAlternatives
from django.template.loader import get_template
from django.template import Context
from django.template import engines, TemplateSyntaxError
from datetime import date
from uuid import uuid4,UUID
import json
from datetime import datetim
import re

from django.db.models import Sum
#from .templatetags.commtags import *
from django.shortcuts import render

from .models import *
from .forms import *

from config.views import *
from azienda.views import *
from utente.views import *
from documento.views import *

def template_from_string(template_string, using=None):

  """
  Convert a string into a template object,
  using a given template engine or using the default backends 
  from settings.TEMPLATES if no engine was specified.
  This function is based on django.template.loader.get_template, 
  but uses Engine.from_string instead of Engine.get_template.
  """

  chain = []
  engine_list = engines.all() if using is None else [engines[using]]
  for engine in engine_list:
    try:
      return engine.from_string(template_string)
    except TemplateSyntaxError as e:
      chain.append(e)
  raise TemplateSyntaxError(template_string, chain=chain)

class ServizioMail:
  def __init__(self,debug=False):
    self._from_ = getConfigurazione('default_mail_from')
    self._to_ = []
    self._to = {}
    self.debug = debug
    self.soggetto = ""
    self.corpo_testo = ""
    self.corpo_html = ""
    self.set_data()
    self.json = None

  def set_mailfrom(self,mail_from):
    self._from_ = mail_from
    if self.debug: print('mail_from',self._from_)

  def set_listadestinatari(self,lista=[]):
    self._to_ = []
    self.add_listadestinatari(lista)
    if self.debug: print('lista destinatari',self._to_)

  def set_rcptto(self,lista=[]):
    self.set_listadestinatari(lista)

  def add_listadestinatari(self,mail=None):
    if self.debug: print('type mail:',type(mail))
    if mail:
      if type(mail) == list:
        for i in mail:
          self._to_.append(i)
        return
      self._to_.append((mail))
      if self.debug: print('lista destinatari',self._to_)

  def add_to(self,mail=None):
    self.add_listadestinatari(mail)

  def set_soggetto(self,soggetto=""):
    self.soggetto = soggetto

  def set_oggetto(self,oggetto="",html=False):
    self.oggetto = oggetto
    if self.debug: print('set_oggetto html:',html)
    self.html = html

  def set_data(self,data={}):
    self.data = data
    #print('data',self.data)

  def set_json(self,data={}):
    self.json = json.dumps(data)
    if self.debug:  print('json:',self.json)
  def send(self):

    # normalizza i destinatari (uno solo, non ripetuti)
    if self.debug: print('self._to_',self._to_)

    for i in self._to_:
      self._to[i] = i
 
    self._to_complete = [ x for x in self._to.values() ]
    if self.debug: print("destinatari:",self._to_complete)
 
    #rendering del soggetto
    soggetto = template_from_string(self.soggetto)
    soggetto_render = soggetto.render(self.data)
    if self.debug: print("soggetto",soggetto)

    oggetto = template_from_string(self.oggetto)
    oggetto_render = None
    try:
      oggetto_render = oggetto.render(self.data)
    except TemplateSyntaxError as tse:
      print('Errore nel Template')
      print(tse)

    if oggetto_render:
      if self.debug: print('oggetto render',oggetto_render)
      ora = datetime.now.strftime("%d/%m/%Y, %H:%M:%S")

      for tt in self._to_complete:
        ttl = [tt,]
        msg = None
        if self.debug: print('richiesta html::',self.html)
        if self.html: 
          msg=EmailMultiAlternatives(soggetto_render, oggetto_render, self._from_, ttl)
          msg.attach_alternative(oggetto_render, "text/html")
        else: msg=EmailMultiAlternatives(soggetto_render, oggetto_render, self._from_, ttl)

        if self.json:
          msg.attach_alternative(self.json,'text/json')

        msg.send()

def welcome(request):
  '''
  punto di ingresso.
  vengono mostrati tutti i modelli presenti presenti
  '''
  print('__name__',__name__,'welcome')
  data = dict()
  data['HeaderTitle'] = getConfig('HeaderTitle')

  if not 'AziendaId' in request.session:
    print('manca azienda')
    return HttpResponseRedirect(reverse("login:start"))
  else:
    data['AziendaId'] = request.session['AziendaId']
  print("Azienda rilevata",data['AziendaId'])

  if not 'AdminId' in request.session or 'UserId' in request.session:
    print("Non rilevo presensa UserId e AdminId in request.session")
    return HttpResponseRedirect(reverse("login:start"))
  else:
    data['AdminId'] = request.session['AdminId']

  if 'UserId' in request.session:
    data['UserId'] = request.session['UserId']

  #filtro:
  # selezionare tutti gli utenti per AziendaId
  data['admin'] = User.objects.get(pk=data['AdminId'])

  data['azienda'] = Azienda.objects.get(pk=data['AziendaId'])
  data['comunicazione'] = data['azienda'].comunicazione_set.all()
  #data['comm'] = data['azienda'].comm
  print(data)

  if request.method == "POST":
    print('Richiesta effettuata')
    print(request.POST)

    if 'Ritorna' in request.POST:
      return HttpResponseRedirect(reverse("azienda:welcome"))

    if 'Nuovo' in request.POST:
      del request.session['ComId']
      return HttpResponseRedirect(reverse("comunicazione:edit"))

    if 'edit' in request.POST:
      request.session['ComId'] = request.POST.get('edit')
      print('ComId',request.session.get('ComId'))
      return HttpResponseRedirect(reverse("comunicazione:edit"))
    
  return render(request,'comunicazione.welcome.html',data)

def edit(request):
  print('__name__',__name__,'edit')
  data = dict()
  data['HeaderTitle'] = getConfig('HeaderTitle')

  if not 'AziendaId' in request.session:
    print('manca azienda')
    return HttpResponseRedirect(reverse("login:start"))

  data['AziendaId'] = request.session['AziendaId']
  print("Azienda rilevata",data['AziendaId'])

  data['azienda'] = Azienda.objects.get(pk=data['AziendaId'])

  if not 'AdminId' in request.session or 'UserId' in request.session:
    print("Non rilevo presensa UserId e AdminId in request.session")
    return HttpResponseRedirect(reverse("login:start"))

  data['AdminId'] = request.session['AdminId']
  print(data)

  if 'UserId' in request.session:
    data['UserId'] = request.session['UserId']

  comunicazione = Comunicazione()

  if 'ComId' in request.session:
    ComId = request.session.get('ComId')
    print('trovato ComId',ComId)
    comunicazione = Comunicazione.objects.get(pk=ComId)

  if request.method == 'POST':
    print('richiesta effettuata')
    if 'Ritorna' in request.POST:
      return HttpResponseRedirect(reverse("comunicazione:welcome"))

    fd = formDocumento(request.POST)
    if fd.is_valid():
      print('documento valido')
      comunicazione.mittente = fd.cleaned_data.get('mittente')
      comunicazione.soggetto = fd.cleaned_data.get('soggetto')
      comunicazione.corpo = fd.cleaned_data.get('corpo')
      comunicazione.azienda = data['azienda']
      comunicazione.save()
    else:
      print('documento non valido')
    data['documento'] = formDocumento(request.POST)
  else:
    print('post non valido')
    tmp = dict()
    if len(data['azienda'].mail):
      print('azienda contiene email',data['azienda'].mail)
      tmp['mittente'] = data['azienda'].mail
    else:
      print('azienda non contiene email, prendo default',getConfig("DefaultEmail"))
      tmp['mittente'] = getConfig("DefaultEmail")

    tmp['soggetto'] = comunicazione.soggetto
    tmp['corpo'] = comunicazione.corpo
    data['documento'] = formDocumento(tmp)
    print(data) 
  return render(request,'comunicazione.edit.html',data)


  '''

  def edit(request):
  AdminId = request.session['AdminId']

  data={}
  data['HeaderTitle'] = getConfig('HeaderTitle')
  data['admin' ] = User.objects.get(pk=AdminId)

  if request.method == "POST":
    print("Richiesta creazione nuova azienda")
    nuovaazienda = formAzienda(request.POST)
    if nuovaazienda.is_valid():
      print("il form e' valido",request.POST)
      azienda = Azienda()
      azienda.nome = nuovaazienda.cleaned_data.get('nome')
      azienda.mail = nuovaazienda.cleaned_data.get('mail')
      azienda.partitaiva = nuovaazienda.cleaned_data.get('partitaiva')
      azienda.save()
      request.session['AziendaId'] = azienda.id
      assegnazione = Assegnazione()
      assegnazione.azienda=azienda
      assegnazione.user=User.objects.get(pk=AdminId)
      assegnazione.save()
      return HttpResponseRedirect(reverse('azienda:welcome'))
    else:
      print("form non valido")
      data['azienda'] = formAzienda(request.POST)

  else: #non è un post
    print("Non è un post")
    formAziendaField = formAzienda()
    data['azienda'] = formAziendaField

  return render(request,'azienda.edit.html',data)



  #filtro:
  # selezionare tutti gli utenti per AziendaId
  admin = User.objects.get(pk=data['AdminId'])
  data['admin'] = admin
  azienda = Azienda.objects.get(pk=data['AziendaId'])
  data['azienda'] = azienda
  utenti = Utente.objects.filter(azienda = azienda)
  data['utenti'] = utenti

  if request.method == 'POST':

    if 'ritorna' in request.POST:
      return HttpResponseRedirect(reverse("azienda:welcome"))

    if 'DeleteDocument' in request.POST:
      print('Richiesta cancellazione Documento',request.POST)
      documento = request.POST['DeleteDocument']  # perche' lo considera una lista e non un singolo valore?
      print('richiesta cancellazione documento:',documento)
      try:
        d = Documento.objects.get(pk=documento)
        delete_file(d)  #rimozione fisica del documento
        setLog(5,documento,admin)
        d.delete()
      except Documento.DoesNotExist as dne:
        print('il documento non esiste')

    filecaricati = AdminUpload(request.POST,request.FILES)

    if filecaricati.is_valid():

      print('record filecaricati validi')
      if 'indice' in filecaricati.cleaned_data and filecaricati.cleaned_data.get('indice'):
        fileindice = filecaricati.cleaned_data.get('indice')
        print('presente file indice',fileindice)
        save_and_load_file_indice(request,fileindice,azienda)

      if 'allegati' in filecaricati.cleaned_data and filecaricati.cleaned_data.get('allegati'):
        print('presenti documenti da allegare')
        listadocumenti = filecaricati.cleaned_data['allegati']
        print(listadocumenti)
        print(type(azienda))
        print(azienda.id)
        listaok,listanotok = save_and_load_file_multiple(listadocumenti,request,utenti,azienda,filecaricati.cleaned_data['descrizione'])
        data['listaok'] = listaok
        data['listanotok'] = listanotok

  ElencoDocumentiPerAzienda = Documento.objects.filter(azienda=azienda).order_by("utente__nome","documento")
  data['ElencoDocumentiPerAzienda'] = ElencoDocumentiPerAzienda
  print("Numero documenti associati",len(ElencoDocumentiPerAzienda))
  '''


