"""
Notification Service Models.
"""
import uuid

from django.conf import settings
from django.db import models
from django.utils.translation import gettext_lazy as _

from apps.core.tenant.models import TenantAwareModel


class NotificationChannel(models.TextChoices):
    """Notification delivery channels."""
    SMS = 'sms', _('SMS')
    EMAIL = 'email', _('Email')
    PANEL = 'panel', _('Panel')


class NotificationStatus(models.TextChoices):
    """Notification delivery status."""
    PENDING = 'pending', _('در انتظار')
    SENT = 'sent', _('ارسال شده')
    DELIVERED = 'delivered', _('تحویل شده')
    FAILED = 'failed', _('خطا')
    READ = 'read', _('خوانده شده')


class NotificationPriority(models.TextChoices):
    """Notification priority levels."""
    LOW = 'low', _('کم')
    NORMAL = 'normal', _('معمولی')
    HIGH = 'high', _('زیاد')
    URGENT = 'urgent', _('فوری')


class NotificationCategory(TenantAwareModel):
    """
    Dynamic notification categories.
    Each tenant can define their own categories.
    """
    name = models.CharField(
        max_length=100,
        verbose_name=_('نام'),
        help_text=_('نام یکتا برای شناسایی (مثلاً transaction)')
    )
    label = models.CharField(
        max_length=255,
        verbose_name=_('عنوان'),
        help_text=_('عنوان نمایشی (مثلاً تراکنش مالی)')
    )
    description = models.TextField(
        blank=True,
        null=True,
        verbose_name=_('توضیحات')
    )
    icon = models.CharField(
        max_length=50,
        blank=True,
        null=True,
        verbose_name=_('آیکون'),
        help_text=_('نام آیکون (اختیاری)')
    )
    color = models.CharField(
        max_length=7,
        default='#6B7280',
        verbose_name=_('رنگ'),
        help_text=_('کد رنگ هگز')
    )
    is_active = models.BooleanField(
        default=True,
        verbose_name=_('فعال')
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name=_('تاریخ ایجاد')
    )
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name=_('تاریخ بروزرسانی')
    )

    class Meta:
        db_table = 'notification_category'
        verbose_name = _('دسته‌بندی نوتیفیکیشن')
        verbose_name_plural = _('دسته‌بندی‌های نوتیفیکیشن')
        unique_together = ['tenant', 'name']
        ordering = ['name']

    def __str__(self):
        return self.label


class NotificationTemplate(TenantAwareModel):
    """
    Notification templates with Jinja2 support.
    """
    category = models.ForeignKey(
        NotificationCategory,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='templates',
        verbose_name=_('دسته‌بندی')
    )
    name = models.CharField(
        max_length=100,
        verbose_name=_('نام'),
        help_text=_('نام یکتا برای شناسایی (مثلاً welcome_email)')
    )
    title = models.CharField(
        max_length=255,
        verbose_name=_('عنوان'),
        help_text=_('عنوان نمایشی')
    )
    channel = models.CharField(
        max_length=20,
        choices=NotificationChannel.choices,
        verbose_name=_('کانال')
    )
    subject = models.CharField(
        max_length=255,
        blank=True,
        verbose_name=_('موضوع'),
        help_text=_('موضوع ایمیل (فقط برای کانال email)')
    )
    content = models.TextField(
        verbose_name=_('محتوا'),
        help_text=_('محتوای template با پشتیبانی از Jinja2')
    )
    variables = models.JSONField(
        default=list,
        verbose_name=_('متغیرها'),
        help_text=_('لیست متغیرهای مورد نیاز template')
    )
    is_active = models.BooleanField(
        default=True,
        verbose_name=_('فعال')
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name=_('تاریخ ایجاد')
    )
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name=_('تاریخ بروزرسانی')
    )

    class Meta:
        db_table = 'notification_template'
        verbose_name = _('قالب نوتیفیکیشن')
        verbose_name_plural = _('قالب‌های نوتیفیکیشن')
        unique_together = ['tenant', 'name']
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.title} ({self.get_channel_display()})"


