# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from datetime import datetime, timedelta
import pytz

from django.apps import apps
from django.db import models
from django.db.models.signals import post_save
from django.utils.translation import ugettext_lazy as _
from django_countries.fields import CountryField
from django.core.urlresolvers import reverse

import urllib
from django.conf import settings

TIMEZONES = ((i, i) for i in pytz.all_timezones)

PLACE_TYPES = (
    ('hotel', _('Hotel')),
    ('hostal', _('Hostal')),
    ('apartment', _('Apartment')),
    ('cottage', _('Cottage')),
)

CREDIT_TYPES = (
    ('visa', _('VISA')),
    ('mastercard', _('Master Card')),
)


class Property(models.Model):
    name = models.CharField(max_length=255)
    vat_name = models.CharField(max_length=255, blank=True, null=True)
    short_name = models.CharField(max_length=20)
    slug = models.SlugField()

    address = models.CharField(max_length=255)
    city = models.CharField(max_length=255)
    country = CountryField()

    email_notify = models.EmailField(blank=True, null=True)

    zipcode = models.IntegerField()
    geo_lat = models.FloatField()
    geo_lng = models.FloatField()
    timezone = models.CharField(max_length=100, choices=TIMEZONES)


    features = models.TextField(blank=True, null=True)
    type = models.CharField(max_length=20, choices=PLACE_TYPES, verbose_name="Tipo")

    cif = models.CharField(max_length=100, blank=True, null=True)

    checking_start = models.TimeField()
    checkout_start = models.TimeField()
    checking_end = models.TimeField()
    checkout_end = models.TimeField()

    valid_credit_cards = models.ManyToManyField('ValidCreditCard', related_name='prop', blank=True)

    last_connection = models.DateTimeField(blank=True, null=True)
    last_updated = models.DateTimeField(auto_now=True)

    # conditions en desuso!
    condition_days = models.IntegerField(default=0)
    condition_percent = models.IntegerField(default=0)
    condition_nights = models.IntegerField(default=0)
    deposit_days = models.IntegerField(default=0)
    deposit_percent = models.IntegerField(default=0)
    deposit_nights = models.IntegerField(default=0)
    # fin desuso
    beach_distance = models.IntegerField(default=0, help_text=_("In metters"))

    active = models.BooleanField(default=True)
    wubookcode=models.CharField(max_length=100, blank=True, null=True) 
    #menores: pte en edit property y en la generacion de condiciones!
    children_max_age_free = models.IntegerField(default=1,help_text=_("Maxima edad para niño gratis"))
    children_max_free = models.IntegerField(default=1,help_text=_("Numero maximo de niños gratuitos"))
    children_max_age = models.IntegerField(default=12,help_text=_("Maxima edad para ser cosiderado niño"))
    type2 = models.CharField(max_length=20, choices=PLACE_TYPES,verbose_name="Tipo Adicional",blank=True,null=True)
    def idrooms(self):
        return [str(room.id) for room in self.rooms.all()]

    def razon_social(self):
        if self.vat_name==None:
            return self.name
        else:
            return self.vat_name

    def __unicode__(self):
        return self.short_name

    def room_servs(self):
        servs = []
        for r in self.rooms.all():
            servs += [s.ident for s in r.services.all()]
        # set to make uniques
        return list(set(servs))

    def servs(self):
        return self.web.services.all()

    # return min price based on availability for this property
    def min_price(self):
        try:
            date1 = datetime.now()
            date2 = date1 + timedelta(days=30)
            return min(rid.price for rid in apps.get_model('availability', 'RateId').objects.filter(avail__property_id=self.pk, avail__date__gte=date1, avail__date__lte=date2) if round(rid.price) != 0)
        except Exception, e:
            return 0

    def serialize(self):
        return {
                'name': self.name,
                'short_name': self.short_name,
                'beach_distance': self.beach_distance,
                'slug': self.slug,
                'address': self.address,
                'city': self.city,
                'country': self.country.name,
                'zipcode': self.zipcode,
                'geo_lat': self.geo_lat,
                'geo_lng': self.geo_lng,
                'timezone': self.timezone,
                'features': self.features,
                'type': self.type,
                'cif': self.cif,
                'checking_start': self.checking_start.isoformat(),
                'checkout_start': self.checkout_start.isoformat(),
                'checking_end': self.checking_end.isoformat(),
                'checkout_end': self.checkout_end.isoformat(),
                'valid_credit_cards': [val.name for val in self.valid_credit_cards.all()],
                'last_updated': self.last_updated.isoformat(),
                'web': self.web.serialize(),
                'type2': self.type2,
        }

    def get_absolute_url(self):
        return reverse('property_view',kwargs={'slug': self.slug})

