from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.db import models
from django.utils import timezone
from decimal import Decimal


class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError('Email is required')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)
        extra_fields.setdefault('department', 'Admin')
        extra_fields.setdefault('full_name', 'System Admin')
        return self.create_user(email, password, **extra_fields)


class Role(models.Model):
    name = models.CharField(max_length=50, unique=True)
    description = models.CharField(max_length=200, blank=True)

    def __str__(self):
        return self.name

class User(AbstractBaseUser, PermissionsMixin):
    ROLE_CHOICES = [
        ('CEO', 'CEO'),
        ('PM', 'Project Manager'),
        ('TL', 'Team Lead'),
        ('BD', 'BD / Sales'),
        ('Member', 'Team Member'),
        ('Finance', 'Finance Officer'),
        ('HR', 'HR / Admin'),
    ]

    DEPARTMENT_CHOICES = [
        ('Tech', 'Technology'),
        ('Cyber', 'Cybersecurity'),
        ('Legal', 'Legal'),
        ('Sales', 'Sales'),
        ('Finance', 'Finance'),
        ('Admin', 'Administration'),
    ]

    THEME_CHOICES = [
        ('system', 'System Default'),
        ('light', 'Light'),
        ('dark', 'Dark'),
    ]

    email = models.EmailField(unique=True)
    full_name = models.CharField(max_length=150)
    roles = models.ManyToManyField(Role, related_name='users', blank=True)
    
    department = models.CharField(max_length=10, choices=DEPARTMENT_CHOICES, default='Tech')
    salary_pkr = models.DecimalField(
        max_digits=12, decimal_places=2, default=Decimal('0.00'),
        help_text='Monthly salary in PKR'
    )
    hourly_rate = models.DecimalField(
        max_digits=10, decimal_places=2, default=Decimal('0.00'),
        help_text='Auto-computed: salary / 176'
    )
    profile_photo = models.ImageField(upload_to='profiles/', blank=True, null=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    joined_date = models.DateField(default=timezone.now)
    force_password_change = models.BooleanField(default=False)
    theme_preference = models.CharField(
        max_length=10, choices=THEME_CHOICES, default='system'
    )
    email_notifications = models.JSONField(
        default=dict, blank=True,
        help_text='Per-category email notification toggles'
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['full_name']

    class Meta:
        app_label = 'users'
        ordering = ['full_name']

    def __str__(self):
        r = ", ".join([r.name for r in self.roles.all()]) if self.id else ""
        return f'{self.full_name} ({r})' if r else self.full_name

    def save(self, *args, **kwargs):
        # Auto-compute hourly rate: salary / 176 (22 days * 8 hours)
        if self.salary_pkr and self.salary_pkr > 0:
            self.hourly_rate = (self.salary_pkr / Decimal('176')).quantize(Decimal('0.01'))
        else:
            self.hourly_rate = Decimal('0.00')
        super().save(*args, **kwargs)

    @property
    def initials(self):
        parts = self.full_name.split()
        if len(parts) >= 2:
            return f'{parts[0][0]}{parts[-1][0]}'.upper()
        return self.full_name[:2].upper()

    def has_role(self, *roles_to_check):
        if self.is_superuser:
            return True
        if self.id:
            return self.roles.filter(name__in=roles_to_check).exists()
        return False

    @property
    def is_management(self):
        return self.has_role('CEO', 'PM', 'TL')

    @property
    def can_view_finance(self):
        return self.has_role('CEO', 'Finance', 'PM')

    @property
    def can_manage_users(self):
        return self.has_role('CEO', 'HR')

    @property
    def can_manage_leads(self):
        return self.has_role('CEO', 'PM', 'BD')

    @property
    def can_approve(self):
        return self.has_role('CEO', 'PM', 'TL')

class SiteConfiguration(models.Model):
    site_name = models.CharField(max_length=100, default='CyberArsenals')
    site_logo = models.ImageField(upload_to='site/', null=True, blank=True)
    site_favicon = models.ImageField(upload_to='site/', null=True, blank=True)
    tagline = models.CharField(max_length=255, default='Ensuring Cyber Peace')
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = "Site Configuration"
        verbose_name_plural = "Site Configuration"

    def __str__(self):
        return self.site_name

    def save(self, *args, **kwargs):
        if not self.pk and SiteConfiguration.objects.exists():
            # Force singleton behavior
            return
        super().save(*args, **kwargs)

    @classmethod
    def get_settings(cls):
        return cls.objects.first() or cls.objects.create()
