from django.conf import settings
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.core.cache import cache
from django.db import models
from django.utils import timezone
from telegram import Bot

from feeds.tasks import execute_feed


class Feed(models.Model):
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    title = models.CharField(max_length=32)
    chat_id = models.CharField(max_length=33)
    check_interval = models.DurationField(help_text='in seconds')
    last_check = models.DateTimeField(null=True, blank=True)
    last_id = models.JSONField(null=True, blank=True)

    config_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    config_id = models.PositiveIntegerField()
    config = GenericForeignKey('config_type', 'config_id')

    @property
    def lock_key(self):
        return 'feed-{}-lock'.format(self.pk)

    @property
    def locked(self):
        return bool(cache.get(self.lock_key))

    def run_check(self):
        if self.locked:
            return False
        if self.last_check and timezone.now() < self.last_check + self.check_interval:
            return False

        cache.set(self.lock_key, 1, timeout=60)
        execute_feed.apply_async(args=(self.pk,), shadow=str(self))
        return True

    def __str__(self):
        return f'#{self.pk} {self.title}'

    class Meta:
        unique_together = ('config_type', 'config_id')


class FeedModuleConfig(models.Model):
    _feeds = GenericRelation(Feed, content_type_field='config_type', object_id_field='config_id')

    MODULE_NAME = '<Not set>'

    @property
    def feed(self):
        return self._feeds.get()

    @property
    def content_type(self):
        return ContentType.objects.get_for_model(self.__class__)

    def execute(self, bot: Bot, chat_id, last_id):
        raise NotImplementedError()

    class Meta:
        abstract = True
