<?php

namespace App\Http\Controllers;

use App\Models\Application;
use App\Models\Customer;
use App\Models\DisbursedLoan;
use App\Models\LoanType;
use App\Models\PaymentSchedule;
use App\Models\Repayment;
use App\Models\InterestIncome;
use App\Models\PendingPayment;
use App\Services\MobileMoneyService;
use App\Services\SmsService;
use App\Services\CreditScoreService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use App\Mail\LoanApplicationSubmitted;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Carbon\Carbon;

class CustomerDashboardController extends Controller
{
    private $smsService;
    private $mobileMoneyService;
    private $creditScoreService;

    public function __construct(SmsService $smsService, MobileMoneyService $mobileMoneyService, CreditScoreService $creditScoreService)
    {
        $this->smsService = $smsService;
        $this->mobileMoneyService = $mobileMoneyService;
        $this->creditScoreService = $creditScoreService;
    }

    /**
     * Get customer from request
     */
    private function getCustomer(Request $request): ?Customer
    {
        $customerId = $request->query('customer_id');
        
        if (!$customerId) {
            return null;
        }

        return Customer::where('id', $customerId)
            ->where('status', 'Active')
            ->first();
    }

    /**
     * Show customer dashboard (Web)
     */
    public function index()
    {
        $customer = Auth::guard('customer')->user();
        
        // Get applications statistics
        $applications = $customer->applications()->latest()->get();
        $applicationStats = $customer->getApplicationStats();
        
        // Get active applications (submitted, under_review, approved)
        $activeApplications = $customer->applications()
            ->whereIn('status', ['submitted', 'under_review', 'approved'])
            ->latest()
            ->get();

        // Get total approved loan amount
        $totalApprovedAmount = $customer->approvedApplications()->sum('loan_amount');

        // Get recent applications
        $recentApplications = $customer->applications()
            ->with('product')
            ->latest()
            ->limit(5)
            ->get();

        // Calculate application progress for each active application
        $applicationProgress = [];
        foreach ($activeApplications as $application) {
            $progress = $this->calculateApplicationProgress($application);
            
            $applicationProgress[$application->id] = [
                'application' => $application,
                'progress' => $progress,
                'status_color' => $this->getStatusColor($application->status),
                'status_text' => $this->getStatusText($application->status),
            ];
        }

        // Get loan statistics using disbursedloans table
        $loanStats = $customer->getLoanStats();

        // Get upcoming payments from paymentschedule table
        $upcomingPayments = $this->getUpcomingPayments($customer);

        // Get credit score information
        $creditScoreInfo = $this->getCreditScoreInfo($customer);

        return view('customer.dashboard', compact(
            'customer',
            'applications',
            'applicationStats',
            'activeApplications',
            'totalApprovedAmount',
            'recentApplications',
            'applicationProgress',
            'upcomingPayments',
            'loanStats',
            'creditScoreInfo'
        ));
    }

    /**
     * Get credit score information for customer
     */
    private function getCreditScoreInfo(Customer $customer): array
    {
        try {
            $currentScore = $customer->currentCreditScore;
            
            // Debug logging
            \Log::info('Credit score debug', [
                'customer_id' => $customer->id,
                'currentScore_type' => gettype($currentScore),
                'currentScore' => $currentScore,
                'is_object' => is_object($currentScore),
                'is_null' => is_null($currentScore)
            ]);
            
            // Check if $currentScore is not an object or is null
            if (!$currentScore || !is_object($currentScore) || is_numeric($currentScore)) {
                \Log::warning('No valid credit score found for customer', [
                    'customer_id' => $customer->id,
                    'currentScore_value' => $currentScore,
                    'currentScore_type' => gettype($currentScore)
                ]);
                
                return [
                    'current_score' => 300,
                    'score_band' => 'Very Poor',
                    'score_change' => 0,
                    'score_band_class' => 'bg-red-100 text-red-800',
                    'trend' => 'stable',
                    'utilization' => 0,
                    'repayment_rate' => 100,
                    'risk_level' => 'Very High Risk',
                    'factors' => ['Limited Credit History'],
                    'recommendations' => ['Build credit history with small, well-managed loans'],
                    'has_good_credit' => false,
                    'needs_attention' => false,
                    'last_updated' => null,
                ];
            }

            // Check if the object has required methods
            if (!method_exists($currentScore, 'getTrendDescription')) {
                \Log::error('Invalid credit score object', [
                    'customer_id' => $customer->id,
                    'object_type' => get_class($currentScore),
                    'available_methods' => get_class_methods($currentScore)
                ]);
                
                return [
                    'current_score' => 300,
                    'score_band' => 'Very Poor',
                    'score_change' => 0,
                    'score_band_class' => 'bg-red-100 text-red-800',
                    'trend' => 'stable',
                    'utilization' => 0,
                    'repayment_rate' => 100,
                    'risk_level' => 'Very High Risk',
                    'factors' => ['Limited Credit History'],
                    'recommendations' => ['Build credit history with small, well-managed loans'],
                    'has_good_credit' => false,
                    'needs_attention' => false,
                    'last_updated' => null,
                ];
            }

            // Use null-safe operator with defaults
            return [
                'current_score' => $currentScore->credit_score ?? 300,
                'score_band' => $currentScore->score_band ?? 'Very Poor',
                'score_change' => $currentScore->score_change ?? 0,
                'score_band_class' => $currentScore->score_band_class ?? 'bg-red-100 text-red-800',
                'trend' => $currentScore->getTrendDescription() ?? 'stable',
                'utilization' => $currentScore->credit_utilization_ratio ?? 0,
                'repayment_rate' => $currentScore->on_time_repayment_rate ?? 100,
                'risk_level' => $currentScore->risk_level ?? 'Very High Risk',
                'factors' => $currentScore->getScoreFactors() ?? ['Limited Credit History'],
                'recommendations' => $currentScore->getImprovementRecommendations() ?? ['Build credit history with small, well-managed loans'],
                'has_good_credit' => ($currentScore->credit_score ?? 300) >= 600,
                'needs_attention' => $currentScore->needs_attention ?? false,
                'last_updated' => $currentScore->score_date ?? null,
            ];
            
        } catch (\Exception $e) {
            \Log::error('Error in getCreditScoreInfo', [
                'customer_id' => $customer->id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            
            return [
                'current_score' => 300,
                'score_band' => 'Very Poor',
                'score_change' => 0,
                'score_band_class' => 'bg-red-100 text-red-800',
                'trend' => 'stable',
                'utilization' => 0,
                'repayment_rate' => 100,
                'risk_level' => 'Very High Risk',
                'factors' => ['Limited Credit History'],
                'recommendations' => ['Build credit history with small, well-managed loans'],
                'has_good_credit' => false,
                'needs_attention' => false,
                'last_updated' => null,
            ];
        }
    }

    /**
     * Get dashboard data (API)
     */
    public function getDashboardData(Request $request): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        // Get credit score information
        $creditScoreInfo = $this->getCreditScoreInfo($customer);

        // Get dashboard data for this customer
        return response()->json([
            'success' => true,
            'message' => 'Dashboard data retrieved successfully',
            'data' => [
                'customer' => [
                    'id' => $customer->id,
                    'customer_number' => $customer->customer_number,
                    'name' => $customer->customer,
                    'email' => $customer->email,
                    'phone' => $customer->phone,
                    'profile_picture' => $customer->docpath ? asset('storage/' . $customer->docpath) : null,
                ],
                'application_stats' => $this->getApplicationStatsData($customer),
                'loan_stats' => $this->getLoanStatsData($customer),
                'active_applications' => $this->getActiveApplicationsData($customer),
                'active_loans' => $this->getActiveLoansData($customer),
                'upcoming_payments' => $this->getUpcomingPaymentsData($customer),
                'credit_score' => $creditScoreInfo,
            ]
        ]);
    }

    /**
     * Get application statistics (API)
     */
    public function getApplicationStats(Request $request): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        return response()->json([
            'success' => true,
            'message' => 'Application stats retrieved successfully',
            'data' => $this->getApplicationStatsData($customer)
        ]);
    }

