"""
Service de remboursement automatique des prêts lors des recharges
"""
from datetime import datetime, timedelta
from sqlalchemy.orm import Session
from models.models import Loan, LoanStatus, User, Transaction, TransactionType, TransactionStatus
from typing import Dict, Optional, Tuple
import uuid
from utility.stock import get_admin_stock

class LoanAutoRepaymentService:
    """Service pour gérer le remboursement automatique des prêts"""
    
    INTEREST_RATE = 0.06  # 6% d'intérêt
    GRACE_PERIOD_DAYS = 2  # 2 jours de délai de grâce
    
    @staticmethod
    def get_active_loan(user_id: str, db: Session) -> Optional[Loan]:
        """
        Récupérer le prêt actif non remboursé d'un utilisateur
        
        Args:
            user_id: ID de l'utilisateur
            db: Session de base de données
            
        Returns:
            Le prêt actif ou None
        """
        loan = db.query(Loan).filter(
            Loan.user_id == user_id,
            Loan.status.in_([LoanStatus.APPROVED, LoanStatus.ACTIVE, LoanStatus.OVERDUE]),
            Loan.remaining_balance > 0
        ).first()
        
        return loan
    
    @staticmethod
    def calculate_total_due(loan: Loan) -> float:
        """
        Calculer le montant total dû (capital + intérêt 6%)
        
        Args:
            loan: Le prêt
            
        Returns:
            Montant total dû
        """
        # Le remaining_balance contient déjà le capital + intérêt
        return loan.remaining_balance
    
    @staticmethod
    def should_block_account(loan: Loan) -> bool:
        """
        Vérifier si le compte doit être bloqué (3ème jour dépassé)
        
        Args:
            loan: Le prêt
            
        Returns:
            True si le compte doit être bloqué
        """
        if not loan or not loan.due_date:
            return False
        
        now = datetime.utcnow()
        # Bloquer si on a dépassé la date d'échéance (2 jours de grâce)
        return now > loan.due_date and loan.remaining_balance > 0
    
    @staticmethod
    def process_auto_repayment(
        user_id: str,
        recharge_amount: float,
        db: Session
    ) -> Dict:
        """
        Traiter le remboursement automatique lors d'une recharge
        
        RÈGLES:
        1. Si montant rechargé >= montant dû: rembourser totalement, créditer le reste
        2. Si montant rechargé < montant dû: déduire tout, wallet reste à 0, prêt reste actif
        
        Args:
            user_id: ID de l'utilisateur
            recharge_amount: Montant de la recharge
            db: Session de base de données
            
        Returns:
            Dict avec les détails du remboursement
        """
        # Vérifier s'il y a un prêt actif
        loan = LoanAutoRepaymentService.get_active_loan(user_id, db)
        
        if not loan:
            # Pas de prêt actif, retourner le montant complet
            return {
                "has_active_loan": False,
                "amount_to_credit": recharge_amount,
                "loan_repayment_amount": 0,
                "loan_remaining_balance": 0,
                "loan_fully_repaid": False
            }
        
        # Calculer le montant total dû
        total_due = LoanAutoRepaymentService.calculate_total_due(loan)
        
        print(f"💳 Remboursement automatique de prêt:")
        print(f"   • Prêt ID: {loan.id}")
        print(f"   • Montant dû: {total_due} FCFA")
        print(f"   • Montant recharge: {recharge_amount} FCFA")
        
        # Déterminer le montant à déduire
        if recharge_amount >= total_due:
            # CAS 1: Remboursement complet
            repayment_amount = total_due
            amount_to_credit = recharge_amount - total_due
            loan_fully_repaid = True
            
            # Mettre à jour le prêt
            loan.remaining_balance = 0
            loan.payments_completed = loan.total_payments
            loan.status = LoanStatus.COMPLETED
            
            print(f"   ✅ Remboursement COMPLET")
            print(f"   • Montant remboursé: {repayment_amount} FCFA")
            print(f"   • Montant crédité au wallet: {amount_to_credit} FCFA")
            
        else:
            # CAS 2: Remboursement partiel
            repayment_amount = recharge_amount
            amount_to_credit = 0
            loan_fully_repaid = False
            
            # Mettre à jour le prêt
            loan.remaining_balance -= repayment_amount
            
            print(f"   ⚠️  Remboursement PARTIEL")
            print(f"   • Montant remboursé: {repayment_amount} FCFA")
            print(f"   • Reste à payer: {loan.remaining_balance} FCFA")
            print(f"   • Wallet crédité: 0 FCFA")
        
        # Créditer le stock admin avec le montant remboursé
        admin_stock = get_admin_stock(db)
        admin_stock.balance += repayment_amount
        admin_stock.total_credits += repayment_amount
        
        # Créer une transaction de remboursement automatique
        repayment_transaction = Transaction(
            id=str(uuid.uuid4()),
            user_id=user_id,
            transaction_type=TransactionType.REMBOURSEMENT_AUTO,
            amount=repayment_amount,
            status=TransactionStatus.COMPLETED,
            description=f"Remboursement automatique prêt {loan.id[:8]} - {'Complet' if loan_fully_repaid else 'Partiel'}",
            reference=f"AUTO-REPAY-{str(uuid.uuid4())[:8]}",
            external_reference=loan.id,
            completed_at=datetime.utcnow()
        )
        
        db.add(repayment_transaction)
        db.commit()
        db.refresh(loan)
        
        return {
            "has_active_loan": True,
            "loan_id": loan.id,
            "amount_to_credit": amount_to_credit,
            "loan_repayment_amount": repayment_amount,
            "loan_remaining_balance": loan.remaining_balance,
            "loan_fully_repaid": loan_fully_repaid,
            "repayment_transaction_id": repayment_transaction.id
        }
    
    @staticmethod
    def check_and_block_overdue_accounts(db: Session) -> Dict:
        """
        Vérifier et bloquer les comptes avec prêts en retard (3ème jour dépassé)
        
        Cette fonction doit être appelée périodiquement (cron job)
        
        Args:
            db: Session de base de données
            
        Returns:
            Dict avec le nombre de comptes bloqués
        """
        now = datetime.utcnow()
        
        # Récupérer tous les prêts actifs en retard
        overdue_loans = db.query(Loan).filter(
            Loan.status.in_([LoanStatus.APPROVED, LoanStatus.ACTIVE, LoanStatus.OVERDUE]),
            Loan.remaining_balance > 0,
            Loan.due_date < now
        ).all()
        
        blocked_count = 0
        
        for loan in overdue_loans:
            # Calculer les jours de retard
            days_overdue = (now - loan.due_date).days
            loan.days_overdue = days_overdue
            
            # Marquer le prêt comme en retard
            if loan.status != LoanStatus.OVERDUE:
                loan.status = LoanStatus.OVERDUE
            
            # Bloquer l'utilisateur
            user = db.query(User).filter(User.id == loan.user_id).first()
            if user and not user.is_blocked:
                user.is_blocked = True
                user.blocked_reason = f"Prêt en retard de {days_overdue} jour(s). Montant dû: {loan.remaining_balance} FCFA"
                blocked_count += 1
                
                print(f"🔒 Compte bloqué: {user.username}")
                print(f"   • Prêt ID: {loan.id}")
                print(f"   • Jours de retard: {days_overdue}")
                print(f"   • Montant dû: {loan.remaining_balance} FCFA")
        
        db.commit()
        
        return {
            "total_overdue_loans": len(overdue_loans),
            "accounts_blocked": blocked_count
        }
    
    @staticmethod
    def unblock_account_after_repayment(user_id: str, db: Session) -> bool:
        """
        Débloquer le compte après remboursement complet du prêt
        
        Args:
            user_id: ID de l'utilisateur
            db: Session de base de données
            
        Returns:
            True si le compte a été débloqué
        """
        # Vérifier s'il reste des prêts actifs
        active_loan = LoanAutoRepaymentService.get_active_loan(user_id, db)
        
        if not active_loan:
            # Plus de prêt actif, débloquer le compte
            user = db.query(User).filter(User.id == user_id).first()
            if user and user.is_blocked:
                user.is_blocked = False
                user.blocked_reason = None
                db.commit()
                
                print(f"🔓 Compte débloqué: {user.username}")
                print(f"   • Tous les prêts ont été remboursés")
                
                return True
        
        return False

