from flask import Blueprint, render_template, request, redirect, url_for, flash
from flask_login import login_required, current_user
from datetime import datetime, timedelta
from functools import wraps
import sys
sys.path.append('..')
from app import db, Loan, Wallet, Transaction, LoanRepayment

loans_bp = Blueprint('loans', __name__)

def role_required(*roles):
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            if not current_user.is_authenticated:
                return redirect(url_for('login'))
            if current_user.role not in roles:
                flash('You do not have permission to access this page.', 'danger')
                return redirect(url_for('dashboard'))
            return f(*args, **kwargs)
        return decorated_function
    return decorator

@loans_bp.route('/loans')
@login_required
def loan_dashboard():
    loans = Loan.query.filter_by(user_id=current_user.id).order_by(Loan.created_at.desc()).all()
    return render_template('loans/dashboard.html', loans=loans)

@loans_bp.route('/loans/apply', methods=['GET', 'POST'])
@login_required
def apply_loan():
    if request.method == 'POST':
        amount = float(request.form.get('amount'))
        duration_months = int(request.form.get('duration_months'))
        purpose = request.form.get('purpose')
        interest_rate = 10.0  # Default interest rate
        
        # Calculate total payable
        interest_amount = (amount * interest_rate / 100) * (duration_months / 12)
        total_payable = amount + interest_amount
        
        # Check if user has pending loans
        pending_loans = Loan.query.filter_by(user_id=current_user.id, status='pending').count()
        if pending_loans > 0:
            flash('You already have a pending loan application. Please wait for approval.', 'warning')
            return redirect(url_for('loans.loan_dashboard'))
        
        loan = Loan(
            user_id=current_user.id,
            amount=amount,
            interest_rate=interest_rate,
            total_payable=total_payable,
            duration_months=duration_months,
            purpose=purpose,
            status='pending'
        )
        
        db.session.add(loan)
        db.session.commit()
        
        flash('Loan application submitted successfully. Please wait for approval.', 'success')
        return redirect(url_for('loans.loan_dashboard'))
    
    return render_template('loans/apply.html')

@loans_bp.route('/loans/manage')
@login_required
@role_required('Super Admin', 'Admin', 'Loan Officer')
def manage_loans():
    pending_loans = Loan.query.filter_by(status='pending').order_by(Loan.created_at.desc()).all()
    approved_loans = Loan.query.filter_by(status='approved').order_by(Loan.created_at.desc()).all()
    rejected_loans = Loan.query.filter_by(status='rejected').order_by(Loan.created_at.desc()).all()
    
    return render_template('loans/manage.html', 
                         pending_loans=pending_loans,
                         approved_loans=approved_loans,
                         rejected_loans=rejected_loans)

@loans_bp.route('/loans/approve/<int:loan_id>')
@login_required
@role_required('Super Admin', 'Admin', 'Loan Officer')
def approve_loan(loan_id):
    loan = Loan.query.get_or_404(loan_id)
    
    if loan.status != 'pending':
        flash('This loan cannot be approved.', 'danger')
        return redirect(url_for('loans.manage_loans'))
    
    # Update loan status
    loan.status = 'approved'
    loan.approved_by = current_user.id
    loan.approved_at = datetime.utcnow()
    loan.due_date = datetime.utcnow() + timedelta(days=loan.duration_months * 30)
    
    # Disburse loan to user's wallet
    wallet = Wallet.query.filter_by(user_id=loan.user_id).first()
    wallet.balance += loan.amount
    
    # Create transaction record
    transaction = Transaction(
        user_id=loan.user_id,
        type='loan_disbursement',
        amount=loan.amount,
        status='completed',
        description=f'Loan disbursement - Ref: {loan.id}',
        reference=f'LOAN-{loan.id}'
    )
    
    db.session.add(transaction)
    db.session.commit()
    
    flash(f'Loan of ₦{loan.amount:.2f} has been approved and disbursed to {loan.user.full_name}.', 'success')
    return redirect(url_for('loans.manage_loans'))

@loans_bp.route('/loans/reject/<int:loan_id>')
@login_required
@role_required('Super Admin', 'Admin', 'Loan Officer')
def reject_loan(loan_id):
    loan = Loan.query.get_or_404(loan_id)
    
    if loan.status != 'pending':
        flash('This loan cannot be rejected.', 'danger')
        return redirect(url_for('loans.manage_loans'))
    
    loan.status = 'rejected'
    loan.approved_by = current_user.id
    loan.approved_at = datetime.utcnow()
    
    db.session.commit()
    
    flash(f'Loan application from {loan.user.full_name} has been rejected.', 'info')
    return redirect(url_for('loans.manage_loans'))

@loans_bp.route('/loans/repay/<int:loan_id>', methods=['GET', 'POST'])
@login_required
def repay_loan(loan_id):
    loan = Loan.query.get_or_404(loan_id)
    
    if loan.user_id != current_user.id:
        flash('You can only repay your own loans.', 'danger')
        return redirect(url_for('loans.loan_dashboard'))
    
    if loan.status != 'approved':
        flash('This loan is not eligible for repayment.', 'danger')
        return redirect(url_for('loans.loan_dashboard'))
    
    if request.method == 'POST':
        amount = float(request.form.get('amount'))
        payment_method = request.form.get('payment_method')
        
        if payment_method == 'wallet':
            wallet = Wallet.query.filter_by(user_id=current_user.id).first()
            
            if wallet.balance < amount:
                flash('Insufficient wallet balance.', 'danger')
                return redirect(url_for('loans.repay_loan', loan_id=loan_id))
            
            # Deduct from wallet
            wallet.balance -= amount
            
            # Create repayment record
            repayment = LoanRepayment(
                loan_id=loan.id,
                amount=amount,
                payment_method='wallet',
                status='completed'
            )
            
            # Create transaction record
            transaction = Transaction(
                user_id=current_user.id,
                type='loan_repayment',
                amount=amount,
                status='completed',
                description=f'Loan repayment - Loan ID: {loan.id}',
                reference=f'REPAY-{loan.id}-{datetime.utcnow().strftime("%Y%m%d%H%M%S")}'
            )
            
            db.session.add(repayment)
            db.session.add(transaction)
            db.session.commit()
            
            flash('Loan repayment successful!', 'success')
            return redirect(url_for('loans.loan_dashboard'))
        else:
            # Manual payment
            repayment = LoanRepayment(
                loan_id=loan.id,
                amount=amount,
                payment_method='manual',
                status='pending'
            )
            
            db.session.add(repayment)
            db.session.commit()
            
            flash('Repayment submitted for approval. Please wait for confirmation.', 'info')
            return redirect(url_for('loans.loan_dashboard'))
    
    # Calculate remaining balance
    total_repaid = sum(r.amount for r in loan.repayments if r.status == 'completed')
    remaining_balance = loan.total_payable - total_repaid
    
    return render_template('loans/repay.html', loan=loan, remaining_balance=remaining_balance)