    /**
     * Get loan statistics (API)
     */
    public function getLoanStats(Request $request): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        return response()->json([
            'success' => true,
            'message' => 'Loan stats retrieved successfully',
            'data' => $this->getLoanStatsData($customer)
        ]);
    }

    /**
     * Get credit score information (API)
     */
    public function getCreditScore(Request $request): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        $creditScoreInfo = $this->getCreditScoreInfo($customer);

        return response()->json([
            'success' => true,
            'message' => 'Credit score information retrieved successfully',
            'data' => $creditScoreInfo
        ]);
    }

    /**
     * Get credit score history (API)
     */
    public function getCreditScoreHistory(Request $request): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        $history = $customer->creditScoreHistory()
            ->orderBy('score_date', 'desc')
            ->limit(12) // Last 12 months
            ->get()
            ->map(function($score) {
                return [
                    'score_date' => $score->score_date->format('Y-m-d'),
                    'credit_score' => $score->credit_score,
                    'score_band' => $score->score_band,
                    'score_change' => $score->score_change,
                    'change_reason' => $score->change_reason,
                    'change_type' => $score->change_type,
                ];
            });

        return response()->json([
            'success' => true,
            'message' => 'Credit score history retrieved successfully',
            'data' => $history
        ]);
    }

    /**
     * Get applications list (API)
     */
    public function getApplications(Request $request): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        $applications = $customer->applications()
            ->with('product')
            ->latest()
            ->get()
            ->map(function($application) {
                return [
                    'id' => $application->id,
                    'application_number' => $application->application_number,
                    'loan_amount' => $application->loan_amount,
                    'loan_tenure' => $application->loan_tenure,
                    'status' => $application->status,
                    'status_text' => $this->getStatusText($application->status),
                    'status_color' => $this->getStatusColor($application->status),
                    'progress' => $this->calculateApplicationProgress($application),
                    'submitted_at' => $application->submitted_at,
                    'product_name' => $application->product->product ?? 'N/A',
                    'estimated_monthly_payment' => $application->estimated_monthly_payment,
                ];
            });

        return response()->json([
            'success' => true,
            'message' => 'Applications retrieved successfully',
            'data' => $applications
        ]);
    }

    /**
     * Get application details (API)
     */
    public function getApplicationDetails(Request $request, $id): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        $application = $customer->applications()
            ->with('product')
            ->find($id);

        if (!$application) {
            return response()->json([
                'success' => false,
                'message' => 'Application not found'
            ], 404);
        }

        return response()->json([
            'success' => true,
            'message' => 'Application details retrieved successfully',
            'data' => [
                'application' => $application,
                'progress' => $this->calculateApplicationProgress($application),
                'status_text' => $this->getStatusText($application->status),
                'status_color' => $this->getStatusColor($application->status),
            ]
        ]);
    }

    /**
     * Submit loan application (API)
     */
  
