from django.db import models
from django.contrib.auth.models import AbstractUser, Group, Permission
from django.utils import timezone
from django.contrib.auth.signals import user_logged_in
from django.dispatch import receiver
import phonenumbers
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from phonenumbers import PhoneNumberFormat

# Create your models here.

class CustomUser(AbstractUser):
    is_member = models.BooleanField(default=True)
    is_librarian = models.BooleanField(default=False)

class Category(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    publisher = models.CharField(max_length=100)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    date_publish = models.IntegerField(null=True)
    image = models.ImageField(upload_to='book_images/', null=True)
    isbn = models.CharField(max_length=13, unique=True)

    def is_available(self):
        return not self.bookloan_set.filter(is_returned=False).exists()

    def __str__(self):
        return self.title

class Member(models.Model):
    user = models.OneToOneField(CustomUser, null=True, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    address = models.TextField()
    email = models.EmailField(unique=True)
    birth_place = models.CharField(max_length=50, null=True)
    date_birth = models.DateField(null=True)
    phone_regex = RegexValidator(
        regex=r'^\+?1?\d{9,15}$',
        message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed."
    )
    phone_number = models.CharField(validators=[phone_regex], max_length=17, blank=True)

    def clean(self):
        super().clean()

        try:
            parsed_number = phonenumbers.parse(self.phone_number, None)
            if not phonenumbers.is_valid_number(parsed_number):
                raise ValidationError("Invalid phone number.")
            self.phone_number = phonenumbers.format_number(parsed_number, PhoneNumberFormat.E164)
        except phonenumbers.NumberParseException:
            raise ValidationError("Error parsing phone number.")

    def __str__(self):
        return self.name

class BookLoan(models.Model):
    book = models.ForeignKey(Book, on_delete=models.CASCADE)
    member = models.ForeignKey(Member, on_delete=models.CASCADE)
    loan_date = models.DateField(auto_now_add=True)
    due_date = models.DateField()
    return_date = models.DateField(null=True, blank=True)
    is_returned = models.BooleanField(default=False)

    def __str__(self):
        return f"{self.book.title} - {self.member.name}"
    
class Librarian(models.Model):
    user = models.OneToOneField(CustomUser, null=True, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    address = models.TextField(null=True)
    last_name = models.CharField(max_length=100, null=True)
    birth_place = models.CharField(max_length=50, null=True)
    date_birth = models.DateField(null=True)
    phone_regex = RegexValidator(
        regex=r'^\+?1?\d{9,15}$',
        message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed."
    )
    phone_number = models.CharField(validators=[phone_regex], max_length=17, blank=True)

    def clean(self):
        super().clean()

        try:
            parsed_number = phonenumbers.parse(self.phone_number, None)
            if not phonenumbers.is_valid_number(parsed_number):
                raise ValidationError("Invalid phone number.")
            self.phone_number = phonenumbers.format_number(parsed_number, PhoneNumberFormat.E164)
        except phonenumbers.NumberParseException:
            raise ValidationError("Error parsing phone number.")

    def __str__(self):
        return self.name

    @receiver(user_logged_in, sender=CustomUser)
    def create_librarian_login_history(sender, user, **kwargs):
        LoginHistory.objects.create(librarian=user)

    # Setup librarian group and permissions
    librarian_group, created = Group.objects.get_or_create(name='Librarian')
    if created:
        librarian_group.permissions.add(
            Permission.objects.get(codename='add_book'),
            Permission.objects.get(codename='change_book'),
            Permission.objects.get(codename='delete_book'),
            # Tambahkan izin lainnya sesuai kebutuhan
    )

class LoginHistory(models.Model):
    librarian = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    login_time = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return f'{self.librarian.username} - {self.login_time}'