# analytics/models.py
"""
Analytics models — all company-scoped for full tenant isolation.
"""
from django.db import models
from django.utils import timezone
from companies.models import Company
from inventory.models import Product


class Insight(models.Model):
    """A generated business insight for a company."""

    CATEGORY_CHOICES = [
        ('sales', 'Sales'),
        ('inventory', 'Inventory'),
        ('customers', 'Customers'),
        ('staff', 'Staff'),
        ('branch', 'Branch'),
        ('financial', 'Financial'),
    ]
    PRIORITY_CHOICES = [
        ('low', 'Low'),
        ('medium', 'Medium'),
        ('high', 'High'),
    ]
    COLOR_CHOICES = [
        ('green', 'Green'),   # good news
        ('yellow', 'Yellow'), # warning
        ('red', 'Red'),       # risk / urgent
        ('blue', 'Blue'),     # informational
    ]

    company = models.ForeignKey(
        Company, on_delete=models.CASCADE,
        related_name='insights', db_index=True,
    )
    title = models.CharField(max_length=200)
    description = models.TextField()
    category = models.CharField(max_length=20, choices=CATEGORY_CHOICES, db_index=True)
    priority = models.CharField(max_length=10, choices=PRIORITY_CHOICES, default='medium')
    color = models.CharField(max_length=10, choices=COLOR_CHOICES, default='blue')
    icon = models.CharField(max_length=50, default='fa-lightbulb', blank=True)
    is_read = models.BooleanField(default=False, db_index=True)
    created_at = models.DateTimeField(auto_now_add=True, db_index=True)

    class Meta:
        verbose_name = 'Insight'
        verbose_name_plural = 'Insights'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['company', 'is_read']),
            models.Index(fields=['company', 'category']),
        ]

    def __str__(self):
        return f"[{self.priority.upper()}] {self.title}"

    @classmethod
    def purge_old(cls, days=30):
        """Delete insights older than `days` days. Called daily."""
        from django.utils import timezone
        from datetime import timedelta
        cutoff = timezone.now() - timedelta(days=days)
        cls.objects.filter(created_at__lt=cutoff).delete()


class Notification(models.Model):
    """Real-time notification for company users."""

    TYPE_CHOICES = [
        ('info', 'Info'),
        ('warning', 'Warning'),
        ('danger', 'Danger'),
        ('success', 'Success'),
    ]

    company = models.ForeignKey(
        Company, on_delete=models.CASCADE,
        related_name='notifications', db_index=True,
    )
    # user=None means all users of the company see it
    user = models.ForeignKey(
        'accounts.CustomUser',
        on_delete=models.CASCADE,
        null=True, blank=True,
        related_name='notifications',
    )
    title = models.CharField(max_length=200)
    message = models.TextField()
    notification_type = models.CharField(max_length=10, choices=TYPE_CHOICES, default='info')
    icon = models.CharField(max_length=50, default='fa-bell', blank=True)
    is_read = models.BooleanField(default=False, db_index=True)
    url = models.CharField(max_length=400, blank=True, help_text="Optional action URL")
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = 'Notification'
        verbose_name_plural = 'Notifications'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['company', 'is_read']),
        ]

    def __str__(self):
        return f"{self.title} ({self.company.name})"


class StockForecast(models.Model):
    """Per-product stock forecast for a company."""

    HEALTH_CHOICES = [
        ('healthy', 'Healthy'),
        ('low_risk', 'Low Stock Risk'),
        ('critical', 'Critical - Restock Now'),
        ('dead', 'Dead Stock'),
        ('overstock', 'Overstock'),
    ]

    company = models.ForeignKey(
        Company, on_delete=models.CASCADE,
        related_name='stock_forecasts', db_index=True,
    )
    product = models.ForeignKey(
        Product, on_delete=models.CASCADE,
        related_name='forecast',
    )
    avg_daily_sales = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    days_until_stockout = models.IntegerField(
        null=True, blank=True,
        help_text="Estimated days until stock reaches zero. NULL = no recent sales."
    )
    recommended_restock_qty = models.PositiveIntegerField(default=0)
    stock_health = models.CharField(max_length=15, choices=HEALTH_CHOICES, default='healthy')
    generated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = 'Stock Forecast'
        verbose_name_plural = 'Stock Forecasts'
        ordering = ['days_until_stockout']
        unique_together = [['company', 'product']]

    def __str__(self):
        return f"{self.product.name} — {self.stock_health}"