class ValidCreditCard(models.Model):
    name = models.CharField(max_length=20, choices=CREDIT_TYPES)
    def __unicode__(self):
        return self.name




# Property web content

class PropertyService(models.Model):
    name = models.CharField(max_length=255)
    def __unicode__(self):
        return self.name

class PropertyWeb(models.Model):
    prop = models.OneToOneField(Property, related_name="web")
    web_url = models.URLField(blank=True, null=True)
    generic_desc = models.TextField(_('Generic Description'), blank=True, null=True)
    desc = models.TextField(_('Description'))

    transport_info = models.TextField(_('Transport info'), blank=True, null=True)
    additional_info = models.TextField(_('Additional info'), blank=True, null=True)

    taxes = models.TextField(_('Taxes'), blank=True, null=True)
    ranking = models.IntegerField(_('Ranking'), default=0)

    services = models.ManyToManyField(PropertyService, related_name='prop', blank=True)

    #email_notify = models.EmailField(blank=False, null=False)

    twitter = models.CharField(max_length=255, default='', blank=True, null=True)
    facebook = models.CharField(max_length=255, default='', blank=True, null=True)
    instagram = models.CharField(max_length=255, default='', blank=True, null=True)



    # mis preferencias
    # mis dispositivos

    def has_social_networks(self):
        return True if (self.twitter or self.facebook) else False

    def conditions(self):
        values = dict(days=self.prop.condition_days,
                      percent=self.prop.condition_percent,
                      nights=self.prop.condition_nights)
        text = _('Si cancelas o modificas la reserva hasta %(days)s días '
                 'antes de la fecha de llegada, el establecimiento no '
                 'efectuará cargos. Si cancelas o modificas la reserva '
                 'fuera de plazo o no te presentas, el establecimiento '
                 'cargará el %(percent)s de las %(nights)s primeras '
                 'noches.') % values
        return text

    def payment_conditions(self):
        values = dict(days=self.prop.condition_days,
                      percent=self.prop.condition_percent)
        text = _('El establecimiento cargará %(percent)s al menos %(days)s '
                 'días antes de la fecha de la reserva.') % values
        return text

    def serialize(self):
        return {
                'generic_desc': self.generic_desc,
                'desc': self.desc,
                'transport_info': self.transport_info,
                'additional_info': self.additional_info,
                'taxes': self.taxes,
                'ranking': self.ranking,
                'services': [ser.name for ser in self.services.all()]
        }

    # Encuestas
    def puntuacion(self):
        from encuesta.models import Respuesta, Pregunta
        vpregunta = Pregunta.objects.all()[0]
        a = Respuesta.objects.filter(pregunta__id=vpregunta.id, respuesta_customer_fecha_responde_date__isnull=False,
                                     respuesta_eliminada=False, prop__id=self.prop.id)
        total = sum(res.respuesta_media_votos for res in a)
        if len(a) == 0:
            return 0
        tmpavg = total / float(len(a))
        return round(tmpavg, 2)
    def puntuacion100(self):
        from encuesta.models import Respuesta, Pregunta
        vpregunta = Pregunta.objects.all()[0]
        a = Respuesta.objects.filter(pregunta__id=vpregunta.id, respuesta_customer_fecha_responde_date__isnull=False,
                                     respuesta_eliminada=False, prop__id=self.prop.id)
        total = sum(res.respuesta_media_votos for res in a)
        if len(a) == 0:
            return 0
        tmpavg = total / float(len(a))
        cadena = (str)( round(tmpavg, 2)*100/5)
        return cadena
    def valoraciones(self):
        from encuesta.models import Respuesta, Pregunta
        vpregunta = Pregunta.objects.all()[0]
        a = Respuesta.objects.filter(respuesta_customer_fecha_responde_date__isnull=False,
                                     respuesta_eliminada=False, prop__id=self.prop.id)
        if a:
            return  len(a)
        else:
            return 0

    def valoracionesmedias(self):
        from encuesta.models import Respuesta, Pregunta
        vpregunta = Pregunta.objects.all()[0]
        a = Respuesta.objects.filter(pregunta__id=vpregunta.id, respuesta_customer_fecha_responde_date__isnull=False,
                                     respuesta_eliminada=False, prop__id=self.prop.id)
        total1 = sum(res.votos1 for res in a)
        total2 = sum(res.votos2 for res in a)
        total3 = sum(res.votos3 for res in a)
        total4 = sum(res.votos4 for res in a)
        total5 = sum(res.votos5 for res in a)
        cuantos = len(a)
        if cuantos > 0:
            v={1:total1/cuantos,2:total2/cuantos,3:total3/cuantos,4:total4/cuantos,5:total5/cuantos}
        else:
            v={1:0,2:0,3:0,4:0,5:0}
        return v
    def valoracionesmediasv1(self):
        from encuesta.models import Respuesta, Pregunta
        vpregunta = Pregunta.objects.all()[0]
        a = Respuesta.objects.filter(pregunta__id=vpregunta.id, respuesta_customer_fecha_responde_date__isnull=False,
                                     respuesta_eliminada=False, prop__id=self.prop.id)
        total1 = sum(res.votos1 for res in a)
        cuantos = len(a)
        cadena = (str)(round((total1 / cuantos) * 100 / 5, 2))
        return cadena
    def valoracionesmediasv2(self):
        from encuesta.models import Respuesta, Pregunta
        vpregunta = Pregunta.objects.all()[0]
        a = Respuesta.objects.filter(pregunta__id=vpregunta.id, respuesta_customer_fecha_responde_date__isnull=False,
                                     respuesta_eliminada=False, prop__id=self.prop.id)
        total1 = sum(res.votos2 for res in a)
        cuantos = len(a)
        cadena = (str)(round((total1 / cuantos) * 100 / 5, 2))
        return cadena
    def valoracionesmediasv3(self):
        from encuesta.models import Respuesta, Pregunta
        vpregunta = Pregunta.objects.all()[0]
        a = Respuesta.objects.filter(pregunta__id=vpregunta.id, respuesta_customer_fecha_responde_date__isnull=False,
                                     respuesta_eliminada=False, prop__id=self.prop.id)
        total1 = sum(res.votos3 for res in a)
        cuantos = len(a)
        cadena = (str)(round((total1 / cuantos) * 100 / 5, 2))
        return cadena
    def valoracionesmediasv4(self):
        from encuesta.models import Respuesta, Pregunta
        vpregunta = Pregunta.objects.all()[0]
        a = Respuesta.objects.filter(pregunta__id=vpregunta.id, respuesta_customer_fecha_responde_date__isnull=False,
                                     respuesta_eliminada=False, prop__id=self.prop.id)
        total1 = sum(res.votos4 for res in a)
        cuantos = len(a)
        cadena = (str)(round((total1 / cuantos) * 100 / 5, 2))
        return cadena
    def valoracionesmediasv5(self):
        from encuesta.models import Respuesta, Pregunta
        vpregunta = Pregunta.objects.all()[0]
        a = Respuesta.objects.filter(pregunta__id=vpregunta.id, respuesta_customer_fecha_responde_date__isnull=False,
                                     respuesta_eliminada=False,prop__id=self.prop.id)
        total1 = sum(res.votos5 for res in a)
        cuantos = len(a)
        cadena = (str)(round((total1 / cuantos) * 100 / 5, 2))
        return cadena
    def valoraciondestacada(self):
        vc = self.valoracionesmedias()
        from encuesta.models import  Pregunta
        maximo=0
        while vc:
            key, value = vc.popitem()
            if value > maximo:
                maximo=key

        vpregunta = Pregunta.objects.all()[0]
        lp=(vpregunta.pregunta_texto_al_mejor_parametro_1_text, vpregunta.pregunta_texto_al_mejor_parametro_2_text,
            vpregunta.pregunta_texto_al_mejor_parametro_3_text, vpregunta.pregunta_texto_al_mejor_parametro_4_text,
            vpregunta.pregunta_texto_al_mejor_parametro_5_text)
        return lp[maximo -1 ]
    def mejoresrespuestasconcomentarios(self):
        from encuesta.models import Respuesta, Pregunta
        vpregunta = Pregunta.objects.all()[0]
        a = Respuesta.objects.filter(pregunta__id=vpregunta.id, respuesta_customer_fecha_responde_date__isnull=False,
                                     respuesta_eliminada=False, prop__id=self.prop.id, respuesta_media_votos__gte=4, respuesta_comentario_text__isnull=False)[:4]
        
        return a
    def __unicode__(self):
        return '%s Web' % self.prop


