from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse, HttpResponse
from django.db.models import Count, Sum, Avg
from django.db.models.functions import TruncMonth
from django.utils import timezone
from django.contrib import messages
from django.template.loader import render_to_string
from datetime import timedelta, datetime
from loans.models import Loan, LoanApplication, Repayment
from decimal import Decimal

@login_required
def reports_dashboard(request):
    """Reports dashboard view"""
    return render(request, 'reports/dashboard.html')

@login_required
def api_report_data(request):
    """API endpoint to fetch report data"""
    # Get the last 6 months for trend analysis
    end_date = timezone.now()
    start_date = end_date - timedelta(days=180)
    
    # 1. Disbursement Trend (last 6 months)
    disbursement_data = (
        Loan.objects
        .filter(disbursement_date__range=(start_date, end_date))
        .annotate(month=TruncMonth('disbursement_date'))
        .values('month')
        .annotate(
            amount=Sum('principal_amount'),
            count=Count('id')
        )
        .order_by('month')
    )
    
    # Prepare disbursement trend data
    months = []
    amounts = []
    for entry in disbursement_data:
        months.append(entry['month'].strftime('%B %Y'))
        amounts.append(float(entry['amount'] or 0))
    
    # 2. Loan Status Distribution
    status_data = (
        Loan.objects
        .values('status')
        .annotate(count=Count('id'))
        .order_by('status')
    )
    
    # Prepare status distribution data
    status_labels = []
    status_counts = []
    status_colors = {
        'active': '#4CAF50',
        'paid': '#2196F3',
        'defaulted': '#F44336',
        'rolled_over': '#FF9800',
        'written_off': '#9E9E9E'
    }
    status_colors_list = []
    
    for entry in status_data:
        status_labels.append(entry['status'].replace('_', ' ').title())
        status_counts.append(entry['count'])
        status_colors_list.append(status_colors.get(entry['status'], '#9E9E9E'))
    
    # 3. Repayment Performance
    repayment_data = (
        Repayment.objects
        .filter(payment_date__range=(start_date, end_date))
        .annotate(month=TruncMonth('payment_date'))
        .values('month')
        .annotate(
            amount=Sum('amount'),
            count=Count('id')
        )
        .order_by('month')
    )
    
    # Prepare repayment performance data
    repayment_months = []
    repayment_amounts = []
    for entry in repayment_data:
        repayment_months.append(entry['month'].strftime('%B %Y'))
        repayment_amounts.append(float(entry['amount'] or 0))
    
    # 4. Summary Statistics
    total_active_loans = Loan.objects.filter(status='active').count()
    total_disbursed = Loan.objects.aggregate(total=Sum('principal_amount'))['total'] or 0
    avg_loan_size = Loan.objects.aggregate(avg=Avg('principal_amount'))['avg'] or 0
    default_rate = (
        Loan.objects.filter(status='defaulted').count() /
        Loan.objects.count() * 100 if Loan.objects.exists() else 0
    )
    
    # Calculate month-over-month changes
    last_month_end = end_date - timedelta(days=30)
    last_month_start = last_month_end - timedelta(days=30)
    
    prev_active_loans = Loan.objects.filter(
        status='active',
        created_at__range=(last_month_start, last_month_end)
    ).count()
    
    prev_disbursed = Loan.objects.filter(
        created_at__range=(last_month_start, last_month_end)
    ).aggregate(total=Sum('principal_amount'))['total'] or 0
    
    prev_avg_loan = Loan.objects.filter(
        created_at__range=(last_month_start, last_month_end)
    ).aggregate(avg=Avg('principal_amount'))['avg'] or 0
    
    prev_default_rate = (
        Loan.objects.filter(
            status='defaulted',
            created_at__range=(last_month_start, last_month_end)
        ).count() /
        Loan.objects.filter(
            created_at__range=(last_month_start, last_month_end)
        ).count() * 100 if Loan.objects.filter(
            created_at__range=(last_month_start, last_month_end)
        ).exists() else 0
    )
    
    # Calculate percentage changes
    active_loans_change = ((total_active_loans - prev_active_loans) / prev_active_loans * 100) if prev_active_loans else 0
    disbursed_change = ((total_disbursed - prev_disbursed) / prev_disbursed * 100) if prev_disbursed else 0
    avg_loan_change = ((avg_loan_size - prev_avg_loan) / prev_avg_loan * 100) if prev_avg_loan else 0
    default_rate_change = default_rate - prev_default_rate
    
    response_data = {
        'disbursementTrend': {
            'labels': months,
            'datasets': [{
                'label': 'Amount Disbursed',
                'data': amounts,
                'borderColor': '#2196F3',
                'tension': 0.4
            }]
        },
        'loanStatusDistribution': {
            'labels': status_labels,
            'datasets': [{
                'data': status_counts,
                'backgroundColor': status_colors_list
            }]
        },
        'repaymentPerformance': {
            'labels': repayment_months,
            'datasets': [{
                'label': 'Amount Repaid',
                'data': repayment_amounts,
                'backgroundColor': '#4CAF50'
            }]
        },
        'summaryStats': {
            'totalActiveLoans': {
                'value': total_active_loans,
                'change': active_loans_change
            },
            'totalDisbursed': {
                'value': float(total_disbursed),
                'change': disbursed_change
            },
            'avgLoanSize': {
                'value': float(avg_loan_size),
                'change': avg_loan_change
            },
            'defaultRate': {
                'value': float(default_rate),
                'change': float(default_rate_change)
            }
        }
    }
    
    return JsonResponse(response_data)

