from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone
import uuid

from .receipt_helper import (
    generate_receipt_number_for_transaction
)

User = get_user_model()


class TransactionReceipt(models.Model):
    RECEIPT_TYPES = [
        ('deposit', 'Deposit'),
        ('withdrawal', 'Withdrawal'),
        ('share', 'Share Transaction'),
    ]

    receipt_number = models.CharField(max_length=20, unique=True)
    transaction_type = models.CharField(max_length=20, choices=RECEIPT_TYPES)
    member_number = models.CharField(max_length=50)
    reference_number = models.CharField(max_length=100, blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    generated_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    pdf_file = models.FileField(upload_to='receipts/', null=True, blank=True)

    # JSON field for full receipt payload
    receipt_data = models.JSONField(default=dict, blank=True, null=True)

    # Extra fields
    amount = models.DecimalField(max_digits=15, decimal_places=2, null=True, blank=True)
    customer_name = models.CharField(max_length=255, blank=True, null=True)
    branch_name = models.CharField(max_length=255, blank=True, null=True)
    transaction_date = models.DateTimeField(null=True, blank=True)
    status = models.CharField(max_length=20, default='active', choices=[
        ('active', 'Active'),
        ('cancelled', 'Cancelled'),
        ('void', 'Void')
    ])

    class Meta:
        db_table = 'public"."transaction_receipt'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['member_number'], name='receipt_member_idx'),
            models.Index(fields=['transaction_type'], name='receipt_type_idx'),
            models.Index(fields=['created_at'], name='receipt_created_idx'),
            models.Index(fields=['reference_number'], name='receipt_ref_idx'),
            models.Index(fields=['status'], name='receipt_status_idx'),
            models.Index(fields=['transaction_date'], name='receipt_trans_date_idx'),
            models.Index(fields=['member_number', 'transaction_type'], name='receipt_member_type_idx'),
            models.Index(fields=['created_at', 'transaction_type'], name='receipt_date_type_idx'),
        ]

    def __str__(self):
        return f"{self.receipt_number} - {self.transaction_type}"

    def save(self, *args, **kwargs):
        if not self.receipt_number:
            # Try generating using helper
            receipt_no = generate_receipt_number_for_transaction(self)
            if receipt_no:
                self.receipt_number = receipt_no
            else:
                # Fallback to UUID
                self.receipt_number = f"RCP-{uuid.uuid4().hex[:10].upper()}"

        super().save(*args, **kwargs)


class ReceiptConfig(models.Model):
    RECEIPT_TYPES = [
        ('DEPOSIT_RECEIPT', 'Deposit Receipt'),
        ('WITHDRAWAL_RECEIPT', 'Withdrawal Receipt'),
        ('LOAN_REPAYMENT_RECEIPT', 'Loan Repayment Receipt'),
        ('SHARE_PURCHASE_RECEIPT', 'Share Purchase Receipt'),
        ('SHARE_WITHDRAWAL_RECEIPT', 'Share Withdrawal Receipt'),
        ('TRANSFER_RECEIPT', 'Transfer Receipt'),
    ]

    receipt_type = models.CharField(max_length=50, choices=RECEIPT_TYPES, unique=True)
    prefix = models.CharField(max_length=10)
    start_number = models.PositiveIntegerField()
    current_number = models.PositiveIntegerField()
    increment_by = models.PositiveIntegerField(default=1)
    format = models.CharField(max_length=100)
    include_date = models.BooleanField(default=False)
    include_time = models.BooleanField(default=False)
    include_branch_code = models.BooleanField(default=False)
    include_org_code = 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)

    class Meta:
        db_table = 'receipt_configs'
        ordering = ['receipt_type']

    def __str__(self):
        return f"{self.receipt_type} - {self.prefix}"

    def clean(self):
        from django.core.exceptions import ValidationError

        if '{prefix}' not in self.format or '{number}' not in self.format:
            raise ValidationError("Format must contain {prefix} and {number}")

        if self.current_number < self.start_number:
            raise ValidationError("current_number must be >= start_number")

    def save(self, *args, **kwargs):
        self.clean()
        super().save(*args, **kwargs)
