import random

from crum import get_current_user
from django.db import models
from jdatetime import datetime

from apps.authentication import models as auth_models
from apps.authorization import models as authoriz_models
from apps.core.models import BaseModel
from apps.tag.tools import tag_code_serial_scanning


class Tag(BaseModel):
    country_code = models.IntegerField(default=364)
    static_code = models.IntegerField(default=0)
    ownership_code = models.IntegerField(default=0)
    species_code = models.IntegerField(default=0)
    serial = models.CharField(max_length=8)
    tag_code = models.CharField(max_length=20, unique=True, null=True)
    organization = models.ForeignKey(
        auth_models.Organization,
        on_delete=models.CASCADE,
        related_name='tag_organization',
        null=True
    )
    status_choices = (
        ('F', 'Free'),
        ('A', 'Assigned')
    )
    status = models.CharField(max_length=20, default="F")

    def __str__(self):
        return f'{self.id}-{self.tag_code}'

    def save(self, *args, **kwargs):
        # set zeros for serial
        if not self.tag_code:
            self.serial = tag_code_serial_scanning(self.serial)
        if not self.tag_code:
            # set total tag code
            self.tag_code = f"{self.country_code}" \
                            f"{self.static_code}" \
                            f"{self.ownership_code}" \
                            f"{self.species_code}" \
                            f"{self.serial}"
        if not self.organization:
            # set user organization for tag
            user = get_current_user()
            self.organization = (
                authoriz_models.UserRelations.objects.select_related(
                    'organization'
                ).get(
                    user=user
                )).organization

        super(Tag, self).save(*args, **kwargs)


class TagAssignment(BaseModel):
    organization = models.ForeignKey(
        auth_models.Organization,
        on_delete=models.CASCADE,
        related_name='tag_assignment_org',
        null=True
    )
    document = models.CharField(max_length=150, null=True)
    serial_sender_part = models.IntegerField(default=0)
    serial_recipient_part = models.IntegerField(default=0)
    serial_date_part = models.CharField(max_length=3, null=True)
    serial_random_part = models.IntegerField(default=0)
    serial = models.CharField(max_length=20, null=True)
    status_choices = (
        ('A', 'Accept'),
        ('W', 'Waiting'),
        ('C', 'Cancel'),
        ('E', 'Exited'),
    )
    status = models.CharField(max_length=1, choices=status_choices, default="W")

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

    def save(self, *args, **kwargs):
        self.serial_recipient_part = self.organization.type.code
        self.serial_date_part = str(
            datetime.now().year
        )[3] + str(
            datetime.now().month
        )
        self.serial_random_part = random.randint(1000, 9999)
        if not self.serial:
            self.serial = f"" \
                          f"{self.serial_sender_part}" \
                          f"{self.serial_recipient_part}" \
                          f"{self.serial_date_part}" \
                          f"{self.serial_random_part}"
        super(TagAssignment, self).save(*args, **kwargs)


class AllocatedTags(BaseModel):
    tag = models.ForeignKey(
        Tag,
        on_delete=models.CASCADE,
        related_name='allocated_tags',
        null=True
    )
    assignment = models.ForeignKey(
        TagAssignment,
        on_delete=models.CASCADE,
        related_name='assigned_allocated_tags',
        null=True
    )
    species_code = models.IntegerField(default=0)
    status_choices = (
        ('A', 'Accept'),
        ('W', 'Waiting'),
        ('C', 'Cancel')
    )
    status = models.CharField(max_length=1, default='W')

    def __str__(self):
        return f'{self.tag.tag_code}-{self.assignment.serial}'

    def save(self, *args, **kwargs):
        super(AllocatedTags, self).save(*args, **kwargs)


class TemporaryTags(BaseModel):
    tag = models.CharField(max_length=150, null=True)
    herd_code = models.CharField(max_length=150, null=True)
    gender = models.CharField(max_length=150, null=True)
    birthdate = models.CharField(max_length=150, null=True)
    type = models.CharField(max_length=150, null=True)
    agent_code = models.CharField(max_length=150, null=True)
    agriculture_unique_id = models.CharField(max_length=150, null=True)
    keeper_agent = models.CharField(max_length=150, null=True)
    registerer_user = models.CharField(max_length=150, null=True)
    sync_status = models.CharField(max_length=150, null=True)

    def save(self, *args, **kwargs):
        super(TemporaryTags, self).save(*args, **kwargs)
