import datetime
import json
from django.db import models
from django.utils import timezone


class Cron(models.Model):
    # request data and response_data store as TextField, incase got return or send somethings in string so cant store in jsonField
    command = models.TextField(null=True, blank=True)
    extra_data = models.TextField(null=True, blank=True)
    start = models.BooleanField(default=False)
    success = models.BooleanField(default=False)
    complete = models.BooleanField(default=False)
    skip = models.BooleanField(default=False, db_comment="if this is true, when do cron running checking skip this row, and add 1 more record with skip = 1")
    start_at = models.DateTimeField(null=True, blank=True)
    complete_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'cron'

    @staticmethod
    def cron_start(command):
        cron = Cron.objects.create(
            command=command,
            start=True,
            start_at=timezone.now()
        )
        return cron

    @staticmethod
    def cron_end(cron,success,extra_data = None):
        if success:
            cron.success = True
        cron.complete = True
        cron.extra_data = extra_data
        cron.complete_at = timezone.now()
        cron.save()
        return cron

    @staticmethod
    def check_cron_processing(command):
        # if a shor cron run 30minute, also possible is timeout already, can ignore those record, so can prevent deadlock problem
        estimate_timeout = timezone.now() - datetime.timedelta(minutes=30)
        # when latest cron is not skip record, already start and complete=False, means not yet finish, will skip
        cron = Cron.objects.filter(command=command, skip=False, start=True,complete=False,start_at__gte=estimate_timeout).order_by('-start_at').first()
        if cron:
            skip_cron = Cron.objects.create(
                command=command,
                extra_data=f"Skipped: Previous cron (ID: {cron.id}) is still processing.",
                skip=True,
                start_at=timezone.now(),
                complete_at = timezone.now()
            )
            return False
        return True