class RolePermission(models.Model):
    """
    Granular per-role permission overrides per company.
    Extends the existing role system (admin/manager/cashier).
    """
    ROLE_CHOICES = [
        ('cashier', 'Cashier'),
        ('manager', 'Manager'),
        ('admin', 'Admin'),
    ]

    company = models.ForeignKey(
        Company, on_delete=models.CASCADE,
        related_name='role_permissions', db_index=True,
    )
    role = models.CharField(max_length=20, choices=ROLE_CHOICES)

    # ── POS Operations ──────────────────────────────────────────────
    can_delete_orders = models.BooleanField(default=False)
    can_reverse_orders = models.BooleanField(default=False)
    can_change_price_at_pos = models.BooleanField(default=False)
    can_apply_discount = models.BooleanField(default=True)

    # ── Reports & Finance ────────────────────────────────────────────
    can_view_profit = models.BooleanField(default=False)
    can_view_pnl = models.BooleanField(default=False)
    can_view_reports = models.BooleanField(default=False)     # daily/transaction/payment reports
    can_export_data = models.BooleanField(default=False)

    # ── Analytics & Insights ─────────────────────────────────────────
    can_view_analytics = models.BooleanField(default=False)
    can_view_stock_forecast = models.BooleanField(default=False)

    # ── Inventory Management ─────────────────────────────────────────
    can_manage_products = models.BooleanField(default=False)
    can_manage_suppliers = models.BooleanField(default=False)
    can_manage_purchase_orders = models.BooleanField(default=False)

    # ── Customer Management ──────────────────────────────────────────
    can_view_customers = models.BooleanField(default=True)
    can_manage_customers = models.BooleanField(default=False)  # create/edit/delete
    can_view_credit_sales = models.BooleanField(default=True)

    # ── Staff & Settings ─────────────────────────────────────────────
    can_manage_users = models.BooleanField(default=False)
    can_view_audit_log = models.BooleanField(default=False)
    can_manage_expenses = models.BooleanField(default=False)
    can_view_staff_performance = models.BooleanField(default=False)  # cashier performance report
    can_change_settings = models.BooleanField(default=False)

    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = 'Role Permission'
        verbose_name_plural = 'Role Permissions'
        unique_together = [['company', 'role']]

    def __str__(self):
        return f"{self.company.name} — {self.role}"

    @classmethod
    def get_for_role(cls, company, role):
        """Returns permission config, creating defaults if not exists."""
        defaults = {
            'cashier': {
                'can_delete_orders': False, 'can_reverse_orders': False,
                'can_change_price_at_pos': False, 'can_apply_discount': True,
                'can_view_profit': False, 'can_view_pnl': False,
                'can_view_reports': False, 'can_export_data': False,
                'can_view_analytics': False, 'can_view_stock_forecast': False,
                'can_manage_products': False, 'can_manage_suppliers': False,
                'can_manage_purchase_orders': False,
                'can_view_customers': True, 'can_manage_customers': False,
                'can_view_credit_sales': True,
                'can_manage_users': False, 'can_view_audit_log': False,
                'can_manage_expenses': False, 'can_view_staff_performance': False,
                'can_change_settings': False,
            },
            'manager': {
                'can_delete_orders': False, 'can_reverse_orders': True,
                'can_change_price_at_pos': True, 'can_apply_discount': True,
                'can_view_profit': True, 'can_view_pnl': True,
                'can_view_reports': True, 'can_export_data': True,
                'can_view_analytics': True, 'can_view_stock_forecast': True,
                'can_manage_products': True, 'can_manage_suppliers': True,
                'can_manage_purchase_orders': True,
                'can_view_customers': True, 'can_manage_customers': True,
                'can_view_credit_sales': True,
                'can_manage_users': False, 'can_view_audit_log': False,
                'can_manage_expenses': True, 'can_view_staff_performance': True,
                'can_change_settings': False,
            },
            'admin': {
                'can_delete_orders': True, 'can_reverse_orders': True,
                'can_change_price_at_pos': True, 'can_apply_discount': True,
                'can_view_profit': True, 'can_view_pnl': True,
                'can_view_reports': True, 'can_export_data': True,
                'can_view_analytics': True, 'can_view_stock_forecast': True,
                'can_manage_products': True, 'can_manage_suppliers': True,
                'can_manage_purchase_orders': True,
                'can_view_customers': True, 'can_manage_customers': True,
                'can_view_credit_sales': True,
                'can_manage_users': True, 'can_view_audit_log': True,
                'can_manage_expenses': True, 'can_view_staff_performance': True,
                'can_change_settings': True,
            },
        }
        obj, created = cls.objects.get_or_create(
            company=company, role=role,
            defaults=defaults.get(role, {})
        )
        return obj


class ExpenseCategory(models.Model):
    """Categories for operating expenses (e.g., Rent, Salaries, Utilities)"""
    company = models.ForeignKey(
        Company, on_delete=models.CASCADE,
        related_name='expense_categories', db_index=True
    )
    name = models.CharField(max_length=100)
    description = models.TextField(blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name_plural = "Expense Categories"
        unique_together = [['company', 'name']]

    def __str__(self):
        return self.name

class OperatingExpense(models.Model):
    """Individual operating expenses to deduct from gross profit"""
    company = models.ForeignKey(
        Company, on_delete=models.CASCADE,
        related_name='operating_expenses', db_index=True
    )
    category = models.ForeignKey(
        ExpenseCategory, on_delete=models.SET_NULL, null=True,
        related_name='expenses'
    )
    amount = models.DecimalField(max_digits=12, decimal_places=2)
    expense_date = models.DateField(default=timezone.now)
    reference = models.CharField(max_length=100, blank=True, help_text="Receipt/Invoice # or short description")
    notes = models.TextField(blank=True)
    logged_by = models.ForeignKey(
        'accounts.CustomUser', on_delete=models.SET_NULL, null=True,
        related_name='logged_expenses'
    )
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-expense_date', '-created_at']

    def __str__(self):
        return f"{self.category.name if self.category else 'Uncategorized'} - {self.amount}"