@login_required
def borrower_reports(request):
    """Borrower reports view"""
    return render(request, 'reports/borrower_reports.html')

@login_required
def loan_reports(request):
    """Loan reports view"""
    return render(request, 'reports/loan_reports.html')

@login_required
def collection_reports(request):
    """Collection reports view"""
    return render(request, 'reports/collection_reports.html')

@login_required
def default_reports(request):
    """Default reports view"""
    return render(request, 'reports/default_reports.html')

@login_required
def rollover_reports(request):
    """Rollover reports view"""
    return render(request, 'reports/rollover_reports.html')

@login_required
def export_report(request, report_type):
    """Export report view"""
    return render(request, 'reports/export_report.html', {'report_type': report_type})

@login_required
def loan_analytics_dashboard(request):
    """Dashboard for loan analytics with filtering options"""
    from loans.models import LoanProduct
    from users.models import CustomUser
    
    # Get available loan products for filtering
    loan_products = LoanProduct.objects.all()
    
    # Get borrowers for filtering (limit to recent ones)
    borrowers = CustomUser.objects.filter(role='borrower').order_by('-date_joined')[:50]
    
    context = {
        'loan_products': loan_products,
        'borrowers': borrowers,
    }
    
    return render(request, 'reports/loan_analytics_dashboard.html', context)

@login_required
def loan_analytics_report(request):
    """Enhanced loan analytics report with view/download functionality"""
    from loans.reports import generate_comprehensive_loan_analytics
    from django.http import HttpResponse
    import base64
    
    # Get parameters from request
    start_date = request.GET.get('start_date')
    end_date = request.GET.get('end_date')
    borrower_id = request.GET.get('borrower_id')
    loan_product_id = request.GET.get('loan_product_id')
    format = request.GET.get('format', 'html')  # 'html', 'pdf', or 'json'
    
    # Convert dates if provided
    if start_date:
        try:
            start_date = datetime.strptime(start_date, '%Y-%m-%d')
        except ValueError:
            start_date = None
    
    if end_date:
        try:
            end_date = datetime.strptime(end_date, '%Y-%m-%d')
        except ValueError:
            end_date = None
    
    # Get borrower if specified
    borrower = None
    if borrower_id:
        try:
            from users.models import CustomUser
            borrower = CustomUser.objects.get(id=borrower_id)
        except CustomUser.DoesNotExist:
            if format == 'html':
                messages.error(request, 'Borrower not found')
                return redirect('reports:reports_dashboard')
            return JsonResponse({
                'success': False,
                'error': 'Borrower not found'
            })
    
    # Get loan product if specified
    loan_product = None
    if loan_product_id:
        try:
            from loans.models import LoanProduct
            loan_product = LoanProduct.objects.get(id=loan_product_id)
        except LoanProduct.DoesNotExist:
            loan_product = None
    
    try:
        # For popup view, use lightweight analytics without heavy chart generation
        if format == 'json' and borrower:
            # Quick analytics for popup
            result = generate_quick_analytics(
                start_date=start_date,
                end_date=end_date,
                borrower=borrower,
                loan_product=loan_product
            )
        else:
            # Full analytics for download/reports
            result = generate_comprehensive_loan_analytics(
                start_date=start_date,
                end_date=end_date,
                borrower=borrower,
                loan_product=loan_product,
                include_charts=True,
                export_format='both',
                include_full_analytics=True
            )
        
        if not result:
            if format == 'html':
                messages.error(request, 'Failed to generate report')
                return redirect('reports:reports_dashboard')
            return JsonResponse({
                'success': False,
                'error': 'Failed to generate report'
            })
        
        if format == 'pdf':
            # Return PDF for download
            if 'pdf_report' not in result:
                return JsonResponse({
                    'success': False,
                    'error': 'PDF report not available'
                })
            
            pdf_buffer = result['pdf_report']
            response = HttpResponse(pdf_buffer.getvalue(), content_type='application/pdf')
            response['Content-Disposition'] = 'attachment; filename="loan_analytics_report.pdf"'
            return response
            
        elif format == 'html':
            # Render the report template with the data
            html_content = render_to_string('reports/loan_analytics_report.html', {
                'stats': result['statistics'],
                'charts': result.get('charts', {}),
                'insights': result.get('insights', []),
                'borrower': borrower
            })
            return HttpResponse(html_content)
            
        else:  # format == 'json'
            # Return JSON response with HTML content and charts
            try:
                html_content = render_to_string('reports/loan_analytics_report.html', {
                    'stats': result['statistics'],
                    'charts': result.get('charts', {}),
                    'insights': result.get('insights', []),
                    'borrower': borrower
                })
                
                # Ensure we have valid chart data
                chart_data = result.get('charts', {})
                if not isinstance(chart_data, dict):
                    chart_data = {}
                
                return JsonResponse({
                    'success': True,
                    'html_content': html_content,
                    'charts': chart_data,
                    'title': f'Loan Analytics Report - {borrower.get_full_name() if borrower else "All Loans"}'
                }, json_dumps_params={'ensure_ascii': False})
                
            except Exception as template_error:
                print(f"Template rendering error: {template_error}")
                return JsonResponse({
                    'success': False,
                    'error': f'Error rendering report template: {str(template_error)}'
                })
            
    except Exception as e:
        if format == 'html':
            messages.error(request, f'Error generating report: {str(e)}')
            return redirect('reports:reports_dashboard')
        return JsonResponse({
            'success': False,
            'error': str(e)
        })