import uuid

from django.conf import settings
from django.contrib.auth.base_user import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.db import models
from django_prometheus.models import ExportModelOperationsMixin
from django_scopes import ScopedManager

from account.managers import UserManager


class Organization(ExportModelOperationsMixin('company'), models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=255, unique=True)
    slug = models.SlugField(unique=True, null=True)
    kvk_number = models.CharField(max_length=20, blank=True, null=True)
    vat_number = models.CharField(max_length=14, blank=True, null=True)
    iban = models.CharField(max_length=34, blank=True, null=True)
    address = models.CharField(max_length=255, blank=True, null=True)
    postal_code = models.CharField(max_length=20, blank=True, null=True)
    city = models.CharField(max_length=100, blank=True, null=True)
    email = models.EmailField(blank=True, null=True)

    users = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        through='Membership',
        related_name='organizations'
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    objects = models.Manager()

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "Organizations"
        ordering = ['name']

class User(ExportModelOperationsMixin('user'), AbstractBaseUser, PermissionsMixin):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    email = models.EmailField(unique=True)

    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    groups = models.ManyToManyField(
        'auth.Group',
        verbose_name='groups',
        blank=True,
        help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.',
        related_name="account_user_groups",
    )
    user_permissions = models.ManyToManyField(
        'auth.Permission',
        verbose_name='user permissions',
        blank=True,
        help_text='Specific permissions for this user.',
        related_name="account_user_permissions",
    )

    @property
    def has_multiple_organizations(self):
        """Geeft True terug als de gebruiker bij meer dan 1 organisatie hoort."""
        return self.memberships.count() > 1

    def is_owner_of(self, organization):
        return self.memberships.filter(organization=organization, role='owner').exists()

    def is_admin_of(self, organization):
        return self.memberships.filter(organization=organization, role='admin').exists()

    def __str__(self):
        return self.email

    class Meta:
        verbose_name = 'user'
        verbose_name_plural = 'users'


class UserProfile(models.Model):
    # De koppeling naar de User
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='profile')

    # De verplaatste velden
    first_name = models.CharField(max_length=30, blank=True)
    last_name = models.CharField(max_length=30, blank=True)

    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return f"Profiel van {self.user.email}"

class Membership(models.Model):
    ROLES = (
        ('owner', 'Eigenaar'),
        ('admin', 'Beheerder'),  # Kan instellingen wijzigen
        ('member', 'Medewerker'),  # Kan facturen maken
        ('viewer', 'Boekhouder'),  # Kan alleen kijken
    )

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='memberships')
    organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
    role = models.CharField(max_length=20, choices=ROLES, default='member')
    joined_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('user', 'organization') # Prevent double memberships
        ordering = ['joined_at']


class TenantAwareModel(models.Model):
    """
    Abstract model to make sure that data ALWAYS belongs to an organization.
    Use this for EVERYTHING in your SaaS system (Invoices, Clients, Tasks, etc).
    """
    organization = models.ForeignKey(
        Organization,
        on_delete=models.CASCADE,
        related_name="%(class)s_set"  # Gives for example: organization.invoice_set
    )

    # This makes sure that Invoice.objects.all() automatically filters on the active organization.
    objects = ScopedManager(organization='organization')

    class Meta:
        abstract = True
