# finance/forms.py
from django import forms
from django.core.exceptions import ValidationError
from .models import (
    FeeStructure, SchoolItemPrice, StudentEnrollmentFee,
    Invoice, Payment, Expense
)


class FeeStructureForm(forms.ModelForm):
    class Meta:
        model = FeeStructure
        fields = [
            'section', 'class_group', 'academic_year',
            'registration_new', 'registration_old',
            'total_fees', 'installment_1', 'installment_2',
            'specific_classes', 'is_active', 'description',
        ]
        widgets = {
            'section':          forms.Select(attrs={'class': 'form-select'}),
            'class_group':      forms.Select(attrs={'class': 'form-select'}),
            'academic_year':    forms.TextInput(attrs={'class': 'form-control'}),
            'registration_new': forms.NumberInput(attrs={'class': 'form-control'}),
            'registration_old': forms.NumberInput(attrs={'class': 'form-control'}),
            'total_fees':       forms.NumberInput(attrs={'class': 'form-control'}),
            'installment_1':    forms.NumberInput(attrs={'class': 'form-control'}),
            'installment_2':    forms.NumberInput(attrs={'class': 'form-control'}),
            'specific_classes': forms.CheckboxSelectMultiple(),
            'description':      forms.Textarea(attrs={'class': 'form-control', 'rows': 2}),
        }

    def clean(self):
        cleaned = super().clean()
        total = cleaned.get('total_fees')
        inst1 = cleaned.get('installment_1')
        inst2 = cleaned.get('installment_2')
        if total and inst1 and inst2:
            if inst1 + inst2 != total:
                raise ValidationError(
                    f'Installment 1 ({inst1:,}) + Installment 2 ({inst2:,}) must equal Total Fees ({total:,}).'
                )
        return cleaned


class SchoolItemPriceForm(forms.ModelForm):
    class Meta:
        model = SchoolItemPrice
        fields = ['item_type', 'name', 'price', 'academic_year', 'is_active', 'description']
        widgets = {
            'item_type':    forms.Select(attrs={'class': 'form-select'}),
            'name':         forms.TextInput(attrs={'class': 'form-control'}),
            'price':        forms.NumberInput(attrs={'class': 'form-control'}),
            'academic_year': forms.TextInput(attrs={'class': 'form-control'}),
            'description':  forms.Textarea(attrs={'class': 'form-control', 'rows': 2}),
        }


class StudentEnrollmentFeeForm(forms.ModelForm):
    class Meta:
        model = StudentEnrollmentFee
        fields = ['student', 'fee_structure', 'academic_year', 'is_new_pupil']
        widgets = {
            'student':       forms.Select(attrs={'class': 'form-select'}),
            'fee_structure': forms.Select(attrs={'class': 'form-select'}),
            'academic_year': forms.TextInput(attrs={'class': 'form-control'}),
        }


class InvoiceForm(forms.ModelForm):
    class Meta:
        model = Invoice
        fields = ['student', 'academic_year', 'invoice_type', 'due_date', 'total_amount', 'notes']
        widgets = {
            'student':       forms.Select(attrs={'class': 'form-select'}),
            'academic_year': forms.TextInput(attrs={'class': 'form-control'}),
            'invoice_type':  forms.Select(attrs={'class': 'form-select'}),
            'due_date':      forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
            'total_amount':  forms.NumberInput(attrs={'class': 'form-control'}),
            'notes':         forms.Textarea(attrs={'class': 'form-control', 'rows': 2}),
        }


class PaymentForm(forms.ModelForm):
    """
    Payment form with basic validation only.
    Duplicate detection is handled gracefully in the view.
    """
    
    class Meta:
        model = Payment
        fields = [
            'invoice', 'amount', 'payment_date', 'payment_method',
            'transaction_id', 'mobile_money_provider', 'mobile_money_number',
            'bank_name', 'cheque_number', 'notes'
        ]
        widgets = {
            'invoice':        forms.Select(attrs={'class': 'form-select'}),
            'amount':         forms.NumberInput(attrs={'class': 'form-control', 'step': '1', 'min': '1'}),
            'payment_date':   forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
            'payment_method': forms.Select(attrs={'class': 'form-select'}),
            'transaction_id': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Optional - unique reference'}),
            'mobile_money_provider': forms.Select(attrs={'class': 'form-select'}),
            'mobile_money_number': forms.TextInput(attrs={'class': 'form-control'}),
            'bank_name':      forms.TextInput(attrs={'class': 'form-control'}),
            'cheque_number':  forms.TextInput(attrs={'class': 'form-control'}),
            'notes':          forms.Textarea(attrs={'class': 'form-control', 'rows': 2}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Only show invoices with outstanding balance
        from django.db.models import Q
        self.fields['invoice'].queryset = Invoice.objects.filter(
            ~Q(status='paid') & ~Q(status='cancelled')
        ).select_related('student')
        
        # Improve dropdown display with balance information
        choices = []
        for invoice in self.fields['invoice'].queryset:
            choices.append((
                invoice.id, 
                f"{invoice.invoice_number} - {invoice.student.get_full_name()} - {invoice.get_invoice_type_display()} (Balance: {invoice.balance:,.0f} XAF)"
            ))
        self.fields['invoice'].choices = choices

    def clean(self):
        """Basic validation only - no duplicate checks (handled in view)"""
        cleaned_data = super().clean()
        amount = cleaned_data.get('amount')
        invoice = cleaned_data.get('invoice')
        
        if amount and invoice:
            if amount <= 0:
                raise ValidationError("Payment amount must be greater than zero.")
            if amount > invoice.balance:
                raise ValidationError(
                    f"Amount (XAF {amount:,.0f}) exceeds remaining balance (XAF {invoice.balance:,.0f})."
                )
        
        return cleaned_data


class ExpenseForm(forms.ModelForm):
    class Meta:
        model = Expense
        fields = [
            'category', 'description', 'amount', 'expense_date',
            'payment_method', 'vendor', 'notes', 'receipt_file',
        ]
        widgets = {
            'category':       forms.Select(attrs={'class': 'form-select'}),
            'description':    forms.TextInput(attrs={'class': 'form-control'}),
            'amount':         forms.NumberInput(attrs={'class': 'form-control'}),
            'expense_date':   forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
            'payment_method': forms.Select(attrs={'class': 'form-select'}),
            'vendor':         forms.TextInput(attrs={'class': 'form-control'}),
            'notes':          forms.Textarea(attrs={'class': 'form-control', 'rows': 2}),
        }