class Notification(TenantAwareModel):
    """
    Individual notification records.
    """
    id = models.UUIDField(
        primary_key=True,
        default=uuid.uuid4,
        editable=False
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='notifications',
        verbose_name=_('گیرنده')
    )
    category = models.ForeignKey(
        NotificationCategory,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='notifications',
        verbose_name=_('دسته‌بندی')
    )
    template = models.ForeignKey(
        NotificationTemplate,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='notifications',
        verbose_name=_('قالب')
    )
    channel = models.CharField(
        max_length=20,
        choices=NotificationChannel.choices,
        verbose_name=_('کانال')
    )
    title = models.CharField(
        max_length=255,
        verbose_name=_('عنوان')
    )
    content = models.TextField(
        verbose_name=_('محتوا'),
        help_text=_('محتوای رندر شده')
    )
    priority = models.CharField(
        max_length=10,
        choices=NotificationPriority.choices,
        default=NotificationPriority.NORMAL,
        verbose_name=_('اولویت')
    )
    status = models.CharField(
        max_length=20,
        choices=NotificationStatus.choices,
        default=NotificationStatus.PENDING,
        verbose_name=_('وضعیت')
    )
    is_read = models.BooleanField(
        default=False,
        verbose_name=_('خوانده شده')
    )
    read_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name=_('زمان خواندن')
    )
    scheduled_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name=_('زمان ارسال برنامه‌ریزی شده')
    )
    sent_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name=_('زمان ارسال')
    )
    metadata = models.JSONField(
        default=dict,
        verbose_name=_('اطلاعات اضافی'),
        help_text=_('اطلاعات اضافی مثل link، action و غیره')
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name=_('تاریخ ایجاد')
    )

    class Meta:
        db_table = 'notification'
        verbose_name = _('نوتیفیکیشن')
        verbose_name_plural = _('نوتیفیکیشن‌ها')
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', 'is_read']),
            models.Index(fields=['user', 'status']),
            models.Index(fields=['scheduled_at']),
            models.Index(fields=['status', 'created_at']),
        ]

    def __str__(self):
        return f"{self.title} - {self.user}"

    def mark_as_read(self):
        """Mark notification as read."""
        from django.utils import timezone
        if not self.is_read:
            self.is_read = True
            self.read_at = timezone.now()
            self.status = NotificationStatus.READ
            self.save(update_fields=['is_read', 'read_at', 'status'])


class NotificationLog(TenantAwareModel):
    """
    Delivery logs for notifications.
    Tracks all send attempts and their results.
    """
    notification = models.ForeignKey(
        Notification,
        on_delete=models.CASCADE,
        related_name='logs',
        verbose_name=_('نوتیفیکیشن')
    )
    channel = models.CharField(
        max_length=20,
        choices=NotificationChannel.choices,
        verbose_name=_('کانال')
    )
    status = models.CharField(
        max_length=20,
        choices=NotificationStatus.choices,
        default=NotificationStatus.PENDING,
        verbose_name=_('وضعیت')
    )
    provider_response = models.JSONField(
        default=dict,
        verbose_name=_('پاسخ provider'),
        help_text=_('پاسخ دریافتی از SMS/Email provider')
    )
    error_message = models.TextField(
        blank=True,
        null=True,
        verbose_name=_('پیام خطا')
    )
    retry_count = models.IntegerField(
        default=0,
        verbose_name=_('تعداد تلاش')
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name=_('تاریخ ایجاد')
    )

    class Meta:
        db_table = 'notification_log'
        verbose_name = _('لاگ نوتیفیکیشن')
        verbose_name_plural = _('لاگ‌های نوتیفیکیشن')
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['notification', 'status']),
            models.Index(fields=['created_at']),
        ]

    def __str__(self):
        return f"Log #{self.pk} - {self.notification_id}"


class UserNotificationPreference(TenantAwareModel):
    """
    User preferences for notification channels per category.
    """
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='notification_preferences',
        verbose_name=_('کاربر')
    )
    category = models.ForeignKey(
        NotificationCategory,
        on_delete=models.CASCADE,
        related_name='user_preferences',
        verbose_name=_('دسته‌بندی')
    )
    sms_enabled = models.BooleanField(
        default=True,
        verbose_name=_('SMS فعال')
    )
    email_enabled = models.BooleanField(
        default=True,
        verbose_name=_('Email فعال')
    )
    panel_enabled = models.BooleanField(
        default=True,
        verbose_name=_('Panel فعال')
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name=_('تاریخ ایجاد')
    )
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name=_('تاریخ بروزرسانی')
    )

    class Meta:
        db_table = 'user_notification_preference'
        verbose_name = _('تنظیمات نوتیفیکیشن کاربر')
        verbose_name_plural = _('تنظیمات نوتیفیکیشن کاربران')
        unique_together = ['user', 'category']

    def __str__(self):
        return f"{self.user} - {self.category}"
