from decimal import Decimal
from datetime import date

class InvoiceScoringAlgorithm:
    """Advanced scoring algorithm for invoice discounting"""
    
    def __init__(self, invoice, credit_application):
        self.invoice = invoice
        self.credit_app = credit_application
        self.score = 0
        self.max_score = 100
        self.decision = 'PENDING'
    
    def calculate_score(self):
        """Calculate comprehensive risk score"""
        self.score = 0
        
        # Factor 1: Invoice amount (20 points max)
        self._score_invoice_amount()
        
        # Factor 2: Days to maturity (15 points max)
        self._score_maturity_days()
        
        # Factor 3: Client company credit rating (25 points max)
        self._score_client_credit()
        
        # Factor 4: Business relationship length (15 points max)
        self._score_relationship_length()
        
        # Factor 5: Payment history (15 points max)
        self._score_payment_history()
        
        # Factor 6: Document completeness (10 points max)
        self._score_document_completeness()
        
        return self.score
    
    def _score_invoice_amount(self):
        """Score based on invoice amount"""
        amount = float(self.invoice.invoice_amount)
        
        if amount <= 50000:
            self.score += 20
        elif amount <= 100000:
            self.score += 15
        elif amount <= 250000:
            self.score += 10
        elif amount <= 500000:
            self.score += 5
        else:
            self.score += 2
    
    def _score_maturity_days(self):
        """Score based on days until payment is due"""
        # Ensure due_date is a date object
        if isinstance(self.invoice.due_date, str):
            from datetime import datetime
            due_date = datetime.strptime(self.invoice.due_date, '%Y-%m-%d').date()
        else:
            due_date = self.invoice.due_date
        
        days_until_due = (due_date - date.today()).days
        
        if days_until_due <= 30:
            self.score += 15
        elif days_until_due <= 45:
            self.score += 12
        elif days_until_due <= 60:
            self.score += 8
        elif days_until_due <= 90:
            self.score += 5
        else:
            self.score += 2
    
    def _score_client_credit(self):
        """Score based on client company creditworthiness"""
        # Placeholder for credit bureau integration
        # For now, assume client has good credit
        self.score += 20
    
    def _score_relationship_length(self):
        """Score based on how long the business has operated"""
        try:
            if hasattr(self.credit_app, 'sector_details') and self.credit_app.sector_details:
                years = self.credit_app.sector_details.years_in_operation
            else:
                years = 0
        except:
            years = 0
        
        if years >= 5:
            self.score += 15
        elif years >= 3:
            self.score += 12
        elif years >= 1:
            self.score += 8
        else:
            self.score += 4
    
    def _score_payment_history(self):
        """Score based on previous payment history"""
        # Check previous invoices
        previous_invoices = self.invoice.__class__.objects.filter(
            credit_application=self.credit_app,
            status='REPAID'
        )
        
        count = previous_invoices.count()
        
        if count >= 10:
            self.score += 15
        elif count >= 5:
            self.score += 12
        elif count >= 1:
            self.score += 8
        else:
            self.score += 5  # New customer
    
    def _score_document_completeness(self):
        """Score based on uploaded documents"""
        try:
            from documents.models import Document
            
            required_docs = ['BEE', 'TAX', 'FINANCIAL', 'ID', 'CIPC']
            uploaded_docs = Document.objects.filter(
                credit_application=self.credit_app,
                status='VERIFIED'
            ).values_list('document_type', flat=True)
            
            uploaded_set = set(uploaded_docs)
            required_set = set(required_docs)
            
            completeness = len(required_set.intersection(uploaded_set)) / len(required_set)
            self.score += int(completeness * 10)
        except:
            self.score += 5  # Default if document module not fully set up
    
    def make_decision(self):
        """Make automated decision based on score"""
        if self.score >= 75:
            self.decision = 'APPROVED'
            return True, f"Application approved with score {self.score}%"
        elif self.score >= 50:
            self.decision = 'REFER'
            return False, f"Application needs manual review (score {self.score}%)"
        else:
            self.decision = 'DECLINED'
            return False, f"Application declined (score {self.score}%)"