import uuid
import secrets
import time

from django.db import models
from django.conf import settings


def uuid7() -> uuid.UUID:
    """Generate a UUID v7 (time-ordered UUID)."""
    nanoseconds = time.time_ns()
    uuid_int = (nanoseconds << 16) | secrets.randbits(48)
    return uuid.UUID(int=uuid_int)


class NotificationTemplate(models.Model):
    """Template for reusable notifications."""
    id = models.UUIDField(primary_key=True, default=uuid7, editable=False)
    name = models.CharField(max_length=100, unique=True)
    title_template = models.CharField(max_length=255)
    message_template = models.TextField()
    notification_type = models.CharField(max_length=50)
    icon = models.CharField(max_length=50, blank=True, default="bell")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        db_table = 'notifications_templates'
        ordering = ['name']

    def __str__(self):
        return self.name


class Notification(models.Model):
    """User notification model."""
    TYPE_CHOICES = [
        ("info", "Info"),
        ("success", "Success"),
        ("warning", "Warning"),
        ("error", "Error"),
        ("message", "Message"),
        ("task", "Task"),
        ("event", "Event"),
        ("meeting", "Meeting"),
        ("project", "Project"),
        ("hr", "HR"),
        ("asset", "Asset"),
        ("procurement", "Procurement"),
        ("chat", "Chat"),
        ("system", "System"),
    ]

    PRIORITY_CHOICES = [
        ("low", "Low"),
        ("medium", "Medium"),
        ("high", "High"),
        ("urgent", "Urgent"),
    ]

    id = models.UUIDField(primary_key=True, default=uuid7, editable=False)
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='app_notifications'
    )
    title = models.CharField(max_length=255)
    message = models.TextField()
    notification_type = models.CharField(
        max_length=50,
        choices=TYPE_CHOICES,
        default="info"
    )
    priority = models.CharField(
        max_length=20,
        choices=PRIORITY_CHOICES,
        default="medium"
    )
    icon = models.CharField(max_length=50, blank=True, default="bell")
    link = models.CharField(max_length=500, blank=True)
    is_read = models.BooleanField(default=False)
    read_at = models.DateTimeField(null=True, blank=True)
    is_deleted = models.BooleanField(default=False)
    metadata = models.JSONField(default=dict, blank=True)
    related_user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='related_notifications'
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        db_table = 'app_notifications'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', '-created_at']),
            models.Index(fields=['user', 'is_read']),
        ]

    def __str__(self):
        return f"{self.title} - {self.user.email}"

    def mark_as_read(self):
        if not self.is_read:
            from django.utils import timezone
            self.is_read = True
            self.read_at = timezone.now()
            self.save(update_fields=['is_read', 'read_at'])

    def mark_as_deleted(self):
        self.is_deleted = True
        self.save(update_fields=['is_deleted'])


class FCMDevice(models.Model):
    """A registered Firebase Cloud Messaging token for a user's device/browser.

    One user can have many devices. The token is the unique key; on re-register
    of an existing token we just re-point it at the current user and bump
    last_seen. Stale tokens are pruned when FCM reports them unregistered.
    """
    PLATFORM_CHOICES = [
        ("web", "Web"),
        ("android", "Android"),
        ("ios", "iOS"),
    ]

    id = models.UUIDField(primary_key=True, default=uuid7, editable=False)
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='fcm_devices'
    )
    token = models.CharField(max_length=512, unique=True)
    platform = models.CharField(max_length=10, choices=PLATFORM_CHOICES, default="web")
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    last_seen = models.DateTimeField(auto_now=True)

    class Meta:
        db_table = 'fcm_devices'
        ordering = ['-last_seen']
        indexes = [
            models.Index(fields=['user', 'is_active']),
        ]

    def __str__(self):
        return f"{self.platform} device for {self.user.email}"


class NotificationPreference(models.Model):
    """User notification preferences."""
    id = models.UUIDField(primary_key=True, default=uuid7, editable=False)
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='notification_preferences'
    )
    email_enabled = models.BooleanField(default=True)
    push_enabled = models.BooleanField(default=True)
    types_enabled = models.JSONField(default=dict)
    quiet_hours_start = models.TimeField(null=True, blank=True)
    quiet_hours_end = models.TimeField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        db_table = 'notification_preferences'

    def __str__(self):
        return f"Preferences for {self.user.email}"

    def is_type_enabled(self, notification_type):
        return self.types_enabled.get(notification_type, True)

    def set_type_enabled(self, notification_type, enabled):
        self.types_enabled[notification_type] = enabled
        self.save(update_fields=['types_enabled'])
