/**
 * Student Loan Matching Calculator Logic
 * Calculates net worth over time with and without SECURE Act 2.0 matching
 */

const INVESTMENT_RETURN_RATE = 0.07; // 7% annual return
const LOAN_INTEREST_RATE = 0.05; // 5% annual interest (federal student loan average)
const RETIREMENT_AGE = 65;
const MAX_CALCULATION_AGE = 70; // Calculate up to age 70 for complete data

/**
 * Calculate loan payoff time in years
 * @param {number} totalDebt - Total loan balance
 * @param {number} monthlyPayment - Monthly payment amount
 * @returns {number} Years to pay off loan
 */
function calculatePayoffYears(totalDebt, monthlyPayment) {
    if (!monthlyPayment || monthlyPayment <= 0) return 0;
    
    const monthlyRate = LOAN_INTEREST_RATE / 12;
    const minPayment = totalDebt * monthlyRate;
    
    if (monthlyPayment <= minPayment) {
        return 50; // Loan will never be paid off at this rate
    }
    
    const months = Math.log(monthlyPayment / (monthlyPayment - totalDebt * monthlyRate)) / Math.log(1 + monthlyRate);
    return Math.ceil(months / 12);
}

/**
 * Calculate remaining loan balance after a number of months
 * @param {number} originalBalance - Original loan amount
 * @param {number} monthlyPayment - Monthly payment
 * @param {number} monthsElapsed - Months since start of loan
 * @param {number} totalMonths - Total months for loan term
 * @returns {number} Remaining balance
 */
function calculateRemainingBalance(originalBalance, monthlyPayment, monthsElapsed, totalMonths) {
    if (monthsElapsed <= 0) return originalBalance;
    if (monthsElapsed >= totalMonths) return 0;
    
    const monthlyRate = LOAN_INTEREST_RATE / 12;
    const factor = Math.pow(1 + monthlyRate, monthsElapsed);
    const paymentsValue = monthlyPayment * ((factor - 1) / monthlyRate);
    const remainingBalance = originalBalance * factor - paymentsValue;
    
    return Math.max(0, remainingBalance);
}

/**
 * Calculate future value of retirement contributions with compound growth
 * @param {number} annualContribution - Annual contribution amount
 * @param {number} yearsContributing - Number of years contributing
 * @param {number} yearsToGrow - Total years for growth (from first contribution to retirement)
 * @returns {number} Future value
 */
function calculateRetirementValue(annualContribution, yearsContributing, yearsToGrow) {
    let totalValue = 0;
    
    for (let year = 0; year < yearsContributing; year++) {
        const growthYears = yearsToGrow - year;
        totalValue += annualContribution * Math.pow(1 + INVESTMENT_RETURN_RATE, growthYears);
    }
    
    return totalValue;
}

/**
 * Main calculation function for net worth comparison
 * @param {Object} params - Input parameters
 * @returns {Object} Chart data with ages and net worth values
 */