/**
 * Submit loan application (API/Web)
 */


    /**
     * Withdraw application (API)
     */
    public function withdrawApplication(Request $request, $id): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        $application = $customer->applications()->find($id);

        if (!$application) {
            return response()->json([
                'success' => false,
                'message' => 'Application not found'
            ], 404);
        }

        // Only allow withdrawal for draft or submitted applications
        if (!in_array($application->status, ['draft', 'submitted'])) {
            return response()->json([
                'success' => false,
                'message' => 'You cannot withdraw this application as it is already being processed.'
            ], 400);
        }

        $application->update([
            'status' => 'withdrawn',
            'admin_notes' => 'Application withdrawn by customer on ' . now()->format('Y-m-d H:i:s'),
        ]);

        \Log::info('Application withdrawn by customer', [
            'customer_id' => $customer->id,
            'application_id' => $application->id,
            'application_number' => $application->application_number,
        ]);

        // Send withdrawal confirmation SMS
        try {
            $smsMessage = "Dear {$customer->customer}, your loan application #{$application->application_number} has been withdrawn successfully.";
            $this->smsService->sendSms($customer->phone, $smsMessage);
            
            \Log::info('Application withdrawal SMS sent successfully', [
                'customer_id' => $customer->id,
                'application_id' => $application->id
            ]);
        } catch (\Exception $e) {
            \Log::error('Failed to send withdrawal SMS', [
                'customer_id' => $customer->id,
                'application_id' => $application->id,
                'error' => $e->getMessage()
            ]);
        }

        return response()->json([
            'success' => true,
            'message' => 'Application has been withdrawn successfully.'
        ]);
    }

    /**
     * Get loans list (API)
     */
    public function getLoans(Request $request): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        $loans = $customer->activeDisbursedLoans()
            ->with('loanType')
            ->latest('disburseddate')
            ->get()
            ->map(function($loan) {
                return [
                    'id' => $loan->loanid,
                    'loan_number' => $loan->loannumber,
                    'loan_type' => $loan->loanType->product ?? 'N/A',
                    'amount' => $loan->amount,
                    'disbursed_date' => $loan->disburseddate,
                    'total_balance' => $loan->totalbalance,
                    'principal_balance' => $loan->principalbalance,
                    'interest_balance' => $loan->interestbalance,
                    'status' => $loan->status,
                    'collection_progress' => $loan->getCollectionProgressAttribute(),
                    'next_payment_due_date' => $loan->next_payment_due_date,
                    'next_due_amount' => $loan->next_due_amount,
                    'is_overdue' => $loan->is_overdue,
                ];
            });

        return response()->json([
            'success' => true,
            'message' => 'Loans retrieved successfully',
            'data' => $loans
        ]);
    }

    /**
     * Get loan details (API)
     */
    public function getLoanDetails(Request $request, $id): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        $loan = $customer->disbursedLoans()
            ->with(['loanType', 'paymentSchedules' => function($query) {
                $query->orderBy('paymentdate', 'asc');
            }])
            ->find($id);

        if (!$loan) {
            return response()->json([
                'success' => false,
                'message' => 'Loan not found'
            ], 404);
        }

        return response()->json([
            'success' => true,
            'message' => 'Loan details retrieved successfully',
            'data' => [
                'loan' => $loan,
                'total_repayment' => $loan->getTotalRepaymentAttribute(),
                'collection_progress' => $loan->getCollectionProgressAttribute(),
                'payment_schedule' => $loan->paymentSchedules,
            ]
        ]);
    }

    /**
     * Get upcoming payments (API)
     */
    public function getUpcomingPaymentsApi(Request $request): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        return response()->json([
            'success' => true,
            'message' => 'Upcoming payments retrieved successfully',
            'data' => $this->getUpcomingPaymentsData($customer)
        ]);
    }

    /**
     * Process payment (API)
     */
    public function processPayment(Request $request): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        \Log::info('Payment process started', [
            'customer_id' => $customer->id,
            'request_data' => $request->all()
        ]);

        $validator = Validator::make($request->all(), [
            'loan_id' => 'required|exists:disbursedloans,loanid',
            'amount' => 'required|numeric|min:1',
            'mobile_number' => 'required|string|max:15',
            'payment_method' => 'required|in:airtel,mtn,zamtel',
            'description' => 'nullable|string'
        ]);

        if ($validator->fails()) {
            \Log::error('Payment validation failed', [
                'errors' => $validator->errors()->toArray()
            ]);
            
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            DB::beginTransaction();

            // Get the loan details
            $loan = DisbursedLoan::where('loanid', $request->loan_id)
                                ->where('customerid', $customer->id)
                                ->firstOrFail();

            \Log::info('Loan found for payment', [
                'loan_id' => $loan->loanid,
                'loan_number' => $loan->loannumber
            ]);

            // Prepare payment data for mobile money API
            $paymentData = [
                'mobile_number' => $request->mobile_number,
                'amount' => $request->amount,
                'customer_name' => $customer->customer,
                'email' => $customer->email,
                'company_id' => $customer->companyid ?? 1,
                'loan_id' => $request->loan_id,
                'description' => $request->description ?? 'Loan repayment payment'
            ];

            \Log::info('Calling mobile money service', $paymentData);

            // Initiate mobile money payment
            $paymentResult = $this->mobileMoneyService->initiatePayment($paymentData);

            \Log::info('Mobile money service response', $paymentResult);

            if (!$paymentResult['success']) {
                throw new \Exception('Mobile money payment failed: ' . ($paymentResult['error'] ?? 'Unknown error'));
            }

            // Store pending payment record
            $pendingPayment = PendingPayment::create([
                'customer_id' => $customer->id,
                'loan_id' => $request->loan_id,
                'transaction_id' => $paymentResult['transaction_id'],
                'external_id' => $paymentResult['external_id'],
                'amount' => $request->amount,
                'mobile_number' => $request->mobile_number,
                'payment_method' => $request->payment_method,
                'status' => $paymentResult['status'],
                'company_id' => $customer->companyid ?? 1,
            ]);

            DB::commit();

            \Log::info('Mobile money payment initiated successfully', [
                'customer_id' => $customer->id,
                'loan_id' => $request->loan_id,
                'transaction_id' => $paymentResult['transaction_id'],
                'pending_payment_id' => $pendingPayment->id
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Payment initiated successfully',
                'transaction_id' => $paymentResult['transaction_id'],
                'external_id' => $paymentResult['external_id'],
                'status' => $paymentResult['status'],
                'pending_payment_id' => $pendingPayment->id,
                'polling_required' => $paymentResult['status'] === 'Pending'
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            
            \Log::error('Mobile money payment processing failed', [
                'customer_id' => $customer->id,
                'loan_id' => $request->loan_id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            return response()->json([
                'success' => false,
                'message' => 'Payment processing failed: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Check payment status (API)
     */
    public function checkPaymentStatus(Request $request): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        $validator = Validator::make($request->all(), [
            'transaction_id' => 'required|string',
            'loan_id' => 'required|exists:disbursedloans,loanid',
            'pending_payment_id' => 'required|exists:pending_payments,id'
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            // Check transaction status
            $statusResult = $this->mobileMoneyService->pollTransactionStatus(
                $request->transaction_id,
                $customer->companyid ?? 1
            );

            if ($statusResult['success']) {
                // Payment successful - process the payment
                return $this->processSuccessfulPayment($customer, $request->loan_id, $request->transaction_id, $request->pending_payment_id, $statusResult);
            } else {
                // Update pending payment status
                PendingPayment::where('id', $request->pending_payment_id)
                    ->where('customer_id', $customer->id)
                    ->update(['status' => $statusResult['status']]);

                return response()->json([
                    'success' => false,
                    'message' => 'Payment failed or is still processing',
                    'status' => $statusResult['status'],
                    'error' => $statusResult['error'] ?? 'Payment processing failed'
                ]);
            }

        } catch (\Exception $e) {
            \Log::error('Payment status check failed', [
                'customer_id' => $customer->id,
                'transaction_id' => $request->transaction_id,
                'error' => $e->getMessage()
            ]);

            return response()->json([
                'success' => false,
                'message' => 'Status check failed: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Process successful payment completion
     */
    private function processSuccessfulPayment($customer, $loanId, $transactionId, $pendingPaymentId, $statusResult): JsonResponse
    {
        try {
            DB::beginTransaction();

            // Get the loan details
            $loan = DisbursedLoan::where('loanid', $loanId)
                                ->where('customerid', $customer->id)
                                ->firstOrFail();

            // Get pending payment record
            $pendingPayment = PendingPayment::where('id', $pendingPaymentId)
                                          ->where('customer_id', $customer->id)
                                          ->firstOrFail();

            $totalAmount = $pendingPayment->amount;
            
            // Calculate interest and principal allocation based on outstanding balances
            $interestBalance = $loan->interestbalance ?? 0;
            $principalBalance = $loan->principalbalance ?? 0;
            
            $interestAmount = 0;
            $principalAmount = 0;
            
            // Allocation logic: Pay interest first, then principal
            if ($interestBalance > 0) {
                $interestAmount = min($totalAmount, $interestBalance);
                $remainingAmount = $totalAmount - $interestAmount;
                $principalAmount = min($remainingAmount, $principalBalance);
            } else {
                $principalAmount = min($totalAmount, $principalBalance);
            }

            // Map payment method to display name
            $paymentMethodMap = [
                'airtel' => 'Airtel Mobile Money',
                'mtn' => 'MTN Mobile Money', 
                'zamtel' => 'Zamtel Mobile Money'
            ];

            $selectedMethod = $paymentMethodMap[$pendingPayment->payment_method] ?? 'Mobile Money';

            // Create repayment record
            $repayment = Repayment::create([
                'customerid' => $customer->id,
                'rpid' => $loan->loantypeid,
                'rloanid' => $loan->loanid,
                'rtotal' => $totalAmount,
                'rinterest' => $interestAmount,
                'rprincipal' => $principalAmount,
                'rdate' => now()->format('Y-m-d'),
                'userid' => 0,
                'branchid' => $loan->branchid,
                'companyid' => $loan->companyid,
                'pmethod' => 'Mobile Money',
                'paccount' => $selectedMethod,
                'transtype' => 'repayment',
                'status' => 'paid',
                'transaction_reference' => $transactionId,
                'mobile_number' => $pendingPayment->mobile_number,
                'description' => $pendingPayment->description
            ]);

            // Record interest payment in interestincome table if interest was paid
            if ($interestAmount > 0) {
                InterestIncome::create([
                    'iloanid' => $loan->loanid,
                    'customerid' => $customer->id,
                    'ipid' => $loan->loantypeid,
                    'charge' => $interestAmount,
                    'chargeddate' => now()->format('Y-m-d'),
                    'poster' => 0,
                    'branchid' => $loan->branchid,
                    'companyid' => $loan->companyid
                ]);
            }

            // Update the disbursed loan balances
            $loan->update([
                'totalprincipalpaid' => $loan->totalprincipalpaid + $principalAmount,
                'totalinterestpaid' => $loan->totalinterestpaid + $interestAmount,
                'totalpaid' => $loan->totalpaid + $totalAmount,
                'totalbalance' => max(0, $loan->totalbalance - $totalAmount),
                'principalbalance' => max(0, $loan->principalbalance - $principalAmount),
                'interestbalance' => max(0, $loan->interestbalance - $interestAmount),
                'lastpaymentdate' => now(),
                'lastpaymentamount' => $totalAmount
            ]);

            // Update payment schedule
            $this->updatePaymentSchedule($loan, $totalAmount);

            // Update pending payment status to completed
            $pendingPayment->update([
                'status' => 'successful',
                'completed_at' => now()
            ]);

            // ==================== CREDIT SCORE UPDATE ====================
            try {
                // Check if payment is on-time by comparing with scheduled payment date
                $isOnTime = $this->isPaymentOnTime($loan, $totalAmount);
                
                // Update credit score for repayment event
                $this->creditScoreService->updateScoreForEvent(
                    $customer->id,
                    'repayment_made',
                    [
                        'loan_id' => $loan->loanid,
                        'amount' => $totalAmount,
                        'is_on_time' => $isOnTime,
                        'principal_amount' => $principalAmount,
                        'interest_amount' => $interestAmount,
                        'transaction_id' => $transactionId,
                        'payment_method' => $pendingPayment->payment_method,
                        'days_late' => $isOnTime ? 0 : $this->calculateDaysLate($loan)
                    ]
                );

                \Log::info('Credit score updated for repayment', [
                    'customer_id' => $customer->id,
                    'loan_id' => $loan->loanid,
                    'amount' => $totalAmount,
                    'is_on_time' => $isOnTime,
                    'transaction_id' => $transactionId
                ]);

            } catch (\Exception $creditScoreException) {
                \Log::error('Failed to update credit score for repayment', [
                    'customer_id' => $customer->id,
                    'loan_id' => $loan->loanid,
                    'error' => $creditScoreException->getMessage(),
                    'trace' => $creditScoreException->getTraceAsString()
                ]);
                // Don't fail the payment if credit score update fails
            }
            // ==================== END CREDIT SCORE UPDATE ====================

            DB::commit();

            // Send payment confirmation SMS
            try {
                $smsMessage = "Dear {$customer->customer}, your payment of ZMW {$totalAmount} for loan #{$loan->loannumber} has been processed successfully. Transaction ID: {$transactionId}";
                $this->smsService->sendSms($customer->phone, $smsMessage);
            } catch (\Exception $e) {
                \Log::error('Failed to send payment confirmation SMS', [
                    'customer_id' => $customer->id,
                    'error' => $e->getMessage()
                ]);
            }

            \Log::info('Mobile money payment completed successfully', [
                'customer_id' => $customer->id,
                'loan_id' => $loanId,
                'transaction_id' => $transactionId,
                'repayment_id' => $repayment->id,
                'amount' => $totalAmount,
                'principal' => $principalAmount,
                'interest' => $interestAmount
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Payment processed successfully',
                'reference_number' => $transactionId,
                'amount' => $totalAmount,
                'repayment_id' => $repayment->id,
                'allocation' => [
                    'principal' => $principalAmount,
                    'interest' => $interestAmount,
                    'remaining_principal_balance' => $loan->principalbalance,
                    'remaining_interest_balance' => $loan->interestbalance
                ],
                'credit_score_updated' => true // Indicate that credit score was updated
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            
            \Log::error('Failed to process successful payment', [
                'customer_id' => $customer->id,
                'loan_id' => $loanId,
                'transaction_id' => $transactionId,
                'error' => $e->getMessage()
            ]);

            return response()->json([
                'success' => false,
                'message' => 'Payment completion failed: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Check if payment is on-time by comparing with scheduled payment date
     */
    private function isPaymentOnTime($loan, $amountPaid): bool
    {
        try {
            // Find the earliest scheduled payment that hasn't been paid
            $scheduledPayment = PaymentSchedule::where('loanid', $loan->loanid)
                ->where('status', 'scheduled')
                ->where('transactiontype', 'Payment')
                ->orderBy('paymentdate', 'asc')
                ->first();

            if (!$scheduledPayment) {
                return true; // No scheduled payments, consider it on-time
            }

            // Check if payment date is on or before due date
            $paymentDate = now();
            $dueDate = Carbon::parse($scheduledPayment->paymentdate);
            
            // Allow 1-day grace period
            return $paymentDate->lte($dueDate->addDay());
            
        } catch (\Exception $e) {
            \Log::error('Error checking payment timeliness', [
                'loan_id' => $loan->loanid,
                'error' => $e->getMessage()
            ]);
            return true; // Default to on-time if we can't determine
        }
    }

    /**
     * Calculate days late for payment
     */
    private function calculateDaysLate($loan): int
    {
        try {
            $scheduledPayment = PaymentSchedule::where('loanid', $loan->loanid)
                ->where('status', 'scheduled')
                ->where('transactiontype', 'Payment')
                ->orderBy('paymentdate', 'asc')
                ->first();

            if (!$scheduledPayment) {
                return 0;
            }

            $dueDate = Carbon::parse($scheduledPayment->paymentdate);
            $paymentDate = now();
            
            return max(0, $paymentDate->diffInDays($dueDate, false));
            
        } catch (\Exception $e) {
            \Log::error('Error calculating days late', [
                'loan_id' => $loan->loanid,
                'error' => $e->getMessage()
            ]);
            return 0;
        }
    }

    /**
     * Update payment schedule when payment is made
     */
    private function updatePaymentSchedule($loan, $amountPaid)
    {
        try {
            // Find the earliest scheduled payment that hasn't been paid
            $scheduledPayment = PaymentSchedule::where('loanid', $loan->loanid)
                ->where('status', 'scheduled')
                ->where('transactiontype', 'Payment')
                ->orderBy('paymentdate', 'asc')
                ->first();

            if ($scheduledPayment) {
                // Check if payment is overdue
                $dueDate = Carbon::parse($scheduledPayment->paymentdate);
                $isOverdue = now()->gt($dueDate);
                
                // Mark as paid if the amount matches or is greater
                if ($amountPaid >= $scheduledPayment->totalamount) {
                    $scheduledPayment->update([
                        'status' => 'paid',
                        'paid_date' => now(),
                        'paid_principal' => $scheduledPayment->principalamount,
                        'paid_interest' => $scheduledPayment->interestamount,
                        'total_paid' => $scheduledPayment->totalamount
                    ]);
                } else {
                    // Partial payment - handle partial payment logic
                    $scheduledPayment->update([
                        'paid_principal' => $amountPaid * 0.7, // Assume 70% to principal, 30% to interest
                        'paid_interest' => $amountPaid * 0.3,
                        'total_paid' => $amountPaid,
                        'status' => $isOverdue ? 'overdue' : 'partially_paid'
                    ]);
                }
                
                // If payment is overdue, we should also update credit score for missed payment
                if ($isOverdue) {
                    try {
                        $this->creditScoreService->updateScoreForEvent(
                            $loan->customerid,
                            'payment_missed',
                            [
                                'loan_id' => $loan->loanid,
                                'due_date' => $scheduledPayment->paymentdate,
                                'days_late' => now()->diffInDays($dueDate),
                                'scheduled_amount' => $scheduledPayment->totalamount,
                                'paid_amount' => $amountPaid
                            ]
                        );
                        
                        \Log::warning('Credit score penalized for overdue payment', [
                            'customer_id' => $loan->customerid,
                            'loan_id' => $loan->loanid,
                            'due_date' => $scheduledPayment->paymentdate,
                            'days_late' => now()->diffInDays($dueDate)
                        ]);
                        
                    } catch (\Exception $e) {
                        \Log::error('Failed to update credit score for overdue payment', [
                            'customer_id' => $loan->customerid,
                            'loan_id' => $loan->loanid,
                            'error' => $e->getMessage()
                        ]);
                    }
                }
            }
        } catch (\Exception $e) {
            \Log::error('Failed to update payment schedule', [
                'loan_id' => $loan->loanid,
                'error' => $e->getMessage()
            ]);
        }
    }

    /**
     * Get profile (API)
     */
    public function getProfile(Request $request): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        // Get credit score information
        $creditScoreInfo = $this->getCreditScoreInfo($customer);

        return response()->json([
            'success' => true,
            'message' => 'Profile retrieved successfully',
            'data' => [
                'customer' => [
                    'id' => $customer->id,
                    'customer_number' => $customer->customer_number,
                    'name' => $customer->customer,
                    'email' => $customer->email,
                    'phone' => $customer->phone,
                    'office_phone' => $customer->office_phone,
                    'address' => $customer->address,
                    'town' => $customer->town,
                    'province' => $customer->province,
                    'occupation' => $customer->occupation,
                    'company' => $customer->company,
                    'income' => $customer->income,
                    'profile_picture' => $customer->docpath ? asset('storage/' . $customer->docpath) : null,
                    'status' => $customer->status,
                    'verification_status' => $customer->verification_status,
                    'created_at' => $customer->created_at,
                ],
                'credit_score' => $creditScoreInfo
            ]
        ]);
    }

    /**
     * Update profile (API)
     */
    public function updateProfile(Request $request): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        $validator = Validator::make($request->all(), [
            'customer' => 'required|string|max:255',
            'phone' => 'required|string|max:25',
            'office_phone' => 'nullable|string|max:25',
            'address' => 'required|string',
            'town' => 'required|string',
            'province' => 'required|string',
            'occupation' => 'nullable|string|max:255',
            'company' => 'nullable|string|max:255',
            'income' => 'nullable|numeric|min:0',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }

        $customer->update($request->only([
            'customer', 'phone', 'office_phone', 'address', 'town', 
            'province', 'occupation', 'company', 'income'
        ]));

        // Send profile update confirmation SMS
        try {
            $smsMessage = "Dear {$customer->customer}, your profile has been updated successfully. If you didn't make this change, please contact support immediately.";
            $this->smsService->sendSms($customer->phone, $smsMessage);
            
            \Log::info('Profile update SMS sent successfully', [
                'customer_id' => $customer->id,
                'customer_phone' => $customer->phone
            ]);
        } catch (\Exception $e) {
            \Log::error('Failed to send profile update SMS', [
                'customer_id' => $customer->id,
                'error' => $e->getMessage()
            ]);
        }

        return response()->json([
            'success' => true,
            'message' => 'Profile updated successfully',
            'data' => [
                'customer' => $customer
            ]
        ]);
    }

    /**
     * Upload profile photo (API)
     */
    public function uploadProfilePhoto(Request $request): JsonResponse
    {
        $customer = $this->getCustomer($request);
        
        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not found or inactive'
            ], 404);
        }

        $validator = Validator::make($request->all(), [
            'profile_photo' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048'
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            if ($request->hasFile('profile_photo')) {
                // Delete old profile photo if exists
                if ($customer->docpath && Storage::disk('public')->exists($customer->docpath)) {
                    Storage::disk('public')->delete($customer->docpath);
                }

                // Store new profile photo
                $path = $request->file('profile_photo')->store('customer-photos', 'public');
                $customer->update(['docpath' => $path]);

                return response()->json([
                    'success' => true,
                    'message' => 'Profile photo uploaded successfully',
                    'data' => [
                        'profile_picture_url' => asset('storage/' . $path)
                    ]
                ]);
            }

            return response()->json([
                'success' => false,
                'message' => 'No profile photo provided'
            ], 400);

        } catch (\Exception $e) {
            \Log::error('Profile photo upload failed', [
                'customer_id' => $customer->id,
                'error' => $e->getMessage()
            ]);

            return response()->json([
                'success' => false,
                'message' => 'Failed to upload profile photo: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * HELPER METHODS FOR DATA PROCESSING
     */

    /**
     * Get application statistics data
     */
    private function getApplicationStatsData(Customer $customer): array
    {
        return $customer->getApplicationStats();
    }

    /**
     * Get loan statistics data
     */
    private function getLoanStatsData(Customer $customer): array
    {
        return $customer->getLoanStats();
    }

    /**
     * Get active applications data
     */
    private function getActiveApplicationsData(Customer $customer): array
    {
        return $customer->applications()
            ->whereIn('status', ['submitted', 'under_review', 'approved'])
            ->with('product')
            ->latest()
            ->get()
            ->map(function($application) {
                return [
                    'id' => $application->id,
                    'application_number' => $application->application_number,
                    'loan_amount' => $application->loan_amount,
                    'loan_tenure' => $application->loan_tenure,
                    'status' => $application->status,
                    'status_text' => $this->getStatusText($application->status),
                    'status_color' => $this->getStatusColor($application->status),
                    'progress' => $this->calculateApplicationProgress($application),
                    'submitted_at' => $application->submitted_at,
                    'product_name' => $application->product->product ?? 'N/A',
                ];
            })
            ->toArray();
    }

    /**
     * Get active loans data
     */
    private function getActiveLoansData(Customer $customer): array
    {
        return $customer->activeDisbursedLoans()
            ->with('loanType')
            ->latest('disburseddate')
            ->get()
            ->map(function($loan) {
                return [
                    'id' => $loan->loanid,
                    'loan_number' => $loan->loannumber,
                    'loan_type' => $loan->loanType->product ?? 'N/A',
                    'amount' => $loan->amount,
                    'disbursed_date' => $loan->disburseddate,
                    'total_balance' => $loan->totalbalance,
                    'principal_balance' => $loan->principalbalance,
                    'interest_balance' => $loan->interestbalance,
                    'status' => $loan->status,
                    'collection_progress' => $loan->getCollectionProgressAttribute(),
                    'next_payment_due_date' => $loan->next_payment_due_date,
                    'next_due_amount' => $loan->next_due_amount,
                    'is_overdue' => $loan->is_overdue,
                ];
            })
            ->toArray();
    }

    /**
     * Get upcoming payments data
     */
    private function getUpcomingPaymentsData(Customer $customer): array
    {
        return $this->getUpcomingPayments($customer);
    }

    /**
     * Get upcoming payments from paymentschedule table
     */
    private function getUpcomingPayments($customer): array
    {
        try {
            $upcomingPayments = PaymentSchedule::whereHas('loan', function($query) use ($customer) {
                    $query->where('customerid', $customer->id)
                          ->where('status', 'active');
                })
                ->where('status', 'scheduled')
                ->where('paymentdate', '>=', now())
                ->where('transactiontype', 'Payment')
                ->orderBy('paymentdate', 'asc')
                ->limit(5)
                ->get()
                ->map(function($payment) {
                    return [
                        'loan_number' => $payment->loannumber,
                        'due_date' => $payment->paymentdate,
                        'amount' => $payment->totalamount,
                        'installment_number' => $payment->installment_number,
                    ];
                })
                ->toArray();

            return $upcomingPayments;

        } catch (\Exception $e) {
            \Log::error('Error fetching upcoming payments', [
                'customer_id' => $customer->id,
                'error' => $e->getMessage()
            ]);
            
            return [];
        }
    }

    /**
     * Calculate monthly payment for loan
     */
    private function calculateMonthlyPayment($loanAmount, $interestRate, $loanTenure): float
    {
        if ($interestRate > 0) {
            return ($loanAmount * $interestRate * pow(1 + $interestRate, $loanTenure)) / 
                   (pow(1 + $interestRate, $loanTenure) - 1);
        } else {
            return $loanAmount / $loanTenure;
        }
    }

    /**
     * Calculate application progress percentage
     */
    private function calculateApplicationProgress($application): int
    {
        $statusWeights = [
            'draft' => 25,
            'submitted' => 50,
            'under_review' => 75,
            'approved' => 90,
            'disbursed' => 100,
            'rejected' => 100,
            'withdrawn' => 100,
        ];

        return $statusWeights[$application->status] ?? 0;
    }

    /**
     * Get status color for UI
     */
    private function getStatusColor($status): string
    {
        $colors = [
            'draft' => 'gray',
            'submitted' => 'blue',
            'under_review' => 'yellow',
            'approved' => 'green',
            'disbursed' => 'purple',
            'rejected' => 'red',
            'withdrawn' => 'orange',
        ];

        return $colors[$status] ?? 'gray';
    }

    /**
     * Get status text for UI
     */
    private function getStatusText($status): string
    {
        $texts = [
            'draft' => 'Draft',
            'submitted' => 'Submitted',
            'under_review' => 'Under Review',
            'approved' => 'Approved',
            'disbursed' => 'Disbursed',
            'rejected' => 'Rejected',
            'withdrawn' => 'Withdrawn',
        ];

        return $texts[$status] ?? 'Unknown';
    }

    /**
     * WEB METHODS (Keep your existing web methods)
     */

    /**
     * Show customer profile (Web)
     */
    public function profile()
    {
        $customer = Auth::guard('customer')->user();
        $applicationStats = $customer->getApplicationStats();
        $loanStats = $customer->getLoanStats();
        $creditScoreInfo = $this->getCreditScoreInfo($customer);
        
        return view('customer.profile', compact('customer', 'applicationStats', 'loanStats', 'creditScoreInfo'));
    }

    /**
     * Update customer profile (Web)
     */
    public function updateProfileWeb(Request $request)
    {
        $customer = Auth::guard('customer')->user();
        
        $request->validate([
            'customer' => 'required|string|max:255',
            'phone' => 'required|string|max:25',
            'office_phone' => 'nullable|string|max:25',
            'address' => 'required|string',
            'town' => 'required|string',
            'province' => 'required|string',
            'occupation' => 'nullable|string|max:255',
            'company' => 'nullable|string|max:255',
            'income' => 'nullable|numeric|min:0',
        ]);

        $customer->update($request->only([
            'customer', 'phone', 'office_phone', 'address', 'town', 
            'province', 'occupation', 'company', 'income'
        ]));

        // Send profile update confirmation SMS
        try {
            $smsMessage = "Dear {$customer->customer}, your profile has been updated successfully. If you didn't make this change, please contact support immediately.";
            $this->smsService->sendSms($customer->phone, $smsMessage);
            
            \Log::info('Profile update SMS sent successfully', [
                'customer_id' => $customer->id,
                'customer_phone' => $customer->phone
            ]);
        } catch (\Exception $e) {
            \Log::error('Failed to send profile update SMS', [
                'customer_id' => $customer->id,
                'error' => $e->getMessage()
            ]);
        }

        return redirect()->route('customer.profile')->with('success', 'Profile updated successfully!');
    }

    /**
     * Show loan application form (Web)
     */
    public function showLoanApplication()
    {
        $customer = Auth::guard('customer')->user();
        
        $loanTypes = LoanType::active()->get();
        
        return view('customer.loan-application', compact('customer', 'loanTypes'));
    }

    /**
     * Show customer's applications (Web)
     */
    public function myApplications()
    {
        $customer = Auth::guard('customer')->user();
        $applications = $customer->applications()
            ->with('product')
            ->latest()
            ->paginate(10);

        $applicationStats = $customer->getApplicationStats();
        $loanStats = $customer->getLoanStats();
        $creditScoreInfo = $this->getCreditScoreInfo($customer);

        return view('customer.my-applications', compact('customer', 'applications', 'applicationStats', 'loanStats', 'creditScoreInfo'));
    }

    /**
     * Show application details (Web)
     */
    public function showApplication($id)
    {
        $customer = Auth::guard('customer')->user();
        $application = $customer->applications()
            ->with('product')
            ->findOrFail($id);

        $progress = $this->calculateApplicationProgress($application);
        $statusColor = $this->getStatusColor($application->status);
        $statusText = $this->getStatusText($application->status);

        $applicationStats = $customer->getApplicationStats();
        $loanStats = $customer->getLoanStats();
        $creditScoreInfo = $this->getCreditScoreInfo($customer);

        return view('customer.application-details', compact(
            'customer', 
            'application', 
            'progress', 
            'statusColor', 
            'statusText',
            'applicationStats',
            'loanStats',
            'creditScoreInfo'
        ));
    }

    /**
     * Show customer's active loans (Web)
     */
    public function myLoans()
    {
        $customer = Auth::guard('customer')->user();
        
        $loanStats = $customer->getLoanStats();
        $activeLoans = $customer->activeDisbursedLoans()
            ->with('loanType')
            ->latest('disburseddate')
            ->paginate(10);

        $applicationStats = $customer->getApplicationStats();
        $creditScoreInfo = $this->getCreditScoreInfo($customer);

        return view('customer.my-loans', compact('customer', 'activeLoans', 'loanStats', 'applicationStats', 'creditScoreInfo'));
    }

    /**
     * Show loan details (Web)
     */
    public function showLoan($id)
    {
        $customer = Auth::guard('customer')->user();
        $loan = $customer->disbursedLoans()
            ->with(['loanType', 'paymentSchedules' => function($query) {
                $query->orderBy('paymentdate', 'desc');
            }])
            ->findOrFail($id);

        // Calculate loan details using the new model methods
        $totalRepayment = $loan->getTotalRepaymentAttribute();
        $collectionProgress = $loan->getCollectionProgressAttribute();
        
        // Get payment schedule
        $paymentSchedule = $loan->paymentSchedules;

        $applicationStats = $customer->getApplicationStats();
        $loanStats = $customer->getLoanStats();
        $creditScoreInfo = $this->getCreditScoreInfo($customer);

        return view('customer.loan-details', compact(
            'customer', 
            'loan', 
            'totalRepayment', 
            'collectionProgress',
            'paymentSchedule',
            'applicationStats',
            'loanStats',
            'creditScoreInfo'
        ));
    }

    /**
     * Show make payment form (Web)
     */
    public function showMakePayment()
    {
        $customer = Auth::guard('customer')->user();
        
        $applicationStats = $customer->getApplicationStats();
        $loanStats = $customer->getLoanStats();
        $creditScoreInfo = $this->getCreditScoreInfo($customer);

        // Get active loans for payment
        $activeLoans = $customer->activeDisbursedLoans()
            ->with('loanType')
            ->get();

        return view('customer.make-payment', compact(
            'customer',
            'applicationStats',
            'loanStats',
            'creditScoreInfo',
            'activeLoans'
        ));
    }

    /**
     * Show application form for editing (only for draft applications) (Web)
     */
    public function editApplication($id)
    {
        $customer = Auth::guard('customer')->user();
        $application = $customer->applications()
            ->where('status', 'draft')
            ->findOrFail($id);

        $loanTypes = LoanType::active()->get();

        $applicationStats = $customer->getApplicationStats();
        $loanStats = $customer->getLoanStats();
        $creditScoreInfo = $this->getCreditScoreInfo($customer);

        return view('customer.edit-application', compact('customer', 'application', 'loanTypes', 'applicationStats', 'loanStats', 'creditScoreInfo'));
    }

    /**
     * Update draft application (Web)
     */
    public function updateApplication(Request $request, $id)
    {
        $customer = Auth::guard('customer')->user();
        $application = $customer->applications()
            ->where('status', 'draft')
            ->findOrFail($id);

        // Similar validation as submitLoanApplication but for draft updates
        $validated = $request->validate([
            'loan_product' => 'required|exists:loantype,id',
            'loan_amount' => 'required|numeric|min:100',
            'loan_tenure' => 'required|integer|min:1|max:120',
            'loan_purpose' => 'required|string',
        ]);

        try {
            $loanProduct = LoanType::findOrFail($validated['loan_product']);
            $monthlyPayment = $this->calculateMonthlyPayment(
                $validated['loan_amount'], 
                $loanProduct->monthlyrate / 100, 
                $validated['loan_tenure']
            );

            $application->update([
                'product_id' => $validated['loan_product'],
                'loan_amount' => $validated['loan_amount'],
                'loan_tenure' => $validated['loan_tenure'],
                'loan_purpose' => $validated['loan_purpose'],
                'interest_rate' => $loanProduct->monthlyrate,
                'estimated_monthly_payment' => round($monthlyPayment, 2),
            ]);

            return redirect()->route('customer.applications.index')
                ->with('success', 'Application updated successfully.');

        } catch (\Exception $e) {
            \Log::error('Application update failed: ' . $e->getMessage(), [
                'customer_id' => $customer->id,
                'application_id' => $application->id,
            ]);

            return back()->with('error', 'Failed to update application. Please try again.')->withInput();
        }
    }

    /**
     * Download application as PDF (Web)
     */
    public function downloadApplication($id)
    {
        $customer = Auth::guard('customer')->user();
        $application = $customer->applications()
            ->with(['product', 'customer'])
            ->findOrFail($id);

        // You can implement PDF generation here
        // For now, just return a view
        return view('customer.application-pdf', compact('application'));
        
        // Example PDF generation:
        // $pdf = PDF::loadView('customer.application-pdf', compact('application'));
        // return $pdf->download('application-' . $application->application_number . '.pdf');
    }

    /**
     * Show credit score dashboard (Web)
     */
    public function showCreditScore()
    {
        $customer = Auth::guard('customer')->user();
        
        $creditScoreInfo = $this->getCreditScoreInfo($customer);
        $creditScoreHistory = $customer->creditScoreHistory()
            ->orderBy('score_date', 'desc')
            ->limit(12)
            ->get();

        $applicationStats = $customer->getApplicationStats();
        $loanStats = $customer->getLoanStats();

        return view('customer.credit-score', compact(
            'customer',
            'creditScoreInfo',
            'creditScoreHistory',
            'applicationStats',
            'loanStats'
        ));
    }
    
    
    
    /**
 * Get requirements for a specific loan product (AJAX)
 * This is used for the multi-step loan application form
 */
/*public function getLoanProductRequirements(Request $request, $id)
{
    try {
        // Ensure customer is authenticated
        $customer = Auth::guard('customer')->user();

        if (!$customer) {
            return response()->json([
                'success' => false,
                'message' => 'Customer not authenticated'
            ], 401);
        }

        \Log::info('Fetching requirements for loan product', [
            'customer_id' => $customer->id,
            'loan_type_id' => $id
        ]);

        // Get loan type (product)
        $loanType = \App\Models\LoanType::find($id);

        if (!$loanType) {
            \Log::warning('Loan type not found', ['id' => $id]);
            return response()->json([
                'success' => false,
                'message' => 'Loan product not found'
            ], 404);
        }

        // Get requirements from product_requirements pivot table
        $requirements = \DB::table('product_requirements')
            ->join('applicationrequirements', 'product_requirements.requirement_id', '=', 'applicationrequirements.id')
            ->where('product_requirements.product_id', $id)
            ->where('applicationrequirements.status', 'active')
            ->select(
                'applicationrequirements.id',
                'applicationrequirements.documentname as name',
                'applicationrequirements.description',
                'product_requirements.is_mandatory',
                'applicationrequirements.createdat as created_at',
                'applicationrequirements.updatedat as updated_at'
            )
            ->orderBy('applicationrequirements.documentname')
            ->get()
            ->map(function($req) {
                return [
                    'id' => $req->id,
                    'name' => $req->name,
                    'description' => $req->description ?? '',
                    'field_type' => 'file', // Default field type
                    'file_types' => 'jpg,jpeg,png,pdf', // Default file types
                    'max_file_size' => 2048, // Default 2MB
                    'is_mandatory' => (int)$req->is_mandatory,
                    'created_at' => $req->created_at,
                    'updated_at' => $req->updated_at,
                ];
            })
            ->toArray();

        // If no specific requirements found for this product, get all active requirements
        if (empty($requirements)) {
            \Log::info('No specific requirements found for product, fetching all active requirements');
            
            $requirements = \DB::table('applicationrequirements')
                ->where('status', 'active')
                ->select(
                    'id',
                    'documentname as name',
                    'description',
                    'createdat as created_at',
                    'updatedat as updated_at'
                )
                ->get()
                ->map(function($req) {
                    return [
                        'id' => $req->id,
                        'name' => $req->name,
                        'description' => $req->description ?? '',
                        'field_type' => 'file',
                        'file_types' => 'jpg,jpeg,png,pdf',
                        'max_file_size' => 2048,
                        'is_mandatory' => 1, // Default to mandatory if no pivot data
                        'created_at' => $req->created_at,
                        'updated_at' => $req->updated_at,
                    ];
                })
                ->toArray();
        }

        \Log::info('Returning requirements', [
            'loan_type_id' => $id,
            'loan_product' => $loanType->product,
            'requirements_count' => count($requirements)
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Requirements loaded successfully',
            'requirements' => $requirements,
            'loan_product' => [
                'id' => $loanType->id,
                'name' => $loanType->product,
                'description' => $loanType->details,
                'total_requirements' => count($requirements),
                'mandatory_requirements' => count(array_filter($requirements, function($req) {
                    return $req['is_mandatory'] == 1;
                })),
            ]
        ]);

    } catch (\Exception $e) {
        \Log::error('Error in getLoanProductRequirements: ' . $e->getMessage(), [
            'trace' => $e->getTraceAsString()
        ]);

        return response()->json([
            'success' => false,
            'message' => 'Failed to load requirements',
            'error' => env('APP_DEBUG') ? $e->getMessage() : 'Internal error'
        ], 500);
    }
}
*/


public function getLoanProductRequirements(Request $request, $id)
{
 return "Reached getLoanProductRequirements – ID: $id";
}


/**
 * Submit loan application with documents (Updated for multi-step form)
 */
public function submitLoanApplication(Request $request): JsonResponse
{
    // Get authenticated customer
    $customer = Auth::guard('customer')->user();
    
    if (!$customer) {
        return response()->json([
            'success' => false,
            'message' => 'Customer not authenticated. Please log in again.'
        ], 401);
    }
    
    if ($customer->status !== 'Active') {
        return response()->json([
            'success' => false,
            'message' => 'Customer account is not active. Please contact support.'
        ], 403);
    }
    
    // Check if customer can apply for loan
    if (!$customer->canApplyForLoan()) {
        return response()->json([
            'success' => false,
            'message' => 'Cannot apply for loan. Please complete your profile verification first.'
        ], 400);
    }
    
    // Check application limit
    if ($customer->hasReachedApplicationLimit()) {
        return response()->json([
            'success' => false,
            'message' => 'You have reached the maximum number of pending applications (3). Please wait for existing applications to be processed.'
        ], 400);
    }
    
    \Log::info('Loan application submission started (multi-step)', [
        'customer_id' => $customer->id,
        'customer_email' => $customer->email,
        'has_files' => $request->hasFile('requirement_')
    ]);

    DB::beginTransaction();

    try {
        // Validate the form data
        $validated = $request->validate([
            // Applicant Details
            'title' => 'required|string|max:10',
            'surname' => 'required|string|max:255',
            'first_name' => 'required|string|max:255',
            'middle_name' => 'nullable|string|max:255',
            'date_of_birth' => 'required|date',
            'nrc_number' => 'required|string|max:255',
            'email' => 'required|email',
            'mobile_number' => 'required|string|max:25',
            'bank_branch' => 'required|string|max:255',
            'account_number' => 'required|string|max:255',
            'employment_years' => 'required|integer|min:0',
            'employee_number' => 'nullable|string|max:255',
            'physical_address' => 'required|string',
            'postal_address' => 'required|string',
            'town' => 'required|string|max:255',
            'province' => 'required|string|max:255',
            'retirement_year' => 'nullable|integer|min:1900|max:2100',
            'office_phone' => 'nullable|string|max:25',
            
            // Employment Details
            'job_title' => 'required|string|max:255',
            'employer_name' => 'required|string|max:255',
            'employer_physical_address' => 'required|string',
            'employer_postal_address' => 'required|string',
            'employer_town_province' => 'required|string|max:255',
            'gross_salary' => 'required|numeric|min:0',
            'net_salary' => 'required|numeric|min:0',
            'employment_type' => 'required|in:permanent,contract',
            'contract_expiry_date' => 'required_if:employment_type,contract|date|nullable',
            
            // Loan Information
            'loan_product' => 'required|exists:loantype,id',
            'loan_amount' => 'required|numeric|min:100',
            'loan_tenure' => 'required|integer|min:1|max:120',
            'loan_purpose' => 'required|string',
            
            // Next of Kin
            'kin_surname' => 'required|string|max:255',
            'kin_first_name' => 'required|string|max:255',
            'kin_physical_address' => 'required|string',
            'kin_postal_address' => 'required|string',
            'kin_town' => 'required|string|max:255',
            'kin_province' => 'required|string|max:255',
            'kin_country' => 'required|string|max:255',
            'kin_telephone' => 'required|string|max:25',
            'kin_email' => 'nullable|email',
            'kin_relationship' => 'nullable|string|max:100',
        ]);

        \Log::info('Form validation passed', [
            'customer_id' => $customer->id,
            'loan_product_id' => $validated['loan_product']
        ]);

        // Get loan product details
        $loanProduct = LoanType::findOrFail($validated['loan_product']);
        
        // Validate loan amount against customer's recommended max
        $recommendedMax = $customer->recommended_max_loan_amount;
        $requestedAmount = $validated['loan_amount'];
        
        if ($requestedAmount > $recommendedMax * 1.5) {
            \Log::warning('Loan amount exceeds recommended maximum', [
                'customer_id' => $customer->id,
                'requested_amount' => $requestedAmount,
                'recommended_max' => $recommendedMax,
                'credit_score' => $customer->current_credit_score
            ]);
        }
        
        // Calculate estimated monthly payment
        $loanAmount = $validated['loan_amount'];
        $interestRate = $loanProduct->monthlyrate / 100;
        $loanTenure = $validated['loan_tenure'];
        
        $monthlyPayment = $this->calculateMonthlyPayment($loanAmount, $interestRate, $loanTenure);

        // Check for duplicate application
        $existingApplication = Application::where('customer_id', $customer->id)
            ->where('product_id', $validated['loan_product'])
            ->whereIn('status', ['draft', 'submitted', 'under_review'])
            ->where('loan_amount', $loanAmount)
            ->first();
            
        if ($existingApplication) {
            \Log::warning('Duplicate loan application detected', [
                'customer_id' => $customer->id,
                'existing_application_id' => $existingApplication->id
            ]);
            
            return response()->json([
                'success' => false,
                'message' => 'You already have a similar application pending. Please check your applications list.'
            ], 400);
        }

        // Create application
        $application = Application::create([
            'customer_id' => $customer->id,
            'product_id' => $validated['loan_product'],
            
            // Bank Details
            'bank_branch' => $validated['bank_branch'],
            'account_number' => $validated['account_number'],
            
            // Employment Details
            'job_title' => $validated['job_title'],
            'employer_name' => $validated['employer_name'],
            'employer_physical_address' => $validated['employer_physical_address'],
            'employer_postal_address' => $validated['employer_postal_address'],
            'employer_town_province' => $validated['employer_town_province'],
            'gross_salary' => $validated['gross_salary'],
            'net_salary' => $validated['net_salary'],
            'employment_type' => $validated['employment_type'],
            'employment_years' => $validated['employment_years'],
            'retirement_year' => $validated['retirement_year'] ?? null,
            'employee_number' => $validated['employee_number'] ?? null,
            'contract_expiry_date' => $validated['contract_expiry_date'] ?? null,
            
            // Next of Kin Details
            'kin_surname' => $validated['kin_surname'],
            'kin_first_name' => $validated['kin_first_name'],
            'kin_physical_address' => $validated['kin_physical_address'],
            'kin_postal_address' => $validated['kin_postal_address'],
            'kin_town' => $validated['kin_town'],
            'kin_province' => $validated['kin_province'],
            'kin_country' => $validated['kin_country'],
            'kin_telephone' => $validated['kin_telephone'],
            'kin_email' => $validated['kin_email'] ?? null,
            'kin_relationship' => $validated['kin_relationship'] ?? 'Next of Kin',
            
            // Loan Details
            'loan_amount' => $validated['loan_amount'],
            'loan_tenure' => $validated['loan_tenure'],
            'loan_purpose' => $validated['loan_purpose'],
            'interest_rate' => $loanProduct->monthlyrate,
            'estimated_monthly_payment' => round($monthlyPayment, 2),
            
            // Application Status
            'status' => 'submitted',
            'submitted_at' => now(),
            
            // System Fields
            'branch_id' => $customer->branchid ?? 1,
            'company_id' => $customer->companyid ?? 1,
            'created_by' => $customer->id,
            
            // Additional fields
            'source' => 'Customer Portal',
            'payment_frequency' => 'Monthly',
        ]);

        \Log::info('Application created successfully', [
            'application_id' => $application->id,
            'application_number' => $application->application_number
        ]);

        // Handle document uploads
        $uploadedDocuments = $this->handleDocumentUploads($request, $application, $customer);
        
        \Log::info('Documents uploaded', [
            'application_id' => $application->id,
            'documents_count' => count($uploadedDocuments),
            'documents' => $uploadedDocuments
        ]);

        // Update credit score for loan application
        try {
            $this->creditScoreService->updateScoreForEvent(
                $customer->id,
                'loan_application_submitted',
                [
                    'application_id' => $application->id,
                    'loan_amount' => $loanAmount,
                    'product_type' => $loanProduct->product,
                    'customer_credit_score' => $customer->current_credit_score,
                    'application_date' => now()->toDateString(),
                    'documents_submitted' => count($uploadedDocuments),
                ]
            );

            \Log::info('Credit score updated for loan application', [
                'customer_id' => $customer->id,
                'application_id' => $application->id
            ]);

        } catch (\Exception $creditScoreException) {
            \Log::error('Failed to update credit score for loan application', [
                'customer_id' => $customer->id,
                'application_id' => $application->id,
                'error' => $creditScoreException->getMessage()
            ]);
        }

        DB::commit();

        // Send email notification
        $emailSent = false;
        try {
            Mail::to($customer->email)
                ->send(new LoanApplicationSubmitted($application));
            
            $emailSent = true;
            \Log::info('Loan application confirmation email sent', [
                'application_id' => $application->id,
                'customer_email' => $customer->email
            ]);
            
        } catch (\Exception $emailException) {
            \Log::error('Failed to send loan application email', [
                'application_id' => $application->id,
                'error' => $emailException->getMessage()
            ]);
        }

        // Send SMS notification
        $smsSent = false;
        try {
            $smsMessage = "Dear {$customer->customer}, your loan application #{$application->application_number} has been received by Immiafinance. We will notify you once approved. Check portal for updates.";
            
            $smsSent = $this->smsService->sendSms($customer->phone, $smsMessage);
            
            if ($smsSent) {
                \Log::info('Loan application confirmation SMS sent', [
                    'application_id' => $application->id,
                    'customer_phone' => $customer->phone
                ]);
            }
            
        } catch (\Exception $smsException) {
            \Log::error('SMS sending failed', [
                'application_id' => $application->id,
                'error' => $smsException->getMessage()
            ]);
        }

        return response()->json([
            'success' => true,
            'message' => 'Loan application submitted successfully!',
            'data' => [
                'application' => [
                    'id' => $application->id,
                    'application_number' => $application->application_number,
                    'loan_amount' => $application->loan_amount,
                    'loan_tenure' => $application->loan_tenure,
                    'estimated_monthly_payment' => $application->estimated_monthly_payment,
                    'status' => $application->status,
                    'status_text' => $this->getStatusText($application->status),
                    'submitted_at' => $application->submitted_at->format('Y-m-d H:i:s'),
                    'product_name' => $loanProduct->product,
                ],
                'documents' => [
                    'total_uploaded' => count($uploadedDocuments),
                    'documents' => $uploadedDocuments
                ],
                'notifications' => [
                    'email_sent' => $emailSent,
                    'sms_sent' => $smsSent
                ]
            ]
        ], 201);

    } catch (\Illuminate\Validation\ValidationException $e) {
        DB::rollBack();
        
        \Log::error('Form validation failed', [
            'customer_id' => $customer->id,
            'errors' => $e->errors()
        ]);

        return response()->json([
            'success' => false,
            'message' => 'Validation failed. Please check your form data.',
            'errors' => $e->errors()
        ], 422);

    } catch (\Exception $e) {
        DB::rollBack();
        
        \Log::error('Loan application submission failed', [
            'customer_id' => $customer->id,
            'error' => $e->getMessage(),
            'trace' => $e->getTraceAsString()
        ]);

        return response()->json([
            'success' => false,
            'message' => 'There was an error submitting your application: ' . $e->getMessage()
        ], 500);
    }
}

/**
 * Handle document uploads for loan application
 */
private function handleDocumentUploads(Request $request, Application $application, Customer $customer): array
{
    $uploadedDocuments = [];
    
    // Get loan product requirements
    $loanType = LoanType::with('requirements')->find($application->product_id);
    
    if (!$loanType || $loanType->requirements->isEmpty()) {
        return $uploadedDocuments;
    }

    // Create directory for application documents
    $applicationDir = "applications/{$application->id}";
    
    foreach ($loanType->requirements as $requirement) {
        $fieldName = "requirement_{$requirement->id}";
        
        if ($request->hasFile($fieldName)) {
            $file = $request->file($fieldName);
            
            // Validate file type if specified
            if ($requirement->file_types) {
                $allowedTypes = array_map('trim', explode(',', $requirement->file_types));
                $fileExtension = strtolower($file->getClientOriginalExtension());
                
                if (!in_array($fileExtension, $allowedTypes)) {
                    throw new \Exception("Invalid file type for '{$requirement->name}'. Allowed types: " . $requirement->file_types);
                }
            }
            
            // Validate file size if specified
            if ($requirement->max_file_size && $file->getSize() > $requirement->max_file_size) {
                $maxSizeMB = round($requirement->max_file_size / 1048576, 2);
                throw new \Exception("File too large for '{$requirement->name}'. Maximum size: {$maxSizeMB} MB");
            }
            
            // Generate unique filename
            $originalName = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
            $extension = $file->getClientOriginalExtension();
            $fileName = $originalName . '_' . time() . '.' . $extension;
            
            // Store file
            $filePath = $file->storeAs($applicationDir, $fileName, 'public');
            
            // Save to loanapplicationdocuments table
            $document = LoanApplicationDocument::create([
                'application_id' => $application->id,
                'requirement_id' => $requirement->id,
                'file_path' => $filePath,
                'file_name' => $file->getClientOriginalName(),
                'file_size' => $file->getSize(),
                'file_type' => $file->getMimeType(),
                'uploaded_by' => $customer->id,
                'status' => 'pending',
                'uploaded_at' => now(),
            ]);
            
            $uploadedDocuments[] = [
                'requirement_id' => $requirement->id,
                'requirement_name' => $requirement->name,
                'document_id' => $document->id,
                'file_name' => $document->file_name,
                'file_size' => $document->file_size,
                'status' => $document->status,
            ];
            
            \Log::info('Document uploaded successfully', [
                'application_id' => $application->id,
                'document_id' => $document->id,
                'requirement_name' => $requirement->name,
                'file_path' => $filePath
            ]);
            
        } else if ($requirement->pivot->is_mandatory) {
            // Check if mandatory document is missing
            throw new \Exception("Mandatory document '{$requirement->name}' is required");
        }
    }
    
    return $uploadedDocuments;
}

/**
 * Helper method to format file size
 */
private function formatFileSize($bytes): string
{
    if ($bytes >= 1073741824) {
        return number_format($bytes / 1073741824, 2) . ' GB';
    } elseif ($bytes >= 1048576) {
        return number_format($bytes / 1048576, 2) . ' MB';
    } elseif ($bytes >= 1024) {
        return number_format($bytes / 1024, 2) . ' KB';
    } elseif ($bytes > 1) {
        return $bytes . ' bytes';
    } elseif ($bytes == 1) {
        return $bytes . ' byte';
    } else {
        return '0 bytes';
    }
}
    
}