<?php
session_start();
require_once 'includes/config.php';
require_once '../cbs.creativewebsolutions.co.ke/includes/sms_helper.php';
require_once '../cbs.creativewebsolutions.co.ke/includes/email_helper.php';

// Check if member is logged in and has an active loan application
if (!isset($_SESSION['member_id']) || !isset($_SESSION['loan_application'])) {
    header("Location: loan_application.php");
    exit();
}

$memberId = $_SESSION['member_id'];
$loanApp = $_SESSION['loan_application'];

// Generate CSRF token
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

// Get notification templates
try {
    $notificationTemplates = $pdo->query("
        SELECT type, template_name, template_sms, template_email 
        FROM notification_templates 
        WHERE type IN ('guarantor_request', 'guarantors_added')
    ")->fetchAll(PDO::FETCH_ASSOC);
    
    // Prepare templates
    $templates = [];
    foreach ($notificationTemplates as $template) {
        $templates[$template['type']] = $template;
    }
} catch (PDOException $e) {
    error_log("Database error loading templates: " . $e->getMessage());
    $templates = [];
}

/**
 * Secure placeholder processing with context-aware sanitization
 */
function processMessagePlaceholders($message, $memberData, $context = 'email') {
    // Format dates
    $registration_date = !empty($memberData['registration_date']) ? date('jS F Y', strtotime($memberData['registration_date'])) : '';
    $application_date = !empty($memberData['application_date']) ? date('jS F Y', strtotime($memberData['application_date'])) : '';
    
    // Context-aware sanitization
    $sanitize = function($value, $context) {
        if ($context === 'email') {
            return htmlspecialchars($value ?? '', ENT_QUOTES, 'UTF-8');
        }
        // For SMS - remove line breaks and special chars that could cause SMS injection
        return preg_replace('/[\r\n]+/', ' ', $value ?? '');
    };
    
    $placeholders = [
        // Basic info
        '{id}' => $sanitize($memberData['id'] ?? '', $context),
        '{personal_number}' => $sanitize($memberData['personal_number'] ?? '', $context),
        '{member_number}' => $sanitize($memberData['member_number'] ?? '', $context),
        
        // Names
        '{first_name}' => $sanitize($memberData['first_name'] ?? '', $context),
        '{middle_name}' => $sanitize($memberData['middle_name'] ?? '', $context),
        '{last_name}' => $sanitize($memberData['last_name'] ?? '', $context),
        '{full_name}' => $sanitize(
            trim(($memberData['first_name'] ?? '') . ' ' . 
            ($memberData['middle_name'] ?? '') . ' ' . 
            ($memberData['last_name'] ?? '')), 
            $context
        ),
        
        // Contact info - additional validation
        '{phone_number}' => preg_replace('/[^0-9+]/', '', $memberData['phone_number'] ?? ''),
        '{email_address}' => filter_var($memberData['email_address'] ?? '', FILTER_SANITIZE_EMAIL),
        
        // Loan info - formatted numbers
        '{loan_number}' => $sanitize($memberData['loan_number'] ?? '', $context),
        '{loan_amount}' => isset($memberData['loan_amount']) ? 
            number_format((float)$memberData['loan_amount'], 2) : '0.00',
        '{guarantee_amount}' => isset($memberData['guarantee_amount']) ? 
            number_format((float)$memberData['guarantee_amount'], 2) : '0.00',
        '{application_date}' => $application_date,
        '{registration_date}' => $registration_date,
        
        // Current date/time
        '{current_date}' => date('jS F Y'),
        '{current_time}' => date('H:i'),
        '{today}' => date('jS F Y'),
        '{now}' => date('jS F Y H:i')
    ];
    
    return str_replace(
        array_keys($placeholders),
        array_values($placeholders),
        $message
    );
}

/**
 * Enhanced notification function with validation and logging
 */
function sendLoanNotification($pdo, $memberId, $templateType, $loanData, $guaranteeAmount = null) {
    global $templates;
    
    // Get member details with additional validation
    $stmt = $pdo->prepare("
        SELECT 
            m.id, m.first_name, m.middle_name, m.last_name, 
            m.personal_number, m.phone_number, m.email_address, 
            m.communication_preference
        FROM members m
        WHERE m.id = ?
    ");
    $stmt->execute([$memberId]);
    $member = $stmt->fetch(PDO::FETCH_ASSOC);
    
    if (!$member) {
        error_log("Notification failed: Member $memberId not found");
        return false;
    }
    
   
    
    // Get template with validation
    $template = $templates[$templateType] ?? null;
    if (!$template) {
        error_log("Notification template $templateType not found");
        return false;
    }
    
    // Prepare data with additional validation
    $notificationData = array_merge($member, [
        'loan_number' => $loanData['loan_number'] ?? '',
        'loan_amount' => $loanData['loan_amount'] ?? 0,
        'application_date' => $loanData['application_date'] ?? date('Y-m-d H:i:s'),
        'guarantee_amount' => $guaranteeAmount
    ]);
    
    $results = [];
    $communicationPref = strtolower($member['communication_preference'] ?? 'both');
    
    // Process SMS notification
    if (($communicationPref === 'sms' || $communicationPref === 'both') && !empty($member['phone_number'])) {
        $phone = preg_replace('/[^0-9+]/', '', $member['phone_number']);
        if (preg_match('/^\+?[0-9]{10,15}$/', $phone)) {
            $smsContent = processMessagePlaceholders($template['template_sms'], $notificationData, 'sms');
            $smsContent = substr($smsContent, 0, 160); // Enforce SMS length limit
            
            try {
                $results['sms'] = sendSms($pdo, $phone, $smsContent);
                logNotification($pdo, $memberId, 'sms', $templateType, $results['sms']);
            } catch (Exception $e) {
                error_log("SMS send failed: " . $e->getMessage());
                $results['sms'] = false;
            }
        } else {
            error_log("Invalid phone number format for member $memberId");
        }
    }
    
    // Process Email notification
    if (($communicationPref === 'email' || $communicationPref === 'both') && !empty($member['email_address'])) {
        $email = filter_var($member['email_address'], FILTER_SANITIZE_EMAIL);
        if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $emailSubject = processMessagePlaceholders(
                "Loan Notification: #{loan_number}", 
                $notificationData,
                'email'
            );
            $emailContent = processMessagePlaceholders(
                $template['template_email'], 
                $notificationData,
                'email'
            );
            
            try {
                $results['email'] = sendEmail($email, $emailSubject, $emailContent);
                logNotification($pdo, $memberId, 'email', $templateType, $results['email']);
            } catch (Exception $e) {
                error_log("Email send failed: " . $e->getMessage());
                $results['email'] = false;
            }
        } else {
            error_log("Invalid email address for member $memberId");
        }
    }
    
    return $results;
}

/**
 * Log notification attempts
 */
function logNotification($pdo, $memberId, $channel, $templateType, $success) {
    try {
        $stmt = $pdo->prepare("
            INSERT INTO notification_logs 
            (member_id, channel, template_type, status, created_at)
            VALUES (?, ?, ?, ?, NOW())
        ");
        $stmt->execute([
            $memberId, 
            $channel, 
            $templateType, 
            $success ? 'sent' : 'failed'
        ]);
        
        
    } catch (PDOException $e) {
        error_log("Failed to log notification: " . $e->getMessage());
    }
}

// Process guarantor specification
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['submit_guarantors'])) {
    try {
        // Verify CSRF token
        if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
            throw new Exception("Invalid form submission");
        }

        $pdo->beginTransaction();

        $totalGuaranteed = 0;
        $guarantors = [];
        
        // 1. Process loanee's self-guarantee first
        $selfGuaranteeAmount = $loanApp['self_guarantee_amount'] ?? 0;
        
        if ($selfGuaranteeAmount > 0) {
            $stmt = $pdo->prepare("
                UPDATE member_accounts 
                SET 
                    available_balance = available_balance - ?,
                    self_guaranteed_amount = self_guaranteed_amount + ?
                WHERE 
                    member_id = ? 
                    AND account_type_id = ?
                    AND available_balance >= ?
            ");
            $stmt->execute([
                $selfGuaranteeAmount,
                $selfGuaranteeAmount,
                $memberId,
                $loanApp['basis_account_id'],
                $selfGuaranteeAmount
            ]);
            
            if ($stmt->rowCount() === 0) {
                throw new Exception("Insufficient balance for self-guarantee amount");
            }
        }
        
        // 2. Process external guarantors
        for ($i = 1; $i <= 3; $i++) {
            if (!empty($_POST['guarantor_'.$i.'_number']) && $_POST['guarantor_'.$i.'_amount'] > 0) {
                $memberNumber = trim($_POST['guarantor_'.$i.'_number']);
                $amount = (float)$_POST['guarantor_'.$i.'_amount'];
                
                // Validate amount
                if ($amount < 100) {
                    throw new Exception("Minimum guarantee amount is Ksh 100");
                }
                
                // Verify guarantor exists and is not the applicant
                $stmt = $pdo->prepare("
                    SELECT id, first_name, last_name, email_address, phone_number, communication_preference 
                    FROM members 
                    WHERE personal_number = ? AND id != ?
                ");
                $stmt->execute([$memberNumber, $memberId]);
                $guarantor = $stmt->fetch();
                
                if (!$guarantor) {
                    throw new Exception("Member number $memberNumber not found or invalid");
                }
                
                // Verify guarantor has sufficient savings
                $stmt = $pdo->prepare("
                    SELECT a.id, a.available_balance, t.account_name
                    FROM member_accounts a
                    JOIN account_types t ON a.account_type_id = t.id
                    WHERE a.member_id = ? AND t.account_type = 'savings' AND a.available_balance >= ?
                    LIMIT 1
                ");
                $stmt->execute([$guarantor['id'], $amount]);
                $account = $stmt->fetch();
                
                if (!$account) {
                    throw new Exception("Member $memberNumber doesn't have sufficient savings to guarantee Ksh ".number_format($amount, 2));
                }
                
                $guarantors[] = [
                    'id' => $guarantor['id'],
                    'name' => $guarantor['first_name'].' '.$guarantor['last_name'],
                    'email' => $guarantor['email_address'],
                    'phone' => $guarantor['phone_number'],
                    'communication_preference' => $guarantor['communication_preference'] ?? 'both',
                    'amount' => $amount,
                    'account_id' => $account['id'],
                    'account_name' => $account['account_name'],
                    'original_balance' => $account['available_balance']
                ];
                
                $totalGuaranteed += $amount;
            }
        }
        
        // 3. Verify guarantor requirements
        if ($loanApp['need_guarantors'] && count($guarantors) === 0) {
            throw new Exception("You need at least one guarantor for this loan");
        }
        
        $totalCoverage = $selfGuaranteeAmount + $totalGuaranteed;
        if ($totalCoverage < $loanApp['loan_amount']) {
            throw new Exception("Insufficient coverage. You need additional Ksh " . 
                number_format($loanApp['loan_amount'] - $totalCoverage, 2));
        }
        
        // 4. Process guarantor commitments
        foreach ($guarantors as $guarantor) {
            // Record guarantor relationship
            $stmt = $pdo->prepare("
                INSERT INTO loan_guarantors 
                (loan_id, guarantor_member_id, guarantee_amount, savings_account_id, 
                 added_by, status, original_balance, created_at)
                VALUES (?, ?, ?, ?, ?, 'pending', ?, NOW())
            ");
            $stmt->execute([
                $loanApp['loan_id'],
                $guarantor['id'],
                $guarantor['amount'],
                $guarantor['account_id'],
                $memberId,
                $guarantor['original_balance']
            ]);
            
            $guarantorId = $pdo->lastInsertId();
            
            // Deduct from guarantor's available balance
            $stmt = $pdo->prepare("
                UPDATE member_accounts
                SET available_balance = available_balance - ?,
                    guaranteed_amount = guaranteed_amount + ?
                WHERE id = ? AND member_id = ?
                AND available_balance >= ?
            ");
            $stmt->execute([
                $guarantor['amount'],
                $guarantor['amount'],
                $guarantor['account_id'],
                $guarantor['id'],
                $guarantor['amount']
            ]);
            
            if ($stmt->rowCount() === 0) {
                throw new Exception("Failed to update guarantor's account balance");
            }
            
       
            
            // Send notification
            $loanData = [
                'loan_number' => $loanApp['loan_number'],
                'loan_amount' => $loanApp['loan_amount'],
                'application_date' => date('Y-m-d H:i:s')
            ];
            
            sendLoanNotification(
                $pdo,
                $guarantor['id'],
                'guarantor_request',
                $loanData,
                $guarantor['amount']
            );
        }
        
        // 5. Update loan status with all guarantee information
        $stmt = $pdo->prepare("
            UPDATE loans 
            SET status = 'pending',
                total_guaranteed_amount = ?,
                self_guaranteed_amount = ?,
                guarantor_count = ?
            
            WHERE id = ? AND status = 'pending'
        ");
        $stmt->execute([
            $totalGuaranteed,
            $selfGuaranteeAmount,
            count($guarantors),
            $loanApp['loan_id']
        ]);
        
        // 6. Send notification to applicant
        sendLoanNotification(
            $pdo,
            $memberId,
            'guarantors_added',
            [
                'loan_number' => $loanApp['loan_number'],
                'loan_amount' => $loanApp['loan_amount'],
                'application_date' => date('Y-m-d H:i:s'),
                'guarantor_count' => count($guarantors)
            ]
        );
        
        $pdo->commit();
        
        // Clear session and redirect
        unset($_SESSION['loan_application']);
        $_SESSION['success'] = "Loan application submitted successfully! Guarantor requests sent.";
        header("Location: loan_status.php?id=".$loanApp['loan_id']);
        exit();
        
    } catch (Exception $e) {
        $pdo->rollBack();
        $_SESSION['error'] = "Error processing application: " . $e->getMessage();
        error_log("Loan application error: " . $e->getMessage());
        header("Location: specify_guarantors.php");
        exit();
    }
}

// Display any messages
$error = isset($_SESSION['error']) ? $_SESSION['error'] : null;
unset($_SESSION['error']);

// HTML and form display remains the same as in original code
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Specify Guarantors</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        .guarantor-box {
            background-color: #f8f9fa;
            border-radius: 5px;
            padding: 20px;
            margin-bottom: 20px;
            border-left: 4px solid #0d6efd;
            transition: all 0.3s ease;
        }
        .guarantor-box:hover {
            box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1);
        }
        .form-container {
            max-width: 800px;
            margin: 0 auto;
        }
        .coverage-display {
            font-size: 1.1rem;
            padding: 10px;
            border-radius: 5px;
        }
        .coverage-good {
            background-color: #d1e7dd;
            color: #0f5132;
        }
        .coverage-warning {
            background-color: #fff3cd;
            color: #664d03;
        }
    </style>
</head>
<body>
    <?php include './partials/layouts/layoutTop.php'; ?>
    
    <div class="container py-5">
        <div class="form-container">
            <div class="card shadow">
                <div class="card-header bg-primary text-white">
                    <h3 class="mb-0"><i class="fas fa-user-friends me-2"></i>Specify Guarantors</h3>
                </div>
                
                <div class="card-body">
                    <?php if ($error): ?>
                        <div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
                    <?php endif; ?>
                    
                    <div class="alert alert-info mb-4">
                        <div class="d-flex align-items-center">
                            <i class="fas fa-info-circle fa-2x me-3"></i>
                            <div>
                                <h5 class="mb-1">Loan Application Details</h5>
                                <p class="mb-1">Loan Number: <strong><?= htmlspecialchars($loanApp['loan_number']) ?></strong></p>
                                <p class="mb-1">Amount: <strong>Ksh <?= number_format($loanApp['loan_amount'], 2) ?></strong></p>
                                <p class="mb-1">Self Guarantee: <strong>Ksh <?= number_format($loanApp['self_guarantee_amount'] ?? 0, 2) ?></strong></p>
                            </div>
                        </div>
                    </div>
                    
                    <div class="alert <?= ($loanApp['loan_amount'] - ($loanApp['self_guarantee_amount'] ?? 0) > 0) ? 'alert-warning' : 'alert-success' ?> mb-4">
                        <div class="d-flex justify-content-between align-items-center">
                            <div>
                                <i class="fas fa-<?= ($loanApp['loan_amount'] - ($loanApp['self_guarantee_amount'] ?? 0) > 0 ? 'exclamation-triangle' : 'check-circle') ?> me-2"></i>
                                <span id="coverage-status">
                                    <?= ($loanApp['loan_amount'] - ($loanApp['self_guarantee_amount'] ?? 0) > 0) ? 
                                        'Additional Guarantee Needed: Ksh '.number_format($loanApp['loan_amount'] - ($loanApp['self_guarantee_amount'] ?? 0), 2) : 
                                        'Your loan is fully covered!' ?>
                                </span>
                            </div>
                            <div id="remaining-display" class="coverage-display <?= ($loanApp['loan_amount'] - ($loanApp['self_guarantee_amount'] ?? 0) > 0) ? 'coverage-warning' : 'coverage-good' ?>">
                                <?= ($loanApp['loan_amount'] - ($loanApp['self_guarantee_amount'] ?? 0) > 0) ? 
                                    'Remaining: Ksh '.number_format($loanApp['loan_amount'] - ($loanApp['self_guarantee_amount'] ?? 0), 2) : 
                                    'Fully Covered' ?>
                            </div>
                        </div>
                    </div>

                    
                    <form method="POST" id="guarantorForm">
                        <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
                        
                        <div class="mb-4">
                            <h5><i class="fas fa-question-circle me-2"></i>How Guarantors Work</h5>
                            <ul>
                                <li>Guarantors must be existing members with sufficient savings</li>
                                <li>Each guarantor will receive a notification to approve the request</li>
                                <li>The guaranteed amount will be held in their account until loan repayment</li>
                                <li>Minimum guarantee amount is Ksh 100</li>
                                <li>Guarantors must have sufficient available balance</li>
                            </ul>
                        </div>
                        
                        <?php for ($i = 1; $i <= 3; $i++): ?>
                            <div class="guarantor-box">
                                <h5><i class="fas fa-user-tie me-2"></i>Guarantor <?= $i ?></h5>
                                <div class="row">
                                    <div class="col-md-6 mb-3">
                                        <label class="form-label">Member Number <span class="text-danger">*</span></label>
                                        <div class="input-group">
                                            <span class="input-group-text"><i class="fas fa-id-card"></i></span>
                                            <input type="text" name="guarantor_<?= $i ?>_number" class="form-control" 
                                                   placeholder="Enter member's personal number" pattern="[A-Za-z0-9]+" title="Alphanumeric characters only">
                                        </div>
                                    </div>
                                    <div class="col-md-6 mb-3">
                                        <label class="form-label">Amount to Guarantee (Ksh) <span class="text-danger">*</span></label>
                                        <div class="input-group">
                                            <span class="input-group-text">Ksh</span>
                                            <input type="number" name="guarantor_<?= $i ?>_amount" class="form-control guarantee-amount" 
                                                   min="100" step="100" placeholder="Enter amount" required>
                                        </div>
                                        <small class="text-muted">Minimum: Ksh 100</small>
                                    </div>
                                </div>
                            </div>
                        <?php endfor; ?>
                        
                        <div class="d-grid gap-2 d-md-flex justify-content-md-end mt-4">
                            <a href="loan_application.php" class="btn btn-secondary me-md-2">
                                <i class="fas fa-arrow-left me-2"></i>Back
                            </a>
                            <button type="submit" name="submit_guarantors" class="btn btn-primary">
                                <i class="fas fa-paper-plane me-2"></i>Submit Guarantor Requests
                            </button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>

    <?php include './partials/layouts/layoutBottom.php'; ?>
    
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        // Calculate total guaranteed amount
        function calculateCoverage() {
            let total = 0;
            document.querySelectorAll('.guarantee-amount').forEach(input => {
                total += parseFloat(input.value) || 0;
            });
            
            const selfGuarantee = <?= $loanApp['self_guarantee_amount'] ?? 0 ?>;
            const loanAmount = <?= $loanApp['loan_amount'] ?>;
            const remainingAmount = loanAmount - selfGuarantee - total;
            
            const coverageStatus = document.getElementById('coverage-status');
            const remainingDisplay = document.getElementById('remaining-display');
            
            if (remainingAmount <= 0) {
                coverageStatus.textContent = 'Your loan is fully covered!';
                remainingDisplay.textContent = 'Fully Covered';
                remainingDisplay.className = 'coverage-display coverage-good';
            } else {
                coverageStatus.textContent = 'Additional Guarantee Needed: Ksh ' + (loanAmount - selfGuarantee).toLocaleString();
                remainingDisplay.textContent = 'Remaining: Ksh ' + remainingAmount.toLocaleString();
                remainingDisplay.className = 'coverage-display coverage-warning';
            }
        }
        
        // Attach event listeners to all amount inputs
        document.querySelectorAll('.guarantee-amount').forEach(input => {
            input.addEventListener('input', calculateCoverage);
        });
        
        // Initial calculation
        calculateCoverage();
        
        // Form validation
        document.getElementById('guarantorForm').addEventListener('submit', function(e) {
            let hasGuarantor = false;
            let allValid = true;
            
            for (let i = 1; i <= 3; i++) {
                const numberInput = document.querySelector(`input[name="guarantor_${i}_number"]`);
                const amountInput = document.querySelector(`input[name="guarantor_${i}_amount"]`);
                
                // If either field has a value, both are required
                if (numberInput.value || amountInput.value) {
                    if (!numberInput.value || !amountInput.value) {
                        alert(`Please complete all fields for Guarantor ${i} or leave both blank`);
                        allValid = false;
                        break;
                    }
                    
                    if (parseFloat(amountInput.value) < 100) {
                        alert(`Minimum guarantee amount is Ksh 100 for Guarantor ${i}`);
                        allValid = false;
                        break;
                    }
                    
                    hasGuarantor = true;
                }
            }
            
            const selfGuarantee = <?= $loanApp['self_guarantee_amount'] ?? 0 ?>;
            const loanAmount = <?= $loanApp['loan_amount'] ?>;
            let totalGuaranteed = 0;
            
            document.querySelectorAll('.guarantee-amount').forEach(input => {
                totalGuaranteed += parseFloat(input.value) || 0;
            });
            
            const remainingAmount = loanAmount - selfGuarantee - totalGuaranteed;
            
            if (remainingAmount > 0) {
                alert(`Insufficient guarantor coverage. You still need Ksh ${remainingAmount.toLocaleString()}`);
                allValid = false;
            }
            
            if (<?= $loanApp['need_guarantors'] ? 'true' : 'false' ?> && !hasGuarantor) {
                alert("You need at least one guarantor for this loan");
                allValid = false;
            }
            
            if (!allValid) {
                e.preventDefault();
            }
        });
    </script>
</body>
</html>