from django.db import models
from django.utils import timezone
from dateutil.relativedelta import relativedelta
from datetime import date

from . import constants as dec_constants

# Create your models here.

class BaseModel(models.Model):
    """models to store details of base model for other models"""
    created_by = models.IntegerField( null=True, blank=True)
    created_on = models.DateTimeField(auto_now_add=True, null=True)
    updated_by = models.IntegerField(null=True, blank=True)
    updated_on = models.DateTimeField(auto_now=True, null=True)
    is_deleted = models.BooleanField(default=False)
    deleted_by = models.IntegerField(null=True, blank=True)
    deleted_on = models.DateTimeField(null=True, blank=True)

    class Meta:
        """Meta class for the above model."""

        abstract = True
        ordering = ('-created_on',)

    def delete(self, *args, **kwargs):
        """Soft delete instead of actual delete"""
        self.del_flag = 1
        self.save(update_fields=['is_deleted'])


class Company(BaseModel):
    """model to details of company"""
    company_name = models.CharField(max_length=500, default='', blank=True, null=True)
    ship_to = models.CharField(max_length=500, default='', blank=True, null=True)
    address_line1 = models.CharField(max_length=500, default='', blank=True, null=True)
    address_line2 = models.CharField(max_length=500, default='', blank=True, null=True)
    address_line3= models.CharField(max_length=500, default='', blank=True, null=True)
    latest_expiry = models.DateField(blank=True, null=True)

    class Meta:
        db_table = 'Company'

    def __str__(self):
        return f'{self.id}: {self.company_name}'


class EUDeclaration(BaseModel):
    """model to details of details of eu declarations"""
    company = models.ForeignKey(
        Company, on_delete=models.SET_NULL, null=True, blank=True, related_name='declarations'
    )
    product_name = models.CharField(max_length=500, default='', blank=True, null=True)
    start_date = models.DateField(default=None, null=True)
    expiry_date = models.DateField(default=None, null=True)
    status = models.CharField(max_length=100, default='Active', blank=True, null=True)
    document_id = models.IntegerField(null=True, blank=True)

    class Meta:
        db_table = 'EUDeclaration'

    def __str__(self):
        return f'{self.id}: {self.product_name}- {self.company.company_name}- {self.expiry_date}'

    def save(self, *args, **kwargs):
        """Override save to set expiry_date = start_date + 1 year"""
        if self.start_date:
            self.expiry_date = self.start_date + relativedelta(years=1)
            company = self.company
            declarations = company.declarations.all().order_by('expiry_date')
            if declarations:
                upcoming_date = declarations[0].expiry_date
                self.company.latest_expiry = upcoming_date
            else:
                self.company.latest_expiry = None
            self.company.save()

        super().save(*args, **kwargs)

    def get_declaration_status(self):
        """function to update status depending on expiry"""

        if self.status==dec_constants.REQUEST_SEND:  # if status is request sent, change it once it is renewed
            return self.status

        expiry_date = self.expiry_date
        today = date.today()

        days_left = (expiry_date - today).days

        if days_left < 1:
            declaration_status = 'Expired'
        else:
            declaration_status = 'Active'
        self.status = declaration_status
        self.save()
        return declaration_status
    
    def update_declaration_history(self, request_user_id=None):
        """function to update history of declaration"""
        history, created = DeclarationActionHistory.objects.get_or_create(declaration=self)
        if request_user_id:
            history.request_sent_by = request_user_id
            history.requested_on = timezone.now()
        history.save()

        return history


class DeclarationDocument(BaseModel):
    """model to store details of documents"""
    declaration = models.ForeignKey(
        EUDeclaration, on_delete=models.SET_NULL, null=True, blank=True, related_name='documents'
    )
    file_path = models.FileField(upload_to='declaration/documents/', blank=True, null=True)
    status = models.CharField(max_length=100, default='A', blank=True, null=True)
    file_name = models.CharField(max_length=500, default='', blank=True, null=True)

    class Meta:
        db_table = 'DeclarationDocument'

    def __str__(self):
        return f'{self.id}: {self.file_name}'



class EUDContactHistory(BaseModel):
    """model to store contacts to send renewal request"""
    declaration = models.ForeignKey(
        EUDeclaration, on_delete=models.SET_NULL, null=True, blank=True, related_name='contacts'
    )
    email = models.EmailField(max_length=254, null=True, blank=True)
    address_type = models.CharField(max_length=50)

    class Meta:
        db_table = 'EUDContactHistory'


class CompanyContactHistory(BaseModel):
    """model to store contacts to send renewal request"""
    company = models.ForeignKey(
        Company, on_delete=models.SET_NULL, null=True, blank=True, related_name='contacts'
    )
    email = models.EmailField(max_length=254, null=True, blank=True)
    address_type = models.CharField(max_length=50)

    class Meta:
        db_table = 'CompanyContactHistory'


class DeclarationActionHistory(BaseModel):
    """model to details of details of eu declarations"""
    declaration = models.ForeignKey(
        EUDeclaration, on_delete=models.SET_NULL, null=True, blank=True, related_name='declaration_histories'
    )
    renewed_by = models.IntegerField(null=True, blank=True)
    renewed_on = models.DateTimeField(null=True, blank=True)
    request_sent_by = models.IntegerField(null=True, blank=True)
    requested_on = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'DeclarationActionHistory'

    def __str__(self):
        return f'{self.id}: {self.declaration}- {self.renewed_by}'



class SharedDocument(BaseModel):
    """model to store details of documents shared to customer"""
    company = models.ForeignKey(
        Company, on_delete=models.SET_NULL, null=True, blank=True, related_name='documents'
    )
    file_path = models.FileField(upload_to='declaration/shared_documents/', blank=True, null=True)
    status = models.CharField(max_length=100, default='A', blank=True, null=True)
    file_name = models.CharField(max_length=500, default='', blank=True, null=True)
    shared_by = models.IntegerField( null=True, blank=True)
    shared_on = models.DateTimeField(auto_now_add=True, null=True)
    description = models.CharField(max_length=1000, default='', blank=True, null=True)


    class Meta:
        db_table = 'SharedDocument'

    def __str__(self):
        return f'{self.id}: {self.file_name}'
    

class SavedDocument(BaseModel):
    """model to store details of documents shared to customer"""
    company = models.ForeignKey(
        Company, on_delete=models.SET_NULL, null=True, blank=True, related_name='saved_documents'
    )
    file_path = models.FileField(upload_to='declaration/saved_documents/', blank=True, null=True)
    status = models.CharField(max_length=100, default='A', blank=True, null=True)
    file_name = models.CharField(max_length=500, default='', blank=True, null=True)
    description = models.CharField(max_length=1000, default='', blank=True, null=True)


    class Meta:
        db_table = 'SavedDocument'

    def __str__(self):
        return f'{self.id}: {self.file_name}'