# accounts/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.contrib.auth.hashers import make_password, check_password as django_check_password
from django.conf import settings
from companies.models import Company


class CustomUser(AbstractUser):
    ROLE_CHOICES = [
        ('superadmin', 'Super Admin'),
        ('admin', 'Admin'),
        ('manager', 'Manager'),
        ('cashier', 'Cashier'),
    ]

    role = models.CharField(max_length=10, choices=ROLE_CHOICES, default='cashier')
    phone = models.CharField(max_length=15, blank=True)
    profile_picture = models.ImageField(upload_to='profiles/', blank=True, null=True)

    company = models.ForeignKey(
        Company,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='users',
        verbose_name="Company",
        db_index=True,
    )

    # ✅ Branch for multi-branch
    branch = models.ForeignKey(
        'core.Branch',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='users',
        verbose_name="Branch"
    )

    # 🔒 PIN for protected actions
    pin_hash = models.CharField(max_length=128, blank=True,
                                help_text="Hashed PIN for protected actions")

    def set_pin(self, raw_pin):
        """Hash and store the PIN."""
        self.pin_hash = make_password(str(raw_pin))

    def check_pin(self, raw_pin):
        """Return True if raw_pin matches stored hash."""
        if not self.pin_hash:
            return False
        return django_check_password(str(raw_pin), self.pin_hash)

    def __str__(self):
        if self.branch:
            return f"{self.username} ({self.get_role_display()}) - {self.branch.name}"
        return f"{self.username} ({self.get_role_display()})"


class AuditLog(models.Model):
    """Track every significant user action for admin review."""
    ACTION_CHOICES = [
        ('login', 'Login'),
        ('logout', 'Logout'),
        ('create_user', 'Create User'),
        ('edit_user', 'Edit User'),
        ('delete_user', 'Delete User'),
        ('set_pin', 'Set PIN'),
        ('pin_verified', 'PIN Verified'),
        ('add_product', 'Add Product'),
        ('edit_product', 'Edit Product'),
        ('delete_product', 'Delete Product'),
        ('add_category', 'Add Category'),
        ('edit_category', 'Edit Category'),
        ('delete_category', 'Delete Category'),
        ('complete_order', 'Complete Order'),
        ('cancel_order', 'Cancel Order'),
        ('clear_credit', 'Clear Credit'),
        ('stock_adjustment', 'Stock Adjustment'),
        ('add_customer', 'Add Customer'),
        ('edit_customer', 'Edit Customer'),
        ('delete_customer', 'Delete Customer'),
        ('view_transactions', 'View Transactions'),
        ('view_pnl', 'View P&L Report'),
        ('export_data', 'Export Data'),
        ('other', 'Other'),
    ]

    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='audit_logs'
    )
    company = models.ForeignKey(
        Company,
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name='audit_logs',
        db_index=True,
    )
    action = models.CharField(max_length=50, choices=ACTION_CHOICES, default='other')
    target = models.CharField(max_length=300, blank=True,
                              help_text="What was acted on, e.g. 'Product: Garri 1kg'")
    ip_address = models.GenericIPAddressField(null=True, blank=True)
    timestamp = models.DateTimeField(auto_now_add=True)
    extra = models.JSONField(default=dict, blank=True,
                             help_text="Additional context as JSON")

    class Meta:
        verbose_name = "Audit Log"
        verbose_name_plural = "Audit Logs"
        ordering = ['-timestamp']

    def __str__(self):
        user_str = self.user.username if self.user else 'Unknown'
        return f"[{self.timestamp:%Y-%m-%d %H:%M}] {user_str} → {self.get_action_display()}"
