import uuid

from django.db import models

from apps.accounts.models import Company, TimeStampedModel, User


class ReminderOffset(models.TextChoices):
    BEFORE_7 = 'before_7', '7 Days Before Due'
    BEFORE_3 = 'before_3', '3 Days Before Due'
    DUE_TODAY = 'due_today', 'Due Today'
    OVERDUE_3 = 'overdue_3', '3 Days Overdue'
    OVERDUE_7 = 'overdue_7', '7 Days Overdue'
    OVERDUE_30 = 'overdue_30', '30 Days Overdue'


class Notification(TimeStampedModel):
    class Type(models.TextChoices):
        INVOICE_VIEWED = 'invoice_viewed', 'Invoice Viewed'
        INVOICE_PAID = 'invoice_paid', 'Invoice Paid'
        INVOICE_REMINDER = 'invoice_reminder', 'Invoice Reminder'
        LARGE_EXPENSE_RECORDED = 'large_expense_recorded', 'Large Expense Recorded'
        MONTHLY_REPORT_READY = 'monthly_report_ready', 'Monthly Report Ready'

    class Channel(models.TextChoices):
        IN_APP = 'in_app', 'In-App'
        EMAIL = 'email', 'Email'
        PUSH = 'push', 'Push'
        SMS = 'sms', 'SMS'

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='notifications')
    type = models.CharField(max_length=32, choices=Type.choices)
    channel = models.CharField(max_length=20, choices=Channel.choices, default=Channel.IN_APP)
    title = models.CharField(max_length=255)
    message = models.TextField(blank=True)
    is_read = models.BooleanField(default=False)
    invoice = models.ForeignKey(
        'invoicing.Invoice', on_delete=models.CASCADE, null=True, blank=True, related_name='notifications'
    )
    reminder_offset = models.CharField(max_length=20, choices=ReminderOffset.choices, null=True, blank=True)

    class Meta:
        ordering = ['-created_at']
        constraints = [
            models.UniqueConstraint(
                fields=['user', 'invoice', 'reminder_offset'],
                name='unique_reminder_per_user_invoice_offset',
                condition=models.Q(reminder_offset__isnull=False),
            )
        ]

    def __str__(self):
        return self.title


class ReminderRule(TimeStampedModel):
    Offset = ReminderOffset

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name='reminder_rules')
    offset = models.CharField(max_length=20, choices=ReminderOffset.choices)
    channel = models.CharField(max_length=20, choices=Notification.Channel.choices, default=Notification.Channel.EMAIL)
    is_active = models.BooleanField(default=True)

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['company', 'offset'], name='unique_reminder_rule_per_company_offset')
        ]

    def __str__(self):
        return f'{self.company.name} - {self.get_offset_display()}'
