
import json
from datetime import timedelta
from django.utils.translation import gettext_lazy as _
from django_resized import ResizedImageField
from django_celery_beat.models import PeriodicTask
from django.dispatch import receiver
from django.utils.text import slugify
from django.utils.safestring import mark_safe
from django.db.models.signals import post_save
from django.db import models
from modules import utils


class DeviceType(models.Model):
    name = models.CharField(_("Nom du capteur"), max_length=64, null=True)
    code = models.SlugField(_("Type de capteur"), help_text=_("Max 16 caractères"), unique=True, max_length=16, null=True, blank=True)

    class Meta:
        ordering = ['name']
        verbose_name = _("Type de capteur")
        verbose_name_plural = _("Types de capteurs")

    def save(self, *args, **kwargs):
        self.code = slugify(self.code)
        super().save(*args, **kwargs)

    def __str__(self):
        return f'{self.name}'


class Device(models.Model):
    label = models.CharField(_("Capteur"), max_length=100, null=True)
    uuid = models.SlugField(_("Uuid"), help_text=_('Uuid iot clef unique'), unique=True, max_length=32, null=True, blank=True)
    device_type = models.ForeignKey(DeviceType, verbose_name=_("Type de capteur"), on_delete=models.CASCADE, null=True, blank=True, )
    index = models.SmallIntegerField(_("Index"), help_text=_("Numéro d'index"), default=0)
    pin_active = models.BooleanField(_("Broche"), help_text=_("Broche active à l'initialisation"), default=True)
    image = ResizedImageField(_("Image"), help_text=_("Image du capteur"), size=[320, 240], upload_to='devices/', null=True, blank=True, default = 'devices/vanne.png')

    task = models.ForeignKey(
        PeriodicTask,
        verbose_name=_("Tâche périodique"),
        help_text=_("Tâche de démarrage périodique de ce capteur (optionnel)"),
        on_delete=models.CASCADE, null=True, blank=False
    )
    lifetime = models.DurationField(_("Durée"), help_text=_("Durée de l'évènement. Jours hh:mm:ss format"), blank=True, null=True, default=timedelta(hours=1, minutes=15))
    heartbeat = models.IntegerField (_("Battement"), help_text=_("Interrogation du capteur en secondes"), default=1)
    active = models.BooleanField(_("Actif"), default=True)

    def image_tag(self):
        return mark_safe(f'<img src="{self.image.url}" style="width: 45px; height:45px;">')
    image_tag.short_description = _("Image")
    image_tag.allow_tags = True


    def to_register(self):
        return dict(
            dev_type=self.device_type.code if self.device_type else 'None',
            index=self.index,
            key=self.uuid,
            label=self.label,
            status=0,
            active=1 if self.pin_active else 0,
        )

    class Meta:
        ordering = ['index', ]
        verbose_name = _("Capteur")
        verbose_name_plural = _("Capteurs")

    @classmethod
    def all_devices(cls):
        return Device.objects.filter(active=True).all().order_by('index')

    @classmethod
    def all_devices_json(cls):
        devices = Device.objects.filter(active=True).all().order_by('index')
        buf = []
        for dev in devices:
            buf.append({
                "uuid": dev.uuid,
                "index": dev.index,
            })
        return json.dumps(buf)

    def save(self, *args, **kwargs):
        if not self.uuid:
            self.uuid = utils.get_device_uuid(12)
        super().save(*args, **kwargs)

    def __str__(self):
        return f'{self.label}'


@receiver(post_save, sender=Device)
def create_device(sender, instance, created, **kwargs):
    name = f'{instance.uuid}'

    t = PeriodicTask.objects.filter(name__exact=name).first()
    if not t:
        p = PeriodicTask.objects.create(
            name=name,
            task='relay status',
            description=_('Pas encore programmé'),
            interval_id=1,
            args=json.dumps([instance.uuid])
        )
        instance.task_id = p.id
        instance.save()
    else:
        PeriodicTask.objects.filter(id=instance.task.id).update(
            name=name,
            args=json.dumps([instance.uuid])
        )
        instance.task.save()
