<?php

namespace App\Http\Controllers;

use App\Models\Loan;
use App\Models\LoanGuarantee;
use App\Models\LoanGuarantor;
use App\Models\LoanCollateral;
use App\Models\LoanSalaryGuarantee;
use App\Models\Transaction;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Mail;
use App\Mail\LoanRepaymentReceipt;
use Barryvdh\DomPDF\Facade\Pdf;
use Maatwebsite\Excel\Facades\Excel;

class LoanController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        $loans = Loan::with('user')->paginate(15);

        // Calculate dynamic financial statistics for approved/active loans
        $approvedLoans = Loan::whereIn('status', ['approved', 'active'])->get();

        $loansIssued = $approvedLoans->sum('amount');
        $amountExpectedRepaid = $approvedLoans->sum(function ($loan) {
            return $loan->total_amount;
        });
        $totalInterest = $amountExpectedRepaid - $loansIssued;

        // Find member with highest loan amount
        $highestLoanBorrower = Loan::whereIn('status', ['approved', 'active'])
            ->with('user')
            ->orderBy('amount', 'desc')
            ->first();

        // Find member with lowest loan amount
        $lowestLoanBorrower = Loan::whereIn('status', ['approved', 'active'])
            ->with('user')
            ->orderBy('amount', 'asc')
            ->first();

        // Find member with highest outstanding balance (defaulter)
        $highestDefaulter = Loan::whereIn('status', ['approved', 'active'])
            ->whereRaw('(amount + (amount * interest_rate / 100)) > paid_amount')
            ->with('user')
            ->orderByRaw('(amount + (amount * interest_rate / 100)) - paid_amount DESC')
            ->first();

        // Calculate total defaulted loans amount (sum of outstanding balances)
        $totalDefaultedAmount = Loan::whereIn('status', ['approved', 'active'])
            ->whereRaw('(amount + (amount * interest_rate / 100)) > paid_amount')
            ->selectRaw('SUM((amount + (amount * interest_rate / 100)) - paid_amount) as total_outstanding')
            ->first()
            ->total_outstanding ?? 0;

        return view('adminlte.loans.index', compact(
            'loans',
            'loansIssued',
            'amountExpectedRepaid',
            'totalInterest',
            'highestLoanBorrower',
            'lowestLoanBorrower',
            'highestDefaulter',
            'totalDefaultedAmount'
        ));
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        $users = User::whereHas('membership')->get();

        return view('adminlte.loans.create', compact('users'));
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        $request->validate([
            'user_id' => 'required|exists:users,id',
            'amount' => 'required|numeric|min:1000',
            'interest_rate' => 'required|numeric|min:0|max:50',
            'application_date' => 'required|date|before_or_equal:today',
            'return_date' => 'required|date|after:application_date',
            'notes' => 'nullable|string|max:1000',
            'guarantees' => 'nullable|array',
            'guarantees.*.type' => 'required|in:salary,collateral,guarantor',
        ]);

        // Calculate term_months from dates
        $applicationDate = \Carbon\Carbon::parse($request->application_date);
        $returnDate = \Carbon\Carbon::parse($request->return_date);
        $termMonths = ceil($applicationDate->diffInMonths($returnDate));

        // Create the loan
        $loanData = $request->only(['user_id', 'amount', 'interest_rate', 'application_date', 'return_date', 'notes']);
        $loanData['term_months'] = $termMonths;
        $loan = Loan::create($loanData);

        // Process guarantees if provided
        if ($request->has('guarantees')) {
            $result = $this->processGuarantees($loan, $request->guarantees, $request);
            if (isset($result['error'])) {
                // Delete the loan since guarantee processing failed
                $loan->delete();
                return redirect()->back()
                    ->withInput()
                    ->withErrors(['guarantee' => $result['error']]);
            }
        }

        return redirect()->route('loans.index')
                         ->with('success', 'Loan application for ' . $loan->user->full_name . ' has been submitted successfully! The application is now pending approval.');
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        $loan = Loan::with([
            'user',
            'repayments',
            'guarantees' => function($query) {
                $query->with(['guarantors.guarantor', 'collateral', 'salaryGuarantee']);
            }
        ])->findOrFail($id);

        return view('adminlte.loans.show', compact('loan'));
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(string $id)
    {
        $loan = Loan::findOrFail($id);
        $users = User::whereHas('membership')->get();

        return view('adminlte.loans.edit', compact('loan', 'users'));
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id)
    {
        $loan = Loan::findOrFail($id);

        $request->validate([
            'user_id' => 'required|exists:users,id',
            'amount' => 'required|numeric|min:1000',
            'interest_rate' => 'required|numeric|min:0|max:50',
            'application_date' => 'required|date|before_or_equal:today',
            'return_date' => 'required|date|after:application_date',
            'status' => 'required|in:pending,approved,rejected,active,paid,defaulted',
            'notes' => 'nullable|string|max:1000',
            'existing_guarantees' => 'nullable|array',
            'guarantees' => 'nullable|array',
        ]);

        // Calculate term_months from dates
        $applicationDate = \Carbon\Carbon::parse($request->application_date);
        $returnDate = \Carbon\Carbon::parse($request->return_date);
        $termMonths = ceil($applicationDate->diffInMonths($returnDate));

        $data = $request->only(['user_id', 'amount', 'interest_rate', 'application_date', 'return_date', 'status', 'notes']);
        $data['term_months'] = $termMonths;

        // Set approved_at when status changes to approved
        if ($request->status === 'approved' && $loan->status !== 'approved') {
            $data['approved_at'] = now();
        }

        $loan->update($data);

        // Process existing guarantees updates
        if ($request->has('existing_guarantees')) {
            $result = $this->updateExistingGuarantees($loan, $request->existing_guarantees, $request);
            if (isset($result['error'])) {
                return redirect()->back()
                    ->withInput()
                    ->withErrors(['guarantee' => $result['error']]);
            }
        }

        // Process new guarantees
        if ($request->has('guarantees')) {
            $result = $this->processGuarantees($loan, $request->guarantees, $request);
            if (isset($result['error'])) {
                return redirect()->back()
                    ->withInput()
                    ->withErrors(['guarantee' => $result['error']]);
            }
        }

        return redirect()->route('loans.index')
                         ->with('success', 'Loan application for ' . $loan->user->full_name . ' has been updated successfully!');
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        $loan = Loan::findOrFail($id);

        $loan->delete();

        return redirect()->route('loans.index')
                        ->with('success', 'Loan deleted successfully!');
    }

    /**
     * Approve a loan application.
     */
    public function approve(Loan $loan)
    {
        $loan->update([
            'status' => 'approved',
            'approved_at' => now(),
        ]);

        return redirect()->route('loans.index')
                        ->with('success', 'Loan approved successfully!');
    }

    /**
     * Reject a loan application.
     */
    public function reject(Loan $loan)
    {
        $loan->update(['status' => 'rejected']);

        return redirect()->route('loans.index')
                         ->with('success', 'Loan rejected successfully!');
    }

    /**
     * Approve a guarantee.
     */
    public function approveGuarantee(LoanGuarantee $guarantee)
    {
        $guarantee->update([
            'status' => 'approved',
            'verified_at' => now(),
            'verified_by' => auth()->id(),
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Guarantee approved successfully',
            'guarantee' => $guarantee->fresh()
        ]);
    }

    /**
     * Reject a guarantee.
     */
    public function rejectGuarantee(Request $request, LoanGuarantee $guarantee)
    {
        $request->validate([
            'reason' => 'required|string|max:1000',
        ]);

        $verificationData = $guarantee->verification_data ?? [];
        $verificationData['rejection_reason'] = $request->reason;
        $verificationData['rejected_at'] = now()->toISOString();
        $verificationData['rejected_by'] = auth()->id();

        $guarantee->update([
            'status' => 'rejected',
            'verification_data' => $verificationData,
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Guarantee rejected successfully',
            'guarantee' => $guarantee->fresh()
        ]);
    }

    /**
     * Process loan repayment.
     */
    public function repay(Request $request, Loan $loan)
    {
        try {
            $request->validate([
                'amount' => 'required|numeric|min:0.01',
                'payment_method' => 'nullable|string|in:cash,bank_transfer,mpesa_manual,mpesa_stk',
                'mpesa_phone_number' => 'nullable|string|regex:/^254[0-9]{9}$/',
                'mpesa_transaction_id' => 'nullable|string|max:50',
                'notes' => 'nullable|string|max:1000',
            ]);

            $repaymentAmount = $request->amount;

            // Debug logging
            \Log::info('Loan repayment attempt', [
                'loan_id' => $loan->id,
                'amount' => $repaymentAmount,
                'current_balance' => $loan->balance,
                'current_paid_amount' => $loan->paid_amount,
                'total_amount' => $loan->total_amount,
                'payment_method' => $request->payment_method
            ]);

            // Allow any positive amount - no balance validation

            // Create transaction record
            $transaction = Transaction::create([
                'user_id' => $loan->user_id,
                'loan_id' => $loan->id,
                'type' => 'loan_repayment',
                'amount' => $repaymentAmount,
                'currency' => 'KES',
                'payment_method' => $request->payment_method ?? 'cash',
                'mpesa_transaction_id' => $request->mpesa_transaction_id,
                'mpesa_phone_number' => $request->mpesa_phone_number,
                'status' => 'completed',
                'notes' => $request->notes,
                'description' => 'Loan repayment for loan #' . $loan->id,
                'processed_at' => now(),
            ]);

            // Update loan paid amount
            $loan->increment('paid_amount', $repaymentAmount);

            // Refresh loan to get updated balance
            $loan->refresh();

            // Check if loan is fully paid
            if ($loan->balance <= 0) {
                $loan->update(['status' => 'paid']);
                \Log::info('Loan marked as fully paid', ['loan_id' => $loan->id]);
            }

            \Log::info('Loan repayment processed successfully', [
                'loan_id' => $loan->id,
                'transaction_id' => $transaction->id,
                'new_balance' => $loan->balance,
                'new_paid_amount' => $loan->paid_amount
            ]);

            // Send email receipt to member
            try {
                Mail::to($loan->user->email)->send(new LoanRepaymentReceipt($loan->user, $loan, $transaction));
                \Log::info('Loan repayment receipt email sent', [
                    'loan_id' => $loan->id,
                    'transaction_id' => $transaction->id,
                    'email' => $loan->user->email
                ]);
            } catch (\Exception $e) {
                \Log::error('Failed to send loan repayment receipt email', [
                    'loan_id' => $loan->id,
                    'transaction_id' => $transaction->id,
                    'email' => $loan->user->email,
                    'error' => $e->getMessage()
                ]);
                // Don't fail the transaction if email fails
            }

            if ($request->expectsJson()) {
                return response()->json([
                    'success' => true,
                    'message' => 'Repayment processed successfully',
                    'transaction' => $transaction,
                    'loan' => $loan->fresh(['user']),
                    'latest_repayment' => $transaction
                ]);
            }

            return back()->with('success', 'Repayment processed successfully');

        } catch (\Exception $e) {
            \Log::error('Loan repayment failed', [
                'loan_id' => $loan->id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
                'request_data' => $request->all()
            ]);

            if ($request->expectsJson()) {
                return response()->json(['error' => 'Failed to process repayment: ' . $e->getMessage()], 500);
            }

            return back()->withErrors(['general' => 'Failed to process repayment: ' . $e->getMessage()]);
        }
    }

    /**
     * Initiate M-Pesa STK Push for loan repayment.
     */
    public function repayMpesa(Request $request, Loan $loan)
    {
        $request->validate([
            'amount' => 'required|numeric|min:0.01',
            'mpesa_phone_number' => 'required|string|regex:/^254[0-9]{9}$/',
            'notes' => 'nullable|string|max:1000',
        ]);

        $repaymentAmount = $request->amount;
        $phoneNumber = $request->mpesa_phone_number;

        // Allow any positive amount - no balance validation

        // Get M-Pesa credentials
        $mpesaConfig = \App\Models\MpesaCredential::where('is_active', true)->first();

        if (!$mpesaConfig) {
            return response()->json(['error' => 'M-Pesa configuration not found'], 500);
        }

        try {
            // For now, simulate M-Pesa STK Push success since we don't have actual M-Pesa credentials
            // In production, you would use the actual M-Pesa API

            // Create transaction record as pending
            $transaction = Transaction::create([
                'user_id' => $loan->user_id,
                'loan_id' => $loan->id,
                'type' => 'loan_repayment',
                'amount' => $repaymentAmount,
                'currency' => 'KES',
                'payment_method' => 'mpesa_stk',
                'mpesa_transaction_id' => 'SIMULATED-' . time(),
                'mpesa_phone_number' => $phoneNumber,
                'status' => 'pending',
                'mpesa_response' => json_encode(['simulated' => true, 'amount' => $repaymentAmount, 'phone' => $phoneNumber]),
                'notes' => $request->notes,
                'description' => 'M-Pesa STK Push initiated for loan repayment - ' . $loan->user->full_name,
            ]);

            // For demo purposes, immediately mark as completed
            // In production, this would be done via callback
            $transaction->update([
                'status' => 'completed',
                'processed_at' => now()
            ]);

            // Update loan paid amount
            $loan->increment('paid_amount', $repaymentAmount);

            // Check if loan is fully paid
            if ($loan->balance <= 0) {
                $loan->update(['status' => 'paid']);
            }

            // Send email receipt to member
            try {
                Mail::to($loan->user->email)->send(new LoanRepaymentReceipt($loan->user, $loan, $transaction));
                \Log::info('M-Pesa loan repayment receipt email sent', [
                    'loan_id' => $loan->id,
                    'transaction_id' => $transaction->id,
                    'email' => $loan->user->email
                ]);
            } catch (\Exception $e) {
                \Log::error('Failed to send M-Pesa loan repayment receipt email', [
                    'loan_id' => $loan->id,
                    'transaction_id' => $transaction->id,
                    'email' => $loan->user->email,
                    'error' => $e->getMessage()
                ]);
                // Don't fail the transaction if email fails
            }

            return response()->json([
                'success' => true,
                'message' => 'M-Pesa STK Push simulated successfully. Payment processed.',
                'transaction' => $transaction,
                'loan' => $loan->fresh(['user'])
            ]);

        } catch (\Exception $e) {
            \Log::error('M-Pesa STK Push failed', [
                'loan_id' => $loan->id,
                'user_id' => $loan->user_id,
                'amount' => $repaymentAmount,
                'error' => $e->getMessage()
            ]);

            return response()->json(['error' => 'Failed to initiate M-Pesa payment: ' . $e->getMessage()], 500);
        }
    }

    private function generatePassword($mpesaConfig)
    {
        $timestamp = date('YmdHis');
        $password = base64_encode($mpesaConfig->shortcode . $mpesaConfig->passkey . $timestamp);
        return $password;
    }

    /**
     * Get members for AJAX loading.
     */
    public function getMembers(Request $request)
    {
        $search = $request->get('search', '');
        $members = User::whereHas('membership')
            ->where(function($query) use ($search) {
                $query->where('first_name', 'like', "%{$search}%")
                      ->orWhere('second_name', 'like', "%{$search}%")
                      ->orWhere('id_number', 'like', "%{$search}%")
                      ->orWhere('phone_number', 'like', "%{$search}%");
            })
            ->with('membership')
            ->limit(50)
            ->get()
            ->map(function($user) {
                return [
                    'id' => $user->id,
                    'text' => $user->full_name . ' (' . $user->id_number . ')',
                    'first_name' => $user->first_name,
                    'second_name' => $user->second_name,
                    'id_number' => $user->id_number,
                    'phone_number' => $user->phone_number,
                    'email' => $user->email,
                    'membership_number' => $user->membership->membership_number ?? 'N/A',
                ];
            });

        return response()->json(['results' => $members]);
    }

    /**
     * Export loans to CSV.
     */
    public function exportCsv(Request $request)
    {
        $filename = 'loans_' . date('Y-m-d_H-i-s') . '.csv';
        return Excel::download(new \App\Exports\LoansExport($request->all()), $filename, \Maatwebsite\Excel\Excel::CSV);
    }

    /**
     * Export loans to Excel.
     */
    public function exportExcel(Request $request)
    {
        $filename = 'loans_' . date('Y-m-d_H-i-s') . '.xlsx';
        return Excel::download(new \App\Exports\LoansExport($request->all()), $filename, \Maatwebsite\Excel\Excel::XLSX);
    }

    /**
     * Export loans to PDF.
     */
    public function exportPdf(Request $request)
    {
        $query = Loan::with(['user', 'user.branch']);

        // Apply same filters as index
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        if ($request->filled('user_id')) {
            $query->where('user_id', $request->user_id);
        }

        $loans = $query->orderBy('created_at', 'desc')->get();

        $pdf = Pdf::loadView('adminlte.loans.exports.pdf', compact('loans'))
                  ->setPaper('a4', 'landscape');

        $filename = 'loans_' . date('Y-m-d_H-i-s') . '.pdf';
        return $pdf->download($filename);
    }

    /**
     * Download detailed loan details PDF for a specific loan.
     */
    public function downloadDetails(Loan $loan)
    {
        $loan->load('user', 'user.branch', 'user.membership', 'repayments');

        $pdf = Pdf::loadView('adminlte.loans.exports.details', compact('loan'))
                  ->setPaper('a4', 'portrait')
                  ->setOptions([
                      'margin-top' => 15,
                      'margin-right' => 15,
                      'margin-bottom' => 15,
                      'margin-left' => 15,
                      'defaultFont' => 'DejaVu Sans'
                  ]);

        $filename = 'loan_details_' . $loan->id . '_' . date('Y-m-d') . '.pdf';
        return $pdf->download($filename);
    }

    /**
     * Download detailed payment schedule PDF for a specific loan.
     */
    public function downloadSchedule(Loan $loan)
    {
        $loan->load('user', 'user.branch', 'user.membership');

        // Calculate payment schedule data
        $scheduleData = [];
        $balance = $loan->amount;
        $monthlyPayment = $loan->monthly_payment;
        $currentDate = $loan->approved_at ?? $loan->created_at;

        $termMonths = $loan->term_months;
        for ($month = 1; $month <= $termMonths; $month++) {
            $interestPayment = $balance * ($loan->interest_rate / 100) / 12;
            $principalPayment = $monthlyPayment - $interestPayment;

            // Ensure we don't overpay on the last payment
            if ($balance + $interestPayment < $monthlyPayment) {
                $monthlyPayment = $balance + $interestPayment;
                $principalPayment = $balance;
            }

            $scheduleData[] = [
                'month' => $month,
                'due_date' => $currentDate->copy()->addMonths($month - 1)->format('M Y'),
                'payment' => $monthlyPayment,
                'principal' => $principalPayment,
                'interest' => $interestPayment,
                'balance' => max(0, $balance - $principalPayment)
            ];

            $balance -= $principalPayment;
            if ($balance < 0.01) $balance = 0;
        }

        $pdf = Pdf::loadView('adminlte.loans.exports.schedule', compact('loan', 'scheduleData'))
                  ->setPaper('a4', 'portrait')
                  ->setOptions([
                      'margin-top' => 10,
                      'margin-right' => 10,
                      'margin-bottom' => 10,
                      'margin-left' => 10,
                      'defaultFont' => 'Arial'
                  ]);

        $filename = 'loan_schedule_' . $loan->id . '_' . date('Y-m-d') . '.pdf';
        return $pdf->download($filename);
    }

    /**
     * Process guarantees for a loan
     */
    private function processGuarantees(Loan $loan, array $guarantees, Request $request)
    {
        foreach ($guarantees as $index => $guaranteeData) {
            // Create the main guarantee record
            $guarantee = LoanGuarantee::create([
                'loan_id' => $loan->id,
                'guarantee_type' => $guaranteeData['type'],
                'status' => 'pending',
                'notes' => $guaranteeData['notes'] ?? null,
            ]);

            // Process specific guarantee type
            switch ($guaranteeData['type']) {
                case 'salary':
                    $this->processSalaryGuarantee($guarantee, $guaranteeData['salary'], $request, $index);
                    break;
                case 'collateral':
                    $this->processCollateralGuarantee($guarantee, $guaranteeData['collateral'], $request, $index);
                    break;
                case 'guarantor':
                    $result = $this->processGuarantorGuarantee($guarantee, $guaranteeData['guarantor']);
                    if (isset($result['error'])) {
                        return $result; // Return error to be handled by controller
                    }
                    break;
            }
        }
        return ['success' => true];
    }

    /**
     * Process salary guarantee
     */
    private function processSalaryGuarantee(LoanGuarantee $guarantee, array $data, Request $request, int $index)
    {
        $salaryData = [
            'loan_guarantee_id' => $guarantee->id,
            'employer_name' => $data['employer_name'],
            'employer_address' => $data['employer_address'],
            'employer_phone' => $data['employer_phone'] ?? null,
            'employee_position' => $data['employee_position'],
            'monthly_salary' => $data['monthly_salary'],
            'employment_start_date' => $data['employment_start_date'],
        ];

        // Handle file uploads
        if ($request->hasFile("guarantees.{$index}.salary.employment_letter")) {
            $salaryData['employment_letter_path'] = $request->file("guarantees.{$index}.salary.employment_letter")->store('loan-documents/salary', 'public');
        }

        if ($request->hasFile("guarantees.{$index}.salary.confirmation_letter")) {
            $salaryData['confirmation_letter_path'] = $request->file("guarantees.{$index}.salary.confirmation_letter")->store('loan-documents/salary', 'public');
        }

        if ($request->hasFile("guarantees.{$index}.salary.payslips")) {
            $payslipPaths = [];
            foreach ($request->file("guarantees.{$index}.salary.payslips") as $file) {
                $payslipPaths[] = $file->store('loan-documents/salary', 'public');
            }
            $salaryData['payslip_paths'] = $payslipPaths;
        }

        LoanSalaryGuarantee::create($salaryData);
    }

    /**
     * Process collateral guarantee
     */
    private function processCollateralGuarantee(LoanGuarantee $guarantee, array $data, Request $request, int $index)
    {
        $collateralData = [
            'loan_guarantee_id' => $guarantee->id,
            'item_type' => $data['item_type'],
            'item_description' => $data['item_description'],
            'estimated_value' => $data['estimated_value'],
            'ownership_document_type' => $data['ownership_document_type'],
            'ownership_document_number' => $data['ownership_document_number'],
            'ownership_document_date' => $data['ownership_document_date'],
            'ownership_details' => $data['ownership_details'] ?? null,
        ];

        // Handle file upload
        if ($request->hasFile("guarantees.{$index}.collateral.document_file")) {
            $collateralData['document_file_path'] = $request->file("guarantees.{$index}.collateral.document_file")->store('loan-documents/collateral', 'public');
        }

        LoanCollateral::create($collateralData);
    }

    /**
     * Process guarantor guarantee
     */
    private function processGuarantorGuarantee(LoanGuarantee $guarantee, array $data)
    {
        // Validate guarantor eligibility
        $guarantor = User::find($data['guarantor_user_id']);
        if (!$guarantor || !$this->isGuarantorEligible($guarantor)) {
            return ['error' => 'Selected guarantor is not eligible. Guarantors must be registered members for more than 3 months with active savings accounts.'];
        }

        LoanGuarantor::create([
            'loan_guarantee_id' => $guarantee->id,
            'guarantor_user_id' => $data['guarantor_user_id'],
            'guarantee_amount' => $data['guarantee_amount'],
            'relationship_type' => $data['relationship_type'],
            'relationship_details' => $data['relationship_details'] ?? null,
        ]);

        return ['success' => true];
    }

    /**
     * Update existing guarantees
     */
    private function updateExistingGuarantees(Loan $loan, array $existingGuarantees, Request $request)
    {
        foreach ($existingGuarantees as $index => $guaranteeData) {
            $guaranteeId = $guaranteeData['id'];
            $guarantee = LoanGuarantee::find($guaranteeId);

            if (!$guarantee || $guarantee->loan_id !== $loan->id) {
                continue; // Skip if guarantee doesn't exist or doesn't belong to this loan
            }

            // Update guarantee notes if provided
            if (isset($guaranteeData['notes'])) {
                $guarantee->update(['notes' => $guaranteeData['notes']]);
            }

            // Update specific guarantee type data
            switch ($guaranteeData['type']) {
                case 'salary':
                    $this->updateSalaryGuarantee($guarantee, $guaranteeData['salary'], $request, $index);
                    break;
                case 'collateral':
                    $this->updateCollateralGuarantee($guarantee, $guaranteeData['collateral'], $request, $index);
                    break;
                case 'guarantor':
                    $result = $this->updateGuarantorGuarantee($guarantee, $guaranteeData['guarantor']);
                    if (isset($result['error'])) {
                        return $result; // Return error to be handled by controller
                    }
                    break;
            }
        }
    }

    /**
     * Update salary guarantee
     */
    private function updateSalaryGuarantee(LoanGuarantee $guarantee, array $data, Request $request, int $index)
    {
        if ($guarantee->salaryGuarantee) {
            $salaryData = [
                'employer_name' => $data['employer_name'],
                'employer_address' => $data['employer_address'],
                'employer_phone' => $data['employer_phone'] ?? null,
                'employee_position' => $data['employee_position'],
                'monthly_salary' => $data['monthly_salary'],
                'employment_start_date' => $data['employment_start_date'],
            ];

            // Handle file uploads (only if new files are provided)
            if ($request->hasFile("existing_guarantees.{$index}.salary.employment_letter")) {
                $salaryData['employment_letter_path'] = $request->file("existing_guarantees.{$index}.salary.employment_letter")->store('loan-documents/salary', 'public');
            }

            if ($request->hasFile("existing_guarantees.{$index}.salary.confirmation_letter")) {
                $salaryData['confirmation_letter_path'] = $request->file("existing_guarantees.{$index}.salary.confirmation_letter")->store('loan-documents/salary', 'public');
            }

            if ($request->hasFile("existing_guarantees.{$index}.salary.payslips")) {
                $payslipPaths = [];
                foreach ($request->file("existing_guarantees.{$index}.salary.payslips") as $file) {
                    $payslipPaths[] = $file->store('loan-documents/salary', 'public');
                }
                $salaryData['payslip_paths'] = $payslipPaths;
            }

            $guarantee->salaryGuarantee->update($salaryData);
        }
    }

    /**
     * Update collateral guarantee
     */
    private function updateCollateralGuarantee(LoanGuarantee $guarantee, array $data, Request $request, int $index)
    {
        foreach ($guarantee->collateral as $collateral) {
            $collateralData = [
                'item_type' => $data['item_type'],
                'item_description' => $data['item_description'],
                'estimated_value' => $data['estimated_value'],
                'ownership_document_type' => $data['ownership_document_type'],
                'ownership_document_number' => $data['ownership_document_number'],
                'ownership_document_date' => $data['ownership_document_date'],
                'ownership_details' => $data['ownership_details'] ?? null,
            ];

            // Handle file upload (only if new file is provided)
            if ($request->hasFile("existing_guarantees.{$index}.collateral.document_file")) {
                $collateralData['document_file_path'] = $request->file("existing_guarantees.{$index}.collateral.document_file")->store('loan-documents/collateral', 'public');
            }

            $collateral->update($collateralData);
        }
    }

    /**
     * Update guarantor guarantee
     */
    private function updateGuarantorGuarantee(LoanGuarantee $guarantee, array $data)
    {
        foreach ($guarantee->guarantors as $guarantor) {
            // Validate guarantor eligibility
            $guarantorUser = User::find($data['guarantor_user_id']);
            if (!$guarantorUser || !$this->isGuarantorEligible($guarantorUser)) {
                return ['error' => 'Selected guarantor is not eligible. Guarantors must be registered members for more than 3 months with active savings accounts.'];
            }

            $guarantor->update([
                'guarantor_user_id' => $data['guarantor_user_id'],
                'guarantee_amount' => $data['guarantee_amount'],
                'relationship_type' => $data['relationship_type'],
                'relationship_details' => $data['relationship_details'] ?? null,
            ]);
        }
        return ['success' => true];
    }

    /**
     * Check if a user is eligible to be a guarantor
     */
    private function isGuarantorEligible(User $user)
    {
        // Check if member for more than 3 months
        if (!$user->membership || $user->membership->created_at->diffInMonths(now()) < 3) {
            return false;
        }

        // Check if has active savings
        return $user->savings()->where('status', 'active')->exists();
    }

    /**
     * Check for defaulted loans and update their status
     */
    public function checkDefaults()
    {
        $defaultedLoans = Loan::where('return_date', '<', now())
            ->where('status', '!=', 'paid')
            ->where('status', '!=', 'defaulted')
            ->where('balance', '>', 0)
            ->with('user')
            ->get();

        $updatedCount = 0;

        foreach ($defaultedLoans as $loan) {
            $loan->update(['status' => 'defaulted']);
            $this->sendDefaultNotification($loan);
            $updatedCount++;
        }

        return response()->json([
            'success' => true,
            'message' => "Checked for defaulted loans. Updated {$updatedCount} loans.",
            'updated_count' => $updatedCount
        ]);
    }

    /**
     * Send default notification email to member
     */
    private function sendDefaultNotification(Loan $loan)
    {
        try {
            \Mail::send('emails.loan-default-notification', [
                'loan' => $loan,
                'user' => $loan->user,
                'outstanding_balance' => $loan->balance,
                'return_date' => $loan->return_date,
                'application_date' => $loan->application_date,
            ], function ($message) use ($loan) {
                $message->to($loan->user->email)
                        ->subject('Loan Default Notice - Morio Sacco');
            });

            \Log::info('Loan default notification email sent', [
                'loan_id' => $loan->id,
                'email' => $loan->user->email
            ]);
        } catch (\Exception $e) {
            \Log::error('Failed to send loan default notification email', [
                'loan_id' => $loan->id,
                'email' => $loan->user->email,
                'error' => $e->getMessage()
            ]);
        }
    }
}
