# Path: billing/models.py
# class CreditCard(Model):
#     ACTIVE = 'ACTIVE'
#     INACTIVE = 'INACTIVE'
#     STATUS_CHOICES = (
#         (ACTIVE, _('Active')),
#         (INACTIVE, _('Inactive')),
#     )
# 
#     id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
#     created = models.DateTimeField(auto_now_add=True, db_index=True)
#     modified = models.DateTimeField(auto_now=True)
#     account = models.ForeignKey(Account, related_name='credit_cards', on_delete=PROTECT)
#     type = models.CharField(db_index=True, max_length=3)
#     number = models.CharField(max_length=255)
#     expiry_month = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(12)])
#     expiry_year = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(99)])
#     expiry_date = models.DateField()  # A field in the database so we can search for expired cards
# 
#     psp_content_type = models.ForeignKey(ContentType, on_delete=CASCADE)
#     psp_object_id = models.UUIDField(db_index=True)
#     psp_object = GenericForeignKey('psp_content_type', 'psp_object_id')
# 
#     status = FSMField(max_length=20, choices=STATUS_CHOICES, default=ACTIVE, db_index=True)
# 
#     objects = CreditCardQuerySet.as_manager()
# 
#     @transition(field=status, source=ACTIVE, target=INACTIVE)
#     def deactivate(self):
#         pass
# 
#     @transition(field=status, source=INACTIVE, target=ACTIVE)
#     def reactivate(self):
#         pass
# 
#     def is_valid(self, as_of: date = None):
#         if as_of is None:
#             as_of = datetime.now().date()
#         return self.expiry_date >= as_of
# 
#     def save(self, *args, **kwargs):
#         if self.expiry_year is not None and self.expiry_month is not None:
#             self.expiry_date = compute_expiry_date(two_digit_year=self.expiry_year, month=self.expiry_month)
#         super().save(*args, **kwargs)


from django.db import transaction
from structlog import get_logger
from ..models import CreditCard


logger = get_logger()


def deactivate(credit_card_id: str) -> None:
    """
    Deactivates a credit card.
    """
    logger.info('deactivating-credit-card', credit_card_id=credit_card_id)
    with transaction.atomic():
        cc = CreditCard.objects.get(pk=credit_card_id)
        cc.deactivate()
        cc.save()


def reactivate(credit_card_id: str) -> None:
    """
    Reactivates a credit card.
    """
    logger.info('reactivating-credit-card', credit_card_id=credit_card_id)
    with transaction.atomic():

# Path: billing/models.py
# class CreditCard(Model):
#     ACTIVE = 'ACTIVE'
#     INACTIVE = 'INACTIVE'
#     STATUS_CHOICES = (
#         (ACTIVE, _('Active')),
#         (INACTIVE, _('Inactive')),
#     )
# 
#     id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
#     created = models.DateTimeField(auto_now_add=True, db_index=True)
#     modified = models.DateTimeField(auto_now=True)
#     account = models.ForeignKey(Account, related_name='credit_cards', on_delete=PROTECT)
#     type = models.CharField(db_index=True, max_length=3)
#     number = models.CharField(max_length=255)
#     expiry_month = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(12)])
#     expiry_year = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(99)])
#     expiry_date = models.DateField()  # A field in the database so we can search for expired cards
# 
#     psp_content_type = models.ForeignKey(ContentType, on_delete=CASCADE)
#     psp_object_id = models.UUIDField(db_index=True)
#     psp_object = GenericForeignKey('psp_content_type', 'psp_object_id')
# 
#     status = FSMField(max_length=20, choices=STATUS_CHOICES, default=ACTIVE, db_index=True)
# 
#     objects = CreditCardQuerySet.as_manager()
# 
#     @transition(field=status, source=ACTIVE, target=INACTIVE)
#     def deactivate(self):
#         pass
# 
#     @transition(field=status, source=INACTIVE, target=ACTIVE)
#     def reactivate(self):
#         pass
# 
#     def is_valid(self, as_of: date = None):
#         if as_of is None:
#             as_of = datetime.now().date()
#         return self.expiry_date >= as_of
# 
#     def save(self, *args, **kwargs):
#         if self.expiry_year is not None and self.expiry_month is not None:
#             self.expiry_date = compute_expiry_date(two_digit_year=self.expiry_year, month=self.expiry_month)
#         super().save(*args, **kwargs)


# Path: billing/actions/credit_cards.py
from django.db import transaction
from structlog import get_logger
from ..models import CreditCard



logger = get_logger()


def deactivate(credit_card_id: str) -> None:
    """
    Deactivates a credit card.
    """
    logger.info('deactivating-credit-card', credit_card_id=credit_card_id)
    with transaction.atomic():
        cc = CreditCard.objects.get(pk=credit_card_id)
        cc.deactivate()
        cc.save()


def reactivate(credit_card_id: str) -> None:
    """
    Reactivates a credit card.
    """
    logger.info('reactivating-credit-card', credit_card_id=credit_card_id)
    with transaction.atomic():

        cc = CreditCard.objects.get(pk=credit_card_id)