from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone
from django.core.validators import MinValueValidator
from decimal import Decimal

User = get_user_model()


class Expense(models.Model):
    """
    Expense tracking model for business expenses
    """
    CATEGORY_CHOICES = [
        ('operational', 'Operational'),
        ('staff', 'Staff'),
        ('marketing', 'Marketing'),
        ('loan_related', 'Loan-Related'),
        ('utilities', 'Utilities'),
        ('office', 'Office'),
        ('transport', 'Transport'),
        ('maintenance', 'Maintenance'),
        ('other', 'Other'),
    ]
    
    PAYMENT_METHOD_CHOICES = [
        ('cash', 'Cash'),
        ('mpesa', 'M-Pesa'),
        ('bank', 'Bank Transfer'),
        ('cheque', 'Cheque'),
    ]
    
    STATUS_CHOICES = [
        ('pending', 'Pending'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected'),
    ]
    
    id = models.BigAutoField(primary_key=True)
    
    # Basic Information
    title = models.CharField(max_length=200, help_text="Brief description of the expense")
    description = models.TextField(blank=True, null=True, help_text="Detailed description")
    category = models.CharField(max_length=20, choices=CATEGORY_CHOICES, default='operational')
    
    # Financial Information
    amount = models.DecimalField(
        max_digits=12, 
        decimal_places=2,
        validators=[MinValueValidator(Decimal('0.01'))],
        help_text="Expense amount in KES"
    )
    payment_method = models.CharField(max_length=20, choices=PAYMENT_METHOD_CHOICES, default='cash')
    paid_to = models.CharField(max_length=200, help_text="Recipient/Vendor name")
    
    # Receipt/Documentation
    receipt_path = models.FileField(
        upload_to='expenses/receipts/%Y/%m/',
        blank=True,
        null=True,
        help_text="Upload receipt or supporting document"
    )
    
    # Relationships
    branch = models.ForeignKey(
        'users.Branch',
        on_delete=models.CASCADE,
        related_name='expenses',
        help_text="Branch where expense was incurred"
    )
    staff = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        null=True,
        related_name='expenses_created',
        help_text="Staff member who created this expense"
    )
    loan = models.ForeignKey(
        'loans.Loan',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='related_expenses',
        help_text="Related loan (if applicable)"
    )
    
    # Approval Information
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
    approved_by = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='expenses_approved',
        help_text="Manager/Admin who approved this expense"
    )
    approved_at = models.DateTimeField(null=True, blank=True)
    rejection_reason = models.TextField(blank=True, null=True)
    
    # Dates
    expense_date = models.DateField(help_text="Date when expense was incurred")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    # Additional Fields
    reference_number = models.CharField(
        max_length=50,
        blank=True,
        null=True,
        help_text="Transaction/Reference number"
    )
    notes = models.TextField(blank=True, null=True, help_text="Additional notes")
    
    class Meta:
        db_table = 'expenses'
        ordering = ['-expense_date', '-created_at']
        verbose_name = 'Expense'
        verbose_name_plural = 'Expenses'
        indexes = [
            models.Index(fields=['branch', 'expense_date']),
            models.Index(fields=['status', 'expense_date']),
            models.Index(fields=['category', 'expense_date']),
            models.Index(fields=['staff', 'expense_date']),
        ]
    
    def __str__(self):
        return f"{self.title} - KES {self.amount} ({self.get_status_display()})"
    
    def approve(self, approved_by_user):
        """Approve the expense"""
        self.status = 'approved'
        self.approved_by = approved_by_user
        self.approved_at = timezone.now()
        self.save()
    
    def reject(self, rejected_by_user, reason):
        """Reject the expense"""
        self.status = 'rejected'
        self.approved_by = rejected_by_user
        self.approved_at = timezone.now()
        self.rejection_reason = reason
        self.save()
    
    @property
    def is_pending(self):
        return self.status == 'pending'
    
    @property
    def is_approved(self):
        return self.status == 'approved'
    
    @property
    def is_rejected(self):
        return self.status == 'rejected'
    
    @property
    def has_receipt(self):
        return bool(self.receipt_path)
