from django.db import models
from django.conf import settings
from django.utils import timezone
import secrets
import time


def uuid7() -> str:
    """Generate a UUID v7 (time-ordered UUID)."""
    nanoseconds = time.time_ns()
    uuid_int = (nanoseconds << 16) | secrets.randbits(48)
    return f"{uuid_int:032x}"


class Publication(models.Model):
    """Publications management."""
    id = models.UUIDField(primary_key=True, default=uuid7, editable=False)
    title = models.CharField(max_length=255)
    content = models.TextField()
    category = models.ForeignKey("PublicationCategory", on_delete=models.SET_NULL, null=True, blank=True, related_name="publications")
    # author = submitting user (must be staff w/ login). Audit/permission FK.
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="publications")
    # byline_contact = canonical author Contact (can be external — no User required).
    # New code should write to byline_contact; author is kept for permission/audit.
    byline_contact = models.ForeignKey(
        "contacts.Contact",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="byline_publications",
    )
    co_author_contacts = models.ManyToManyField(
        "contacts.Contact",
        related_name="co_byline_publications",
        blank=True,
    )
    status = models.CharField(max_length=20, choices=[
        ("draft", "Draft"),
        ("review", "In Review"),
        ("approved", "Approved"),
        ("published", "Published"),
        ("rejected", "Rejected"),
    ], default="draft")
    published_at = models.DateTimeField(null=True, blank=True)
    tags = models.JSONField(default=list)
    cover_image = models.ImageField(upload_to="publication_covers/", null=True, blank=True)
    attachments = models.JSONField(default=list)
    views = models.IntegerField(default=0)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        db_table = "publications"
        ordering = ["-created_at"]
        indexes = [
            models.Index(fields=["status"]),
            models.Index(fields=["published_at"]),
        ]


class PublicationCategory(models.Model):
    """Publication categories."""
    id = models.UUIDField(primary_key=True, default=uuid7, editable=False)
    slug = models.SlugField(max_length=100, unique=True, blank=True, null=True)
    name = models.CharField(max_length=100, unique=True)
    description = models.TextField(blank=True)
    color = models.CharField(max_length=7, default="#6b7280")

    class Meta:
        db_table = "publication_categories"
        ordering = ["name"]

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if not self.slug and self.name:
            self.slug = self.name.lower().replace(" ", "-")
        super().save(*args, **kwargs)


class Author(models.Model):
    """Author profile — bio/expertise. Attached to Contact (canonical Person), not User.
    External authors (no login) supported via Contact with user=None."""
    id = models.UUIDField(primary_key=True, default=uuid7, editable=False)
    # user kept temporarily for back-compat; new code should use contact. Deprecated.
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="author_profile",
        null=True,
        blank=True,
    )
    contact = models.OneToOneField(
        "contacts.Contact",
        on_delete=models.CASCADE,
        related_name="author_profile",
        null=True,
        blank=True,
    )
    bio = models.TextField(blank=True)
    expertise = models.JSONField(default=list)
    social_links = models.JSONField(default=dict)
    publications = models.ManyToManyField(Publication, related_name="co_authors", blank=True)

    class Meta:
        db_table = "authors"

    def __str__(self):
        if self.contact:
            return self.contact.name
        if self.user:
            return self.user.get_full_name()
        return f"Author {self.id}"


class Submission(models.Model):
    """Publication submissions for review."""
    id = models.UUIDField(primary_key=True, default=uuid7, editable=False)
    publication = models.OneToOneField(Publication, on_delete=models.CASCADE, related_name="submission")
    submitted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="submissions")
    status = models.CharField(max_length=20, choices=[
        ("submitted", "Submitted"),
        ("under_review", "Under Review"),
        ("revision_requested", "Revision Requested"),
        ("accepted", "Accepted"),
        ("rejected", "Rejected"),
    ], default="submitted")
    review_notes = models.TextField(blank=True)
    reviewed_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True)
    reviewed_at = models.DateTimeField(null=True, blank=True)
    submitted_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = "submissions"
        ordering = ["-submitted_at"]
        indexes = [
            models.Index(fields=["status"]),
        ]


class CSISPublication(models.Model):
    """Snapshot of a publication fetched from api.csis.or.id."""
    csis_id = models.IntegerField(unique=True)
    title = models.CharField(max_length=512)
    slug = models.SlugField(max_length=512, unique=True)
    date_publish = models.DateField(null=True, blank=True)
    authors = models.JSONField(default=list)
    topics = models.JSONField(default=list)
    category_name = models.CharField(max_length=255, blank=True)
    category_slug = models.CharField(max_length=255, blank=True)
    image = models.URLField(max_length=1024, blank=True)
    file_url = models.URLField(max_length=1024, blank=True)
    description = models.TextField(blank=True)
    viewed = models.IntegerField(default=0)
    download_count = models.IntegerField(default=0)
    synced_at = models.DateTimeField(auto_now=True)

    class Meta:
        db_table = "csis_publications"
        ordering = ["-date_publish"]
        indexes = [
            models.Index(fields=["category_slug"]),
            models.Index(fields=["date_publish"]),
        ]

    def __str__(self):
        return self.title


class ExternalPublication(models.Model):
    """External/publication references."""
    id = models.UUIDField(primary_key=True, default=uuid7, editable=False)
    title = models.CharField(max_length=255)
    source = models.CharField(max_length=255)
    url = models.URLField(blank=True)
    # authors JSON kept for legacy free-form refs. Prefer byline_contacts when authors
    # have Contact records (resolves to canonical Person).
    authors = models.JSONField(default=list)
    byline_contacts = models.ManyToManyField(
        "contacts.Contact",
        related_name="external_publications",
        blank=True,
    )
    published_date = models.DateField(null=True, blank=True)
    description = models.TextField(blank=True)
    tags = models.JSONField(default=list)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = "external_publications"
        ordering = ["-created_at"]