from django.db import models, transaction
from django.contrib.auth.models import AbstractUser
from django.utils import timezone


class User(AbstractUser):
    """Custom User model with role and admin flag"""
    ROLE_CHOICES = [
        ('employee', 'Employee'),
        ('viewer', 'Viewer'),
    ]

    role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='viewer')
    is_admin = models.BooleanField(default=False)
    can_measure = models.BooleanField(default=False)
    can_manually_measure = models.BooleanField(default=False)
    can_manage_entities = models.BooleanField(default=False)
    can_edit_documents = models.BooleanField(default=False)

    class Meta:
        db_table = 'api_user'

    def __str__(self):
        return f"{self.username} ({self.get_role_display()})"


class ComPortReading(models.Model):
    """Model to store serial port readings"""
    port = models.CharField(max_length=20)
    data = models.TextField()
    timestamp = models.DateTimeField(auto_now_add=True)
    source_ip = models.GenericIPAddressField(null=True, blank=True)

    class Meta:
        ordering = ['-timestamp']
        indexes = [
            models.Index(fields=['-timestamp']),
            models.Index(fields=['port', '-timestamp']),
        ]

    def __str__(self):
        return f"{self.port} - {self.timestamp}"


class Report(models.Model):
    """Model to store report templates for the report editor"""
    name = models.CharField(max_length=255)
    page_width = models.IntegerField(default=80)
    page_height = models.IntegerField(default=66)
    api_endpoint = models.CharField(max_length=500, blank=True, default='')
    elements = models.JSONField(default=list)
    created_by = models.ForeignKey(
        User, on_delete=models.SET_NULL, null=True, blank=True,
        related_name='reports'
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-updated_at']

    def __str__(self):
        return self.name


class DocumentCounter(models.Model):
    year = models.IntegerField(unique=True)
    last_number = models.IntegerField(default=0)


def generate_doc_number(year):
    with transaction.atomic():
        counter, _ = DocumentCounter.objects.select_for_update().get_or_create(
            year=year, defaults={'last_number': 0}
        )
        counter.last_number += 1
        counter.save()
        return f"{year}-{counter.last_number:06d}"
