from django.db import models
from django.conf import settings
from apps.core.models import BaseModel


class Notification(BaseModel):
    CHANNEL_CHOICES = (
        ('in_app', 'In App'),
        ('email', 'Email'),
        ('sms', 'SMS'),
        ('push', 'Push'),
        ('whatsapp', 'WhatsApp'),
    )

    STATUS_CHOICES = (
        ('pending', 'Pending'),
        ('sent', 'Sent'),
        ('failed', 'Failed'),
    )

    user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL, related_name='notifications')
    channel = models.CharField(max_length=20, choices=CHANNEL_CHOICES)
    recipient = models.CharField(max_length=255)
    subject = models.CharField(max_length=512, blank=True)
    message = models.TextField(blank=True)
    payload = models.JSONField(default=dict, blank=True)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending', db_index=True)
    is_read = models.BooleanField(default=False, db_index=True)
    read_at = models.DateTimeField(null=True, blank=True)
    provider = models.CharField(max_length=100, blank=True)
    sent_at = models.DateTimeField(null=True, blank=True)
    tenant_id = models.CharField(max_length=100, null=True, blank=True, db_index=True)

    def __str__(self):
        return f"{self.channel} -> {self.recipient} ({self.status})"


class NotificationTemplate(BaseModel):
    channel = models.CharField(max_length=20)
    code = models.CharField(max_length=100, unique=True, db_index=True)
    subject_template = models.CharField(max_length=512, blank=True)
    body_template = models.TextField(blank=True)
    is_active = models.BooleanField(default=True, db_index=True)

    def __str__(self):
        return self.code

    class Meta:
        indexes = [models.Index(fields=['code']), models.Index(fields=['channel'])]


class NotificationCampaign(BaseModel):
    AUDIENCE_CHOICES = (
        ('all', 'All Users'),
        ('active', 'Active Users'),
        ('role', 'Role Based'),
    )

    DELIVERY_CHOICES = (
        ('in_app', 'In App'),
        ('push', 'Push'),
        ('both', 'In App + Push'),
    )

    MODE_CHOICES = (
        ('instant', 'Instant'),
        ('scheduled', 'Scheduled'),
    )

    STATUS_CHOICES = (
        ('draft', 'Draft'),
        ('scheduled', 'Scheduled'),
        ('sent', 'Sent'),
        ('failed', 'Failed'),
    )

    title = models.CharField(max_length=255)
    message = models.TextField()
    banner_image = models.ImageField(upload_to='notifications/banners/', null=True, blank=True)
    audience = models.CharField(max_length=20, choices=AUDIENCE_CHOICES, default='all')
    role = models.CharField(max_length=50, blank=True)
    delivery_channel = models.CharField(max_length=20, choices=DELIVERY_CHOICES, default='both')
    mode = models.CharField(max_length=20, choices=MODE_CHOICES, default='instant')
    scheduled_at = models.DateTimeField(null=True, blank=True, db_index=True)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='draft', db_index=True)
    sent_at = models.DateTimeField(null=True, blank=True)
    total_recipients = models.PositiveIntegerField(default=0)
    total_sent = models.PositiveIntegerField(default=0)
    total_failed = models.PositiveIntegerField(default=0)
    created_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL, related_name='created_notification_campaigns')

    class Meta:
        indexes = [
            models.Index(fields=['status', 'scheduled_at']),
            models.Index(fields=['created_at']),
        ]

    def __str__(self):
        return f"{self.title} ({self.status})"


class UserDeviceToken(BaseModel):
    PLATFORM_CHOICES = (
        ('android', 'Android'),
        ('ios', 'iOS'),
        ('web', 'Web'),
    )

    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='device_tokens')
    platform = models.CharField(max_length=20, choices=PLATFORM_CHOICES, default='android')
    device_token = models.CharField(max_length=512, unique=True, db_index=True)
    last_seen_at = models.DateTimeField(auto_now=True)

    class Meta:
        indexes = [
            models.Index(fields=['user', 'platform']),
            models.Index(fields=['is_active']),
        ]

    def __str__(self):
        return f"{self.user_id} {self.platform}"


class EmailConfig(BaseModel):
    PROVIDER_CHOICES = (
        ('smtp', 'SMTP'),
    )

    name = models.CharField(max_length=120)
    provider = models.CharField(max_length=30, choices=PROVIDER_CHOICES, default='smtp')
    host = models.CharField(max_length=255)
    port = models.PositiveIntegerField(default=587)
    username = models.CharField(max_length=255, blank=True)
    password = models.CharField(max_length=255, blank=True)
    from_email = models.EmailField()
    use_tls = models.BooleanField(default=True)
    use_ssl = models.BooleanField(default=False)
    is_primary = models.BooleanField(default=False, db_index=True)
    is_enabled = models.BooleanField(default=True, db_index=True)
    allow_notifications = models.BooleanField(default=True)
    allow_otps = models.BooleanField(default=True)

    class Meta:
        indexes = [
            models.Index(fields=['is_primary', 'is_enabled']),
            models.Index(fields=['provider']),
        ]

    def __str__(self):
        return f"{self.name} ({self.provider})"