function calculateNetWorthComparison(params) {
    const {
        salary = 0,
        totalDebt = 0,
        monthlyPayment = 0,
        matchRate = 0,
        currentAge = 28
    } = params;
    
    // Calculate derived values
    const payoffYears = calculatePayoffYears(totalDebt, monthlyPayment);
    const annualMatch = Math.min(monthlyPayment * 12, salary * (matchRate / 100));
    const payoffAge = currentAge + payoffYears;
    
    // Arrays for full calculation data (yearly)
    const allAges = [];
    const allWithProgram = [];
    const allWithoutProgram = [];
    
    // Calculate for each year from current to age 70
    for (let age = currentAge; age <= MAX_CALCULATION_AGE; age++) {
        allAges.push(age);
        const yearsElapsed = age - currentAge;
        const monthsElapsed = yearsElapsed * 12;
        
        // Calculate remaining loan balance
        const totalMonths = payoffYears * 12;
        const remainingDebt = calculateRemainingBalance(totalDebt, monthlyPayment, monthsElapsed, totalMonths);
        
        if (age <= payoffAge) {
            // DURING LOAN PAYMENT PERIOD
            
            // With program: Get employer match while paying loans
            const yearsContributing = Math.min(yearsElapsed, payoffYears);
            const retirementValue = calculateRetirementValue(annualMatch, yearsContributing, yearsElapsed);
            const netWorthWith = retirementValue - remainingDebt;
            allWithProgram.push(Math.round(netWorthWith));
            
            // Without program: No retirement savings, just debt
            const netWorthWithout = -remainingDebt;
            allWithoutProgram.push(Math.round(netWorthWithout));
            
        } else {
            // AFTER LOANS PAID OFF
            
            const yearsSincePayoff = age - payoffAge;
            const postPayoffContribution = Math.min(monthlyPayment * 12, salary * (matchRate / 100));
            
            // With program: Initial match during loan period + continued contributions after
            const duringLoanValue = calculateRetirementValue(annualMatch, payoffYears, yearsElapsed);
            const afterLoanValue = calculateRetirementValue(postPayoffContribution, yearsSincePayoff, yearsSincePayoff);
            const totalWithProgram = duringLoanValue + afterLoanValue;
            allWithProgram.push(Math.round(totalWithProgram));
            
            // Without program: Only start contributing after loans paid off
            const totalWithoutProgram = calculateRetirementValue(postPayoffContribution, yearsSincePayoff, yearsSincePayoff);
            allWithoutProgram.push(Math.round(totalWithoutProgram));
        }
    }
    
    // Now filter the data for chart display (up to age 65)
    // Show consistent points regardless of starting age: every 2 years on even ages
    // Plus always include the starting age and retirement age
    const ages = [];
    const withProgram = [];
    const withoutProgram = [];
    
    for (let i = 0; i < allAges.length; i++) {
        const age = allAges[i];
        
        // Only include ages up to 65 for chart display
        if (age > RETIREMENT_AGE) break;
        
        // Include if:
        // 1. It's the starting age (first point)
        // 2. It's the retirement age (last point)  
        // 3. It's an even age and at least 2 years from start
        const isStartAge = (i === 0);
        const isRetirementAge = (age === RETIREMENT_AGE);
        const isEvenInterval = (age % 2 === 0 && age > currentAge);
        
        if (isStartAge || isRetirementAge || isEvenInterval) {
            ages.push(age);
            withProgram.push(allWithProgram[i]);
            withoutProgram.push(allWithoutProgram[i]);
        }
    }
    
    return {
        ages,
        withProgram,
        withoutProgram,
        payoffYears,
        annualMatch,
        totalRetirementWith: allWithProgram[allWithProgram.length - 1],
        totalRetirementWithout: allWithoutProgram[allWithoutProgram.length - 1],
        retirementDifference: allWithProgram[allWithProgram.length - 1] - allWithoutProgram[allWithoutProgram.length - 1],
        // Include full yearly data if needed
        allAges,
        allWithProgram,
        allWithoutProgram
    };
}

// Export for use in browser
if (typeof window !== 'undefined') {
    window.StudentLoanCalculator = {
        calculatePayoffYears,
        calculateRemainingBalance,
        calculateRetirementValue,
        calculateNetWorthComparison,
        INVESTMENT_RETURN_RATE,
        LOAN_INTEREST_RATE,
        RETIREMENT_AGE,
        MAX_CALCULATION_AGE
    };
}

// Export for Node.js testing
if (typeof module !== 'undefined' && module.exports) {
    module.exports = {
        calculatePayoffYears,
        calculateRemainingBalance,
        calculateRetirementValue,
        calculateNetWorthComparison,
        INVESTMENT_RETURN_RATE,
        LOAN_INTEREST_RATE,
        RETIREMENT_AGE,
        MAX_CALCULATION_AGE
    };
}