class PropertyWebContact(models.Model):
    web = models.ForeignKey(PropertyWeb, related_name='contacts')
    name = models.CharField(max_length=255)
    phone = models.CharField(max_length=20, blank=True, null=True)
    email = models.EmailField(blank=True, null=True)

    def __unicode__(self):
        return self.name


class PropertyWebPhoto(models.Model):
    web = models.ForeignKey(PropertyWeb, related_name='photos')
    photo = models.ImageField(upload_to='photos')
    order = models.IntegerField(blank = True, null = True)
    
    class Meta:
        ordering = ('order',)


class ExtraService(models.Model):
    prop = models.ForeignKey(Property, related_name='extras')
    title = models.CharField(max_length=255)
    photo = models.ImageField(upload_to='extras')
    desc = models.TextField()

    def __unicode__(self):
        return '%s - %s' % (self.prop, self.title)



### Signals ###

from rate.models import Rate, Eating

def add_rate(property=None, name='', type='general', negative_percentage=0.0, eat=None, nrp=0.0):
    r = Rate(prop=property, name=name, type=type, negative_percentage=negative_percentage, non_refundable_percentage=nrp)
    r.save()
    if eat:
        r.eatings.add(eat)
        r.save()

def add_default_rates(sender, instance, created, *args, **kwargs):
    if created:
      none_eat = None
      breakfast_eat = None
      if Eating.objects.count() > 0:
          try:
              breakfast_eat = Eating.objects.get(name='breakfast')
              try:
                  none_eat = Eating.objects.get(name='none')
              except:
                  none_eat = None
          except:
              breakfast_eat = None
      try:
          add_rate(property=instance, name="Standard Rate", eat=none_eat)
          add_rate(property=instance, name="Breakfast Included", eat=breakfast_eat)
          add_rate(property=instance, name="Non refundable", type="non-refundable", eat=none_eat, negative_percentage=10.0, nrp=50.0)
          add_rate(property=instance, name="Non refundable Breakfast Included", type="non-refundable", eat=breakfast_eat, negative_percentage=10.0, nrp=50.0)
      except Exception, e:
          pass

post_save.connect(add_default_rates, sender=Property)

