from django.db import models
from django.contrib.auth.models import User, Group, Permission
from django.core.exceptions import ValidationError
from django.utils.text import slugify
from django.conf import settings
import json
import uuid

class TeamMember(models.Model):
    name = models.CharField(max_length=255, help_text="Nama lengkap anggota tim.")
    description = models.TextField(help_text="Deskripsi tentang anggota tim, termasuk keahlian atau peran mereka.")
    profile_photo = models.TextField(help_text="Foto profil dalam format teks (blob/base64).", blank=True, null=True)
    linkedin_url = models.URLField(max_length=500, help_text="URL profil LinkedIn anggota tim.", blank=True, null=True)
    role = models.CharField(max_length=255, help_text="Peran atau posisi anggota tim.")

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = "Team Member"
        verbose_name_plural = "Team Members"
        ordering = ['name']

class Year(models.Model):
    year = models.PositiveIntegerField(unique=True)

    def __str__(self):
        return str(self.year)

class Category(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField(blank=True, null=True)

    def __str__(self):
        return self.name


class MyModel(models.Model):
    uuid = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
    data = models.JSONField()
    category = models.ForeignKey('Category', on_delete=models.CASCADE, blank=True, null=True)
    year = models.ForeignKey('Year', on_delete=models.CASCADE, blank=True, null=True, db_index=True)
    is_verified = models.BooleanField(default=False, verbose_name="Verified")

    def __str__(self):
        nomor = self.data.get('Nomor', 'Unknown Number')
        tahun = self.year.year if self.year else 'Unknown Year'
        tentang = self.data.get('Tentang', 'Unknown Subject')
        return f"UU No {nomor} Tahun {tahun} Tentang {tentang}"

    def clean(self):
        # Jika kategori adalah "Konstitusi", skip validasi JSON
        if self.category and self.category.name == "Konstitusi":
            return

        # Validasi untuk UU biasa
        if not self.data:
            raise ValidationError("The 'data' field cannot be empty.")
        if 'Nomor' not in self.data or 'Tahun' not in self.data or 'Tentang' not in self.data:
            raise ValidationError("The JSON data must contain 'Nomor', 'Tahun', and 'Tentang'.")
        try:
            tahun_value = int(self.data['Tahun'])
            self.year, created = Year.objects.get_or_create(year=tahun_value)
        except (ValueError, KeyError):
            raise ValidationError("Invalid year format in JSON data.")

        
class Term(models.Model):
    name = models.CharField(max_length=255)
    definition = models.TextField()
    my_models = models.ManyToManyField(MyModel, related_name='terms')
    slug = models.SlugField(max_length=255, unique=True, blank=True, null=True)

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)

    def __str__(self):
        return self.name

class RecentlyUpdated(models.Model):
    my_model = models.ForeignKey(MyModel, on_delete=models.CASCADE, related_name='recent_updates')
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-updated_at']

    def __str__(self):
        nomor = self.my_model.data.get('Nomor', 'Unknown Number')
        tahun = self.my_model.year.year if self.my_model.year else 'Unknown Year'
        tentang = self.my_model.data.get('Tentang', 'Unknown Subject')
        return f"Recently Updated: UU No {nomor} Tahun {tahun} Tentang {tentang}"

class MyModelVisits(models.Model):
    uu = models.ForeignKey(MyModel, on_delete=models.CASCADE)
    user_ip = models.CharField(max_length=15)
    visited_at = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
    device_type = models.CharField(max_length=255, null=True)
    platform_type = models.CharField(max_length=255, null=True)
    browser_type = models.CharField(max_length=255, null=True)

class Popularity(models.Model):
    uu = models.OneToOneField(MyModel, on_delete=models.CASCADE)
    view_count = models.PositiveIntegerField(default=0)

    def __str__(self):
        return f"Popularity for {self.uu} with {self.view_count} views"

class SearchQuery(models.Model):
    query = models.CharField(max_length=255)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.query

class SearchTermQuery(models.Model):
    query = models.CharField(max_length=255)
    created_at = models.DateTimeField(auto_now_add=True)
    status = models.CharField(max_length=50, choices=[('found', 'Found'), ('not_found', 'Not Found')], default='found')

    def __str__(self):
        return self.query

class Bookmark(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    regulation = models.ForeignKey(MyModel, on_delete=models.CASCADE)
    last_read_position = models.FloatField(default=0)
    url = models.URLField()

    class Meta:
        unique_together = ('user', 'regulation')

    def __str__(self):
        return f"Bookmark by {self.user.username} for {self.regulation}"

class VisitorIP(models.Model):
    ip_address = models.GenericIPAddressField()
    accessed_url = models.CharField(max_length=255)
    timestamp = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.ip_address} accessed {self.accessed_url} at {self.timestamp}"
def load_provinces():
    """Load province names from JSON file."""
    with open(settings.BASE_DIR / 'provinces.json') as f:
        return json.load(f)

PROVINSI_CHOICES = [(provinsi, provinsi) for provinsi in load_provinces()]

def load_jobs():
    """Load job names from JSON file."""
    with open(settings.BASE_DIR / 'jobs.json') as f:
        jobs = json.load(f)
    return jobs

# Daftar kategori pekerjaan dari file JSON
JOB_CHOICES = [(job, job) for job in load_jobs()]

class UserProfile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=255, blank=True, null=True)
    last_name = models.CharField(max_length=255, blank=True, null=True)
    job = models.CharField(max_length=255, choices=JOB_CHOICES, blank=True, null=True)
    province = models.CharField(max_length=255, choices=PROVINSI_CHOICES, blank=True, null=True)
    birth_date = models.DateField(blank=True, null=True)
    profile_picture = models.TextField(blank=True, null=True, editable=True)
    groups = models.ManyToManyField(Group, related_name='userprofile_groups', blank=True)
    user_permissions = models.ManyToManyField(Permission, related_name='userprofile_permissions', blank=True)

    def __str__(self):
        return f"{self.first_name} {self.last_name}"

    def save(self, *args, **kwargs):
        if self.first_name:
            self.first_name = self.first_name.capitalize()
        if self.last_name:
            self.last_name = self.last_name.capitalize()
        super().save(*args, **kwargs)

    def get_initials(self):
        first_initial = self.first_name[0] if self.first_name else ''
        last_initial = self.last_name[0] if self.last_name else ''
        return f"{first_initial}{last_initial}".upper()

class Subscriber(models.Model):
    email = models.EmailField(unique=True, verbose_name="Email Address")
    subscribed_at = models.DateTimeField(auto_now_add=True, verbose_name="Subscription Date")

    def __str__(self):
        return self.email

class ContactMessage(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField()
    message = models.TextField()
    submitted_at = models.DateTimeField(auto_now_add=True)
    is_read = models.BooleanField(default=False)

    def __str__(self):
        return f"Message from {self.name}"

class SuspiciousLog(models.Model):
    ip = models.GenericIPAddressField(unique=True)
    count = models.IntegerField(default=0)
    timestamp = models.DateTimeField(auto_now_add=True)
    blocked = models.BooleanField(default=False)  # Bisa dikelola di admin

    def __str__(self):
        status = "Diblokir" if self.blocked else "Aman"
        return f"{self.ip} - {self.count} requests - {status}"

