<?php

namespace App\Services;

use Carbon\Carbon;

class FinancialCalculationService
{
    /**
     * Calculate RD (Recurring Deposit) maturity amount
     * Supports: Simple and Compound Interest
     * Supports: Daily, Weekly, Monthly deposits
     */
    public static function calculateRD(
        float $installmentAmount,
        float $annualInterestRate,
        int $duration,
        string $compoundingFrequency = 'monthly',
        string $interestType = 'compound',
        string $durationType = 'monthly'
    ): array {
        // Convert duration to months for standardization
        $durationMonths = match($durationType) {
            'daily' => ceil($duration / 30), // Approximate: 30 days = 1 month
            'weekly' => ceil($duration / 4), // Approximate: 4 weeks = 1 month
            'monthly' => $duration,
            default => $duration
        };
        
        // Calculate number of installments (actual deposits)
        $numberOfInstallments = $duration;
        
        // Total deposits
        $totalDeposits = $installmentAmount * $numberOfInstallments;
        
        if ($interestType === 'simple') {
            // Simple Interest RD Formula
            // Interest = P × n × (n + 1) × r / (2 × 12 × 100)
            // where n = number of installments, r = annual rate, P = installment amount
            $interest = ($installmentAmount * $numberOfInstallments * ($numberOfInstallments + 1) * $annualInterestRate) / (2 * 12 * 100);
            $maturityAmount = $totalDeposits + $interest;
        } else {
            // Compound Interest RD Formula
            // M = P × [((1 + r/n)^(n×t) - 1) / (r/n)] × (1 + r/n)
            
            $rate = $annualInterestRate / 100;
            
            // Determine compounding periods per year
            $n = match($compoundingFrequency) {
                'monthly' => 12,
                'quarterly' => 4,
                'yearly' => 1,
                default => 12
            };
            
            $periodicRate = $rate / $n;
            $years = $durationMonths / 12;
            $totalPeriods = $n * $years;
            
            // For RD, we use the future value of annuity formula
            // Each installment needs to be adjusted based on deposit frequency
            $installmentsPerYear = match($durationType) {
                'daily' => 365,
                'weekly' => 52,
                'monthly' => 12,
                default => 12
            };
            
            $periodicInstallment = $installmentAmount;
            
            // Calculate maturity using annuity formula
            if ($periodicRate > 0) {
                $maturityAmount = $periodicInstallment * $installmentsPerYear * 
                                ((pow(1 + $periodicRate, $totalPeriods) - 1) / $periodicRate) * 
                                (1 + $periodicRate) / ($installmentsPerYear / $n);
            } else {
                $maturityAmount = $totalDeposits;
            }
            
            $interest = $maturityAmount - $totalDeposits;
        }
        
        return [
            'maturity_amount' => round($maturityAmount, 2),
            'total_deposits' => round($totalDeposits, 2),
            'total_interest' => round($interest, 2),
            'installment_amount' => $installmentAmount,
            'number_of_installments' => $numberOfInstallments,
        ];
    }

    /**
     * Calculate FD (Fixed Deposit) maturity amount
     * Supports: Simple and Compound Interest
     */
    public static function calculateFD(
        float $principalAmount,
        float $annualInterestRate,
        int $durationMonths,
        string $compoundingFrequency = 'monthly',
        string $interestType = 'compound'
    ): array {
        $years = $durationMonths / 12;
        $rate = $annualInterestRate / 100;
        
        if ($interestType === 'simple') {
            // Simple Interest FD Formula
            // A = P × (1 + r×t)
            $interest = $principalAmount * $rate * $years;
            $maturityAmount = $principalAmount + $interest;
        } else {
            // Compound Interest FD Formula
            // A = P × (1 + r/n)^(n×t)
            
            // Determine compounding periods per year
            $n = match($compoundingFrequency) {
                'monthly' => 12,
                'quarterly' => 4,
                'yearly' => 1,
                default => 12
            };
            
            $maturityAmount = $principalAmount * pow(1 + ($rate / $n), $n * $years);
            $interest = $maturityAmount - $principalAmount;
        }
        
        return [
            'maturity_amount' => round($maturityAmount, 2),
            'principal_amount' => $principalAmount,
            'total_interest' => round($interest, 2),
            'interest_rate' => $annualInterestRate,
            'duration_years' => $years,
        ];
    }

    /**
     * Calculate MIS (Monthly Income Scheme) - Monthly interest payout
     * Always uses Simple Interest
     * Formula: Monthly Interest = (Principal × Annual Rate) / 12
     * At maturity, principal is returned
     */
    public static function calculateMIS(
        float $principalAmount,
        float $annualInterestRate,
        int $durationMonths
    ): array {
        // MIS always uses simple interest
        // Monthly payout = (P × R) / 12
        $monthlyInterest = ($principalAmount * $annualInterestRate / 100) / 12;
        $totalMonthlyPayouts = $monthlyInterest * $durationMonths;
        
        return [
            'principal_amount' => $principalAmount,
            'monthly_interest_payout' => round($monthlyInterest, 2),
            'total_interest_payout' => round($totalMonthlyPayouts, 2),
            'maturity_amount' => $principalAmount, // Principal returned at maturity
            'total_interest_payouts' => round($totalMonthlyPayouts, 2), // Alias for compatibility
        ];
    }

    /**
     * Calculate maturity date based on deposit date and duration
     */
    public static function calculateMaturityDate(Carbon $depositDate, int $duration, string $durationType = 'monthly'): Carbon
    {
        return match($durationType) {
            'daily' => $depositDate->copy()->addDays($duration),
            'weekly' => $depositDate->copy()->addWeeks($duration),
            'monthly' => $depositDate->copy()->addMonths($duration),
            default => $depositDate->copy()->addMonths($duration),
        };
    }

    /**
     * Calculate remaining installments for RD
     */
    public static function calculateRemainingRDInstallments(
        int $totalInstallments,
        int $collectedInstallments,
        float $installmentAmount
    ): array {
        $remainingInstallments = max(0, $totalInstallments - $collectedInstallments);
        $remainingAmount = $remainingInstallments * $installmentAmount;
        
        return [
            'remaining_installments' => $remainingInstallments,
            'remaining_amount' => round($remainingAmount, 2),
        ];
    }
    
    /**
     * Get display-friendly interest type and compounding info
     */
    public static function getInterestDisplayText(string $interestType, ?string $compoundingFrequency = null): string
    {
        if ($interestType === 'simple') {
            return 'Simple Interest';
        }
        
        $compounding = $compoundingFrequency ? ucfirst($compoundingFrequency) . ' Compounding' : 'Compound';
        return "Compound Interest ({$compounding})";
    }
}
