"""
Client Portfolio Views
Enhanced views for viewing individual client portfolios with loan officer information
"""

from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.db.models import Sum, Count, Q
from django.utils import timezone
from datetime import timedelta
from decimal import Decimal

from users.models import CustomUser
from loans.models import Loan, LoanApplication, Repayment
from .decorators import admin_required, portfolio_access_required


@login_required
@portfolio_access_required
def client_portfolio_detail(request, client_id):
    """
    Detailed view of a client's portfolio showing:
    - Loan history
    - Loan officer assignments
    - Performance metrics
    - Growth trends
    """
    # Check if user has permission to access portfolio
    if not request.user.has_permission('portfolio', 'access'):
        messages.error(request, 'You do not have permission to access portfolio.')
        return redirect('users:portfolio_dashboard')
    client = get_object_or_404(CustomUser, id=client_id, role='borrower')
    
    # Check permissions
    user = request.user
    if user.role not in ['admin', 'team_leader', 'loan_officer']:
        return JsonResponse({'error': 'Permission denied'}, status=403)
    
    # Get loan officer information
    loan_officer = client.portfolio_manager
    loan_officer_stats = None
    if loan_officer:
        stats = loan_officer.get_portfolio_stats()
        if stats:
            loan_officer_stats = {
                'officer': loan_officer,
                'total_clients': stats['total_clients'],
                'active_loans': stats['active_loans'],
                'collection_rate': float(stats.get('collection_rate', 0)),
                'default_rate': float(stats.get('default_rate', 0)) if stats.get('default_rate') else None,
            }
    
    # Get all loans for this client
    loans = Loan.objects.filter(borrower=client).select_related('application', 'application__loan_product').order_by('-created_at')
    
    # Calculate loan statistics
    total_loans = loans.count()
    active_loans = loans.filter(status='active').count()
    paid_loans = loans.filter(status='paid').count()
    defaulted_loans = loans.filter(status='defaulted').count()
    
    # Calculate amounts
    total_borrowed = loans.aggregate(total=Sum('principal_amount'))['total'] or Decimal('0')
    total_repaid = loans.aggregate(total=Sum('amount_paid'))['total'] or Decimal('0')
    total_outstanding = sum(loan.outstanding_amount for loan in loans.filter(status='active'))
    
    # Get recent repayments
    recent_repayments = Repayment.objects.filter(
        loan__borrower=client
    ).select_related('loan').order_by('-payment_date')[:10]
    
    # Get loan applications
    applications = LoanApplication.objects.filter(
        borrower=client
    ).select_related('loan_product').order_by('-submitted_at')[:10]
    
    # Calculate performance metrics
    on_time_payments = Repayment.objects.filter(
        loan__borrower=client,
        is_on_time=True
    ).count()
    late_payments = Repayment.objects.filter(
        loan__borrower=client,
        is_on_time=False
    ).count()
    total_payments = on_time_payments + late_payments
    on_time_rate = (on_time_payments / total_payments * 100) if total_payments > 0 else 0
    
    # Get loan history with outstanding amounts
    loan_history = []
    for loan in loans:
        loan_history.append({
            'loan': loan,
            'outstanding_amount': loan.outstanding_amount,
            'total_amount': loan.total_amount,
            'is_overdue': loan.is_overdue,
            'days_overdue': loan.days_overdue if loan.is_overdue else 0,
        })
    
    context = {
        'client': client,
        'loan_officer': loan_officer,
        'loan_officer_stats': loan_officer_stats,
        'loans': loan_history,
        'total_loans': total_loans,
        'active_loans': active_loans,
        'paid_loans': paid_loans,
        'defaulted_loans': defaulted_loans,
        'total_borrowed': total_borrowed,
        'total_repaid': total_repaid,
        'total_outstanding': total_outstanding,
        'recent_repayments': recent_repayments,
        'applications': applications,
        'on_time_rate': on_time_rate,
        'on_time_payments': on_time_payments,
        'late_payments': late_payments,
    }
    
    return render(request, 'users/client_portfolio_detail.html', context)


@login_required
@admin_required
def officer_client_portfolio(request, officer_id):
    """
    View all clients assigned to a loan officer with their portfolio performance
    """
    officer = get_object_or_404(CustomUser, id=officer_id, role__in=['loan_officer', 'team_leader'])
    
    # Get all clients assigned to this officer
    clients = CustomUser.objects.filter(
        portfolio_manager=officer,
        role='borrower',
        status='active'
    ).select_related('portfolio_manager', 'branch')
    
    # Get statistics for each client
    client_portfolios = []
    for client in clients:
        client_loans = Loan.objects.filter(borrower=client)
        active_loans = client_loans.filter(status='active').count()
        total_outstanding = sum(loan.outstanding_amount for loan in client_loans.filter(status='active'))
        total_borrowed = client_loans.aggregate(total=Sum('principal_amount'))['total'] or Decimal('0')
        total_repaid = client_loans.aggregate(total=Sum('amount_paid'))['total'] or Decimal('0')
        
        # Calculate performance
        defaulted_count = client_loans.filter(status='defaulted').count()
        total_loans = client_loans.count()
        default_rate = (defaulted_count / total_loans * 100) if total_loans > 0 else 0
        
        client_portfolios.append({
            'client': client,
            'active_loans': active_loans,
            'total_outstanding': total_outstanding,
            'total_borrowed': total_borrowed,
            'total_repaid': total_repaid,
            'default_rate': default_rate,
        })
    
    # Sort by total outstanding (descending)
    client_portfolios.sort(key=lambda x: x['total_outstanding'], reverse=True)
    
    # Get officer statistics
    officer_stats = officer.get_portfolio_stats()
    
    context = {
        'officer': officer,
        'officer_stats': officer_stats,
        'client_portfolios': client_portfolios,
        'total_clients': len(client_portfolios),
    }
    
    return render(request, 'users/officer_client_portfolio.html', context)

