<?php
// Load CORS configuration FIRST
require_once __DIR__ . '/includes/cors.php';
configureCors();

// Load environment variables
require_once __DIR__ . '/includes/config_loader.php';

// Load dependencies
require_once __DIR__ . '/includes/config.php';
require_once __DIR__ . '/includes/auth_functions.php'; // Your existing auth functions
require_once __DIR__ . '/includes/sms_helper.php';
require_once __DIR__ . '/includes/email_helper.php'; // If you have separate email helper
require_once __DIR__ . '/auth/AuditLogger.php';
require_once __DIR__ . '/auth/JWTManager.php';
require_once __DIR__ .  '/includes/functions.php';

/* ================= SESSION ================= */
if (session_status() === PHP_SESSION_NONE) {
    session_start([
        'cookie_httponly' => true,
        'cookie_secure'  => true,     // HTTPS REQUIRED
        'cookie_samesite'=> 'None'
    ]);
}

/* ================= CORS HEADERS ================= */
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
header("Access-Control-Allow-Origin: $origin");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, X-Session-ID');
header('Content-Type: application/json');

/* ================= SECURITY HEADERS ================= */
header('X-Frame-Options: DENY');
header('X-Content-Type-Options: nosniff');
header('X-XSS-Protection: 1; mode=block');

/* ================= PREFLIGHT ================= */
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

/* ================= DEBUG (DEV ONLY) ================= */
if (ENVIRONMENT === 'development') {
    error_log("Session ID: " . session_id());
    error_log("Session data: " . print_r($_SESSION, true));
    error_log("Cookies: " . print_r($_COOKIE, true));
}

/* ================= AUTH CHECK ================= */
if (empty($_SESSION['member_id'])) {
    http_response_code(401);
    echo json_encode([
        'success' => false,
        'error'   => 'Unauthorized - Please login first',
        'code'    => 'SESSION_EXPIRED'
    ]);
    exit;
}

/* ================= LOAD DEPENDENCIES ================= */


/* ================= REQUEST DATA ================= */
$method    = $_SERVER['REQUEST_METHOD'];
$member_id = $_SESSION['member_id'];
$action    = $_GET['action'] ?? '';

// ============================================
// CHARGE MANAGEMENT CLASS (MATCHING LOAN-APPLICATION-API.PHP)
// ============================================

class LoanChargesManager {
    private $pdo;
    
    public function __construct($pdo) {
        $this->pdo = $pdo;
    }
    
    /**
     * Get charges for specific loan type from database
     * IDENTICAL TO loan-application-api.php
     */
    public function getLoanCharges($loanTypeId) {
        try {
            $stmt = $this->pdo->prepare("
                SELECT id, charge_type, charge_value, value_type, description, charge_code
                FROM account_charges
                WHERE account_type_id = ? AND status = 'active'
            ");
            $stmt->execute([$loanTypeId]);
            return $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
        } catch (PDOException $e) {
            error_log("Failed to fetch loan charges: " . $e->getMessage());
            return [];
        }
    }
    
    /**
     * Calculate charges for a loan
     * IDENTICAL TO loan-application-api.php
     */
    public function calculateCharges($loanAmount, $charges) {
        $totalCharges = 0;
        $calculatedCharges = [];
        
        foreach ($charges as $charge) {
            $chargeAmount = 0;
            
            if ($charge['value_type'] === 'percentage') {
                $chargeAmount = $loanAmount * ($charge['charge_value'] / 100);
            } else {
                $chargeAmount = $charge['charge_value'];
            }
            
            $totalCharges += $chargeAmount;
            
            $calculatedCharges[] = [
                'charge_id' => $charge['id'],
                'charge_type' => $charge['charge_type'],
                'charge_amount' => round($chargeAmount, 2),
                'value_type' => $charge['value_type'],
                'charge_value' => $charge['charge_value'],
                'description' => $charge['description'] ?? '',
                'charge_code' => $charge['charge_code'] ?? ''
            ];
        }
        
        return [
            'total_charges' => round($totalCharges, 2),
            'charges' => $calculatedCharges,
            'total_loan_amount' => $loanAmount + $totalCharges
        ];
    }
    
    /**
     * Save loan charges to database
     * IDENTICAL TO loan-application-api.php
     */
    public function saveLoanCharges($loanId, $charges) {
        try {
            foreach ($charges as $charge) {
                $stmt = $this->pdo->prepare("
                    INSERT INTO loan_charges (
                        loan_id, charge_id, charge_type, charge_amount,
                        value_type, charge_value, description, charge_code, created_at
                    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())
                ");
                $stmt->execute([
                    $loanId,
                    $charge['charge_id'],
                    $charge['charge_type'],
                    $charge['charge_amount'],
                    $charge['value_type'],
                    $charge['charge_value'],
                    $charge['description'],
                    $charge['charge_code']
                ]);
            }
            return true;
        } catch (PDOException $e) {
            error_log("Failed to save loan charges: " . $e->getMessage());
            throw new Exception("Failed to save loan charges");
        }
    }
    
    /**
     * Get loan charges for a specific loan from loan_charges table
     * Returns detailed list of individual charges
     */
   public function getLoanChargesDetails($loanId)
{
    try {
        $stmt = $this->pdo->prepare("
            SELECT 
                lc.id,
                lc.charge_id,
                lc.charge_amount,
                lc.created_at,
                COALESCE(lc.charge_type, ac.charge_type) AS charge_type,
                COALESCE(lc.value_type, ac.value_type) AS value_type,
                COALESCE(lc.calculation_method, ac.calculation_method) AS calculation_method
            FROM loan_charges lc
            LEFT JOIN account_charges ac ON lc.charge_id = ac.id
            WHERE lc.loan_id = ?
            ORDER BY lc.created_at ASC
        ");

        $stmt->execute([$loanId]);
        $charges = $stmt->fetchAll(PDO::FETCH_ASSOC);

        $totalCharges = 0;
        $chargesBreakdown = [];

        foreach ($charges as $charge) {
            $amount = (float) $charge['charge_amount'];
            $totalCharges += $amount;

            $chargesBreakdown[] = [
                'id' => (int) $charge['id'],
                'charge_id' => (int) $charge['charge_id'],
                'charge_type' => $charge['charge_type'],
                'value_type' => $charge['value_type'],
                'calculation_method' => $charge['calculation_method'],
                'charge_amount' => round($amount, 2),
                'created_at' => $charge['created_at'],
                'formatted_amount' => 'Ksh ' . number_format($amount, 2),
                'calculation' => $charge['value_type'] === 'percentage'
                    ? 'Percentage based charge'
                    : 'Fixed amount'
            ];
        }

        return [
            'charges' => $chargesBreakdown,
            'total_charges' => round($totalCharges, 2),
            'charges_count' => count($chargesBreakdown),
            'formatted_total' => 'Ksh ' . number_format($totalCharges, 2)
        ];

    } catch (PDOException $e) {
        error_log('Failed to fetch loan charges details: ' . $e->getMessage());

        return [
            'charges' => [],
            'total_charges' => 0,
            'charges_count' => 0,
            'formatted_total' => 'Ksh 0.00'
        ];
    }
}

    
    /**
     * Get total charges for a loan (sum of all individual charges)
     */
    public function getTotalChargesForLoan($loanId) {
        try {
            $stmt = $this->pdo->prepare("
                SELECT SUM(charge_amount) as total_charges
                FROM loan_charges
                WHERE loan_id = ?
            ");
            $stmt->execute([$loanId]);
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            return round($result['total_charges'] ?? 0, 2);
        } catch (PDOException $e) {
            error_log("Failed to get total charges: " . $e->getMessage());
            return 0;
        }
    }
}

// ============================================
// HELPER FUNCTIONS
// ============================================

// Helper function to format loan status
function formatLoanStatus($status) {
    $status = strtolower($status);
    $statusClasses = [
        'pending' => 'badge bg-warning text-dark',
        'pending_approval' => 'badge bg-info',
        'approved' => 'badge bg-success',
        'rejected' => 'badge bg-danger',
        'disbursed' => 'badge bg-primary',
        'active' => 'badge bg-success',
        'completed' => 'badge bg-secondary',
        'cancelled' => 'badge bg-dark',
        'default' => 'badge bg-danger'
    ];
    
    $statusTexts = [
        'pending' => 'Pending',
        'pending_approval' => 'Pending Approval',
        'approved' => 'Approved',
        'rejected' => 'Rejected',
        'disbursed' => 'Disbursed',
        'active' => 'Active',
        'completed' => 'Completed',
        'cancelled' => 'Cancelled',
        'default' => 'Defaulted'
    ];
    
    return [
        'text' => $statusTexts[$status] ?? ucfirst($status),
        'class' => $statusClasses[$status] ?? 'badge bg-dark',
        'value' => $status
    ];
}

// Helper function to get loan purpose name
function getLoanPurposeName($pdo, $purposeId) {
    static $purposes = null;
    
    if ($purposes === null) {
        $stmt = $pdo->query("SELECT id, purpose_name FROM loan_purposes");
        $purposes = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
    }
    
    return $purposes[$purposeId] ?? 'Not specified';
}

// Helper function to get loan account type name
function getLoanAccountTypeName($pdo, $typeId) {
    static $types = null;
    
    if ($types === null) {
        $stmt = $pdo->query("SELECT id, account_name FROM account_types WHERE account_type = 'loan'");
        $types = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
    }
    
    return $types[$typeId] ?? 'Not specified';
}

// Helper function to get savings account details
function getSavingsAccountDetails($pdo, $accountId) {
    if (!$accountId) return null;
    
    $stmt = $pdo->prepare("
        SELECT ma.account_number, at.account_name, at.type
        FROM member_accounts ma
        JOIN account_types at ON ma.account_type_id = at.id
        WHERE ma.id = ?
    ");
    $stmt->execute([$accountId]);
    return $stmt->fetch(PDO::FETCH_ASSOC);
}

// Helper function to get loan summary with individual charges
function getLoanSummary($pdo, $loanId) {
    $chargesManager = new LoanChargesManager($pdo);
    
    $stmt = $pdo->prepare("
        SELECT 
            l.*,
            at.account_name as loan_type_name,
            at.interest_rate as loan_type_interest_rate,
            lp.purpose_name,
            ma.account_number as savings_account_number,
            at2.account_name as savings_account_name,
            at2.type as savings_account_type,
            m.first_name,
            m.last_name,
            m.member_number
        FROM loans l
        LEFT JOIN account_types at ON l.account_type_id = at.id
        LEFT JOIN loan_purposes lp ON l.loan_purpose_id = lp.id
        LEFT JOIN member_accounts ma ON l.savings_account_id = ma.id
        LEFT JOIN account_types at2 ON ma.account_type_id = at2.id
        LEFT JOIN members m ON l.member_id = m.id
        WHERE l.id = ?
    ");
    $stmt->execute([$loanId]);
    $loan = $stmt->fetch(PDO::FETCH_ASSOC);
    
    if (!$loan) {
        return null;
    }
    
    // Get detailed charges from loan_charges table
    $chargesInfo = $chargesManager->getLoanChargesDetails($loanId);
    $loan['charges_details'] = $chargesInfo['charges']; // Individual charges
    $loan['total_charges'] = $chargesInfo['total_charges']; // Total sum
    $loan['charges_count'] = $chargesInfo['charges_count'];
    $loan['charges_formatted_total'] = $chargesInfo['formatted_total'];
    
    // Calculate totals
    $loanAmount = (float)($loan['loan_amount'] ?? 0);
    $totalCharges = (float)($loan['total_charges'] ?? 0);
    $loan['total_with_charges'] = $loanAmount + $totalCharges;
    $loan['total_with_charges_formatted'] = 'Ksh ' . number_format($loanAmount + $totalCharges, 2);
    $loan['loan_amount_formatted'] = 'Ksh ' . number_format($loanAmount, 2);
    $loan['total_charges_formatted'] = 'Ksh ' . number_format($totalCharges, 2);
    
    // Calculate interest if not already set
    if (empty($loan['interest_rate']) && !empty($loan['loan_type_interest_rate'])) {
        $loan['interest_rate'] = $loan['loan_type_interest_rate'];
    }
    
    // Get guarantors
    $stmt = $pdo->prepare("
        SELECT 
            lg.*,
            m.member_number,
            m.first_name,
            m.last_name,
            m.id_number,
            m.phone_number,
            ma.account_number as guarantor_account_number,
            at.account_name as guarantor_account_name
        FROM loan_guarantors lg
        JOIN members m ON lg.guarantor_member_id = m.id
        LEFT JOIN member_accounts ma ON lg.savings_account_id = ma.id
        LEFT JOIN account_types at ON ma.account_type_id = at.id
        WHERE lg.loan_id = ?
    ");
    $stmt->execute([$loanId]);
    $loan['guarantors'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    // Format guarantor status
    foreach ($loan['guarantors'] as &$guarantor) {
        $guarantor['full_name'] = $guarantor['first_name'] . ' ' . $guarantor['last_name'];
        $guarantor['status_formatted'] = formatLoanStatus($guarantor['status']);
    }
    
    // Get collaterals
    $stmt = $pdo->prepare("
        SELECT 
            id, loan_id, collateral_description, collateral_value,
            status, created_at, updated_at, collateral_number,
            collateral_file, collateral_type
        FROM loan_collaterals
        WHERE loan_id = ?
    ");
    $stmt->execute([$loanId]);
    $loan['collaterals'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    // Format collateral status
    foreach ($loan['collaterals'] as &$collateral) {
        $collateral['status_formatted'] = formatLoanStatus($collateral['status']);
    }
    
    return $loan;
}

// Helper function to get all loans with individual charges
function getLoansWithCharges($pdo, $member_id) {
    $chargesManager = new LoanChargesManager($pdo);
    
    $stmt = $pdo->prepare("
        SELECT 
            l.id, l.member_id, l.loan_amount, l.loan_period, l.account_type_id,
            l.is_topup, l.application_date, l.loan_purpose_id, l.loan_number,
            l.status, l.repayment_amount, l.disbursement_date,
            l.disbursement_method, l.registration_date, l.reviewer_id,
            l.approved_loan_amount, l.recommended_amount, l.disbursement_amount,
            l.recommended_period, l.comments, l.recommendation_date,
            l.disburser_id, l.approver_1, l.approval_1_decision,
            l.approval_1_notes, l.approval_1_date, l.approver_2,
            l.approval_2_decision, l.approval_2_notes, l.approval_2_date,
            l.approver_3, l.approval_3_decision, l.approval_3_notes,
            l.approval_3_date, l.collateral_id, l.updated_at,
            l.interest_rate, l.savings_account_id,
            l.self_guaranteed_amount, l.total_guaranteed_amount,
            l.guarantor_count
        FROM loans l
        WHERE l.member_id = ?
        ORDER BY l.application_date DESC
    ");
    $stmt->execute([$member_id]);
    $loans = $stmt->fetchAll(PDO::FETCH_ASSOC);

    // Enhance each loan with additional information and charges
    foreach ($loans as &$loan) {
        // Format dates
        $loan['application_date_formatted'] = date('M j, Y', strtotime($loan['application_date']));
        $loan['application_date_full'] = date('M j, Y H:i', strtotime($loan['application_date']));
        
        // Add formatted status
        $loan['status_formatted'] = formatLoanStatus($loan['status']);
        
        // Add loan purpose name
        $loan['loan_purpose_name'] = getLoanPurposeName($pdo, $loan['loan_purpose_id']);
        
        // Add loan account type name
        $loan['loan_type_name'] = getLoanAccountTypeName($pdo, $loan['account_type_id']);
        
        // Add savings account details if available
        if ($loan['savings_account_id']) {
            $savingsAccount = getSavingsAccountDetails($pdo, $loan['savings_account_id']);
            if ($savingsAccount) {
                $loan['savings_account_number'] = $savingsAccount['account_number'];
                $loan['savings_account_name'] = $savingsAccount['account_name'];
                $loan['savings_account_type'] = $savingsAccount['type'];
            }
        }
        
        // Get detailed charges from loan_charges table for THIS SPECIFIC LOAN
        $chargesInfo = $chargesManager->getLoanChargesDetails($loan['id']);
        $loan['charges'] = $chargesInfo['charges']; // Individual charges array
        $loan['total_charges'] = $chargesInfo['total_charges']; // Total sum
        $loan['charges_count'] = $chargesInfo['charges_count'];
        $loan['total_with_charges'] = $loan['loan_amount'] + $loan['total_charges'];
        $loan['loan_amount_formatted'] = 'Ksh ' . number_format($loan['loan_amount'], 2);
        $loan['total_charges_formatted'] = $chargesInfo['formatted_total'];
        $loan['total_with_charges_formatted'] = 'Ksh ' . number_format($loan['total_with_charges'], 2);
        
        // Fetch collaterals
        $stmt2 = $pdo->prepare("
            SELECT 
                id, loan_id, collateral_description, collateral_value,
                status, created_at, updated_at, collateral_number,
                collateral_file, collateral_type
            FROM loan_collaterals
            WHERE loan_id = ?
        ");
        $stmt2->execute([$loan['id']]);
        $loan['collaterals'] = $stmt2->fetchAll(PDO::FETCH_ASSOC);
        
        // Format collateral status
        foreach ($loan['collaterals'] as &$collateral) {
            $collateral['status_formatted'] = formatLoanStatus($collateral['status']);
        }

        // Fetch guarantors
        $stmt3 = $pdo->prepare("
            SELECT 
                lg.id, lg.loan_id, lg.guarantor_member_id, 
                lg.guarantee_amount, lg.savings_account_id,
                lg.created_at, lg.status,
                m.member_number, m.first_name, m.last_name,
                m.id_number, m.phone_number
            FROM loan_guarantors lg
            JOIN members m ON lg.guarantor_member_id = m.id
            WHERE lg.loan_id = ?
        ");
        $stmt3->execute([$loan['id']]);
        $loan['guarantors'] = $stmt3->fetchAll(PDO::FETCH_ASSOC);
        
        // Format guarantor status
        foreach ($loan['guarantors'] as &$guarantor) {
            $guarantor['status_formatted'] = formatLoanStatus($guarantor['status']);
            $guarantor['full_name'] = $guarantor['first_name'] . ' ' . $guarantor['last_name'];
        }
    }
    
    return $loans;
}

// Helper function to log actions
function apiLog($message, $level = 'INFO') {
    $logEntry = "[" . date('Y-m-d H:i:s') . "] [$level] " . $message;
    error_log($logEntry);
    
    // Also log to file if needed
    $logFile = __DIR__ . '/logs/loans-api_' . date('Y-m-d') . '.log';
    if (!file_exists(dirname($logFile))) {
        mkdir(dirname($logFile), 0755, true);
    }
    file_put_contents($logFile, $logEntry . PHP_EOL, FILE_APPEND);
}

// ============================================
// REQUEST HANDLERS
// ============================================

// Handle GET requests
function handleGetRequest($pdo, $member_id, $action) {
    $chargesManager = new LoanChargesManager($pdo);
    
    try {
        switch ($action) {
            case 'loan_details':
                $loanId = $_GET['loan_id'] ?? null;
                if (!$loanId) {
                    http_response_code(400);
                    echo json_encode([
                        'success' => false,
                        'error' => 'Loan ID is required'
                    ]);
                    return;
                }
                
                $loan = getLoanSummary($pdo, $loanId);
                
                if (!$loan || $loan['member_id'] != $member_id) {
                    http_response_code(404);
                    echo json_encode([
                        'success' => false,
                        'error' => 'Loan not found'
                    ]);
                    return;
                }
                
                // Format dates
                $loan['application_date_formatted'] = date('M j, Y', strtotime($loan['application_date']));
                $loan['application_date_full'] = date('M j, Y H:i', strtotime($loan['application_date']));
                if ($loan['updated_at']) {
                    $loan['updated_at_formatted'] = date('M j, Y H:i', strtotime($loan['updated_at']));
                }
                
                // Add formatted status
                $loan['status_formatted'] = formatLoanStatus($loan['status']);
                
                // Add member details
                $loan['member_name'] = $loan['first_name'] . ' ' . $loan['last_name'];
                $loan['member_number'] = $loan['member_number'];
                
                echo json_encode([
                    'success' => true,
                    'data' => $loan
                ], JSON_NUMERIC_CHECK);
                break;
                
            case 'active_loans':
                // Get only active loans (approved, disbursed, active)
                $stmt = $pdo->prepare("
                    SELECT 
                        l.id, l.loan_number, l.loan_amount, l.loan_period,
                        l.status, l.application_date, l.disbursement_date,
                        l.interest_rate, l.self_guaranteed_amount,
                        l.total_guaranteed_amount, l.account_type_id,
                        at.account_name as loan_type,
                        lp.purpose_name,
                        COUNT(lg.id) as guarantor_count
                    FROM loans l
                    LEFT JOIN account_types at ON l.account_type_id = at.id
                    LEFT JOIN loan_purposes lp ON l.loan_purpose_id = lp.id
                    LEFT JOIN loan_guarantors lg ON l.id = lg.loan_id
                    WHERE l.member_id = ? 
                    AND l.status IN ('approved', 'disbursed', 'active')
                    GROUP BY l.id
                    ORDER BY l.application_date DESC
                ");
                $stmt->execute([$member_id]);
                $loans = $stmt->fetchAll(PDO::FETCH_ASSOC);
                
                // Add formatted data and detailed charges
                foreach ($loans as &$loan) {
                    $loan['application_date_formatted'] = date('M j, Y', strtotime($loan['application_date']));
                    $loan['status_formatted'] = formatLoanStatus($loan['status']);
                    
                    // Get detailed charges from loan_charges table for THIS LOAN
                    $chargesInfo = $chargesManager->getLoanChargesDetails($loan['id']);
                    $loan['charges'] = $chargesInfo['charges']; // Individual charges
                    $loan['total_charges'] = $chargesInfo['total_charges'];
                    $loan['charges_count'] = $chargesInfo['charges_count'];
                    $loan['total_with_charges'] = $loan['loan_amount'] + $loan['total_charges'];
                    $loan['loan_amount_formatted'] = 'Ksh ' . number_format($loan['loan_amount'], 2);
                    $loan['total_charges_formatted'] = $chargesInfo['formatted_total'];
                    $loan['total_with_charges_formatted'] = 'Ksh ' . number_format($loan['total_with_charges'], 2);
                }
                
                echo json_encode([
                    'success' => true,
                    'data' => $loans,
                    'count' => count($loans)
                ], JSON_NUMERIC_CHECK);
                break;
                
            case 'pending_loans':
                // Get pending loans
                $stmt = $pdo->prepare("
                    SELECT 
                        l.id, l.loan_number, l.loan_amount, l.loan_period,
                        l.status, l.application_date, l.self_guaranteed_amount,
                        l.total_guaranteed_amount, l.account_type_id,
                        at.account_name as loan_type,
                        lp.purpose_name,
                        COUNT(lg.id) as guarantor_count
                    FROM loans l
                    LEFT JOIN account_types at ON l.account_type_id = at.id
                    LEFT JOIN loan_purposes lp ON l.loan_purpose_id = lp.id
                    LEFT JOIN loan_guarantors lg ON l.id = lg.loan_id
                    WHERE l.member_id = ? 
                    AND l.status IN ('pending', 'pending_approval')
                    GROUP BY l.id
                    ORDER BY l.application_date DESC
                ");
                $stmt->execute([$member_id]);
                $loans = $stmt->fetchAll(PDO::FETCH_ASSOC);
                
                // Add formatted data and detailed charges
                foreach ($loans as &$loan) {
                    $loan['application_date_formatted'] = date('M j, Y', strtotime($loan['application_date']));
                    $loan['status_formatted'] = formatLoanStatus($loan['status']);
                    
                    // Get detailed charges from loan_charges table for THIS LOAN
                    $chargesInfo = $chargesManager->getLoanChargesDetails($loan['id']);
                    $loan['charges'] = $chargesInfo['charges']; // Individual charges
                    $loan['total_charges'] = $chargesInfo['total_charges'];
                    $loan['charges_count'] = $chargesInfo['charges_count'];
                    $loan['total_with_charges'] = $loan['loan_amount'] + $loan['total_charges'];
                    $loan['loan_amount_formatted'] = 'Ksh ' . number_format($loan['loan_amount'], 2);
                    $loan['total_charges_formatted'] = $chargesInfo['formatted_total'];
                    $loan['total_with_charges_formatted'] = 'Ksh ' . number_format($loan['total_with_charges'], 2);
                }
                
                echo json_encode([
                    'success' => true,
                    'data' => $loans,
                    'count' => count($loans)
                ], JSON_NUMERIC_CHECK);
                break;
                
            case 'loan_charges':
                $loanId = $_GET['loan_id'] ?? null;
                if (!$loanId) {
                    http_response_code(400);
                    echo json_encode([
                        'success' => false,
                        'error' => 'Loan ID is required'
                    ]);
                    return;
                }
                
                // Verify loan belongs to member
                $stmt = $pdo->prepare("
                    SELECT id, member_id 
                    FROM loans 
                    WHERE id = ?
                ");
                $stmt->execute([$loanId]);
                $loan = $stmt->fetch(PDO::FETCH_ASSOC);
                
                if (!$loan || $loan['member_id'] != $member_id) {
                    http_response_code(404);
                    echo json_encode([
                        'success' => false,
                        'error' => 'Loan not found'
                    ]);
                    return;
                }
                
                // Get detailed charges from loan_charges table
                $chargesInfo = $chargesManager->getLoanChargesDetails($loanId);
                
                echo json_encode([
                    'success' => true,
                    'data' => $chargesInfo
                ], JSON_NUMERIC_CHECK);
                break;
                
            case 'calculate_charges':
                // Calculate charges for a loan type and amount
                $loanTypeId = $_GET['loan_type_id'] ?? null;
                $loanAmount = $_GET['loan_amount'] ?? null;
                
                if (!$loanTypeId || !$loanAmount) {
                    http_response_code(400);
                    echo json_encode([
                        'success' => false,
                        'error' => 'Loan type ID and amount are required'
                    ]);
                    return;
                }
                
                // Get charges from account_charges table
                $charges = $chargesManager->getLoanCharges($loanTypeId);
                
                // Calculate charges
                $chargesInfo = $chargesManager->calculateCharges((float)$loanAmount, $charges);
                
                // Get loan type name for context
                $stmt = $pdo->prepare("SELECT account_name FROM account_types WHERE id = ?");
                $stmt->execute([$loanTypeId]);
                $loanType = $stmt->fetch(PDO::FETCH_ASSOC);
                
                // Format individual charges for display
                $formattedCharges = [];
                foreach ($chargesInfo['charges'] as $charge) {
                    $formattedCharges[] = [
                        'charge_id' => $charge['charge_id'],
                        'charge_type' => $charge['charge_type'],
                        'charge_amount' => $charge['charge_amount'],
                        'formatted_amount' => 'Ksh ' . number_format($charge['charge_amount'], 2),
                        'value_type' => $charge['value_type'],
                        'charge_value' => $charge['charge_value'],
                        'description' => $charge['description'],
                        'calculation' => $charge['value_type'] === 'percentage' 
                            ? $charge['charge_value'] . '% of loan amount' 
                            : 'Fixed amount'
                    ];
                }
                
                echo json_encode([
                    'success' => true,
                    'data' => [
                        'loan_type_id' => $loanTypeId,
                        'loan_type_name' => $loanType['account_name'] ?? 'Unknown',
                        'loan_amount' => (float)$loanAmount,
                        'loan_amount_formatted' => 'Ksh ' . number_format($loanAmount, 2),
                        'total_charges' => $chargesInfo['total_charges'],
                        'total_charges_formatted' => 'Ksh ' . number_format($chargesInfo['total_charges'], 2),
                        'total_with_charges' => $chargesInfo['total_loan_amount'],
                        'total_with_charges_formatted' => 'Ksh ' . number_format($chargesInfo['total_loan_amount'], 2),
                        'charges' => $formattedCharges,
                        'charges_count' => count($formattedCharges)
                    ]
                ], JSON_NUMERIC_CHECK);
                break;
                
            case 'loan_statistics':
                // Get loan statistics
                $stmt = $pdo->prepare("
                    SELECT 
                        COUNT(*) as total_loans,
                        SUM(CASE WHEN status IN ('approved', 'disbursed', 'active') THEN 1 ELSE 0 END) as active_loans,
                        SUM(CASE WHEN status IN ('pending', 'pending_approval') THEN 1 ELSE 0 END) as pending_loans,
                        SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed_loans,
                        SUM(CASE WHEN status = 'rejected' THEN 1 ELSE 0 END) as rejected_loans,
                        SUM(CASE WHEN status IN ('approved', 'disbursed', 'active', 'completed') THEN loan_amount ELSE 0 END) as total_borrowed,
                        SUM(CASE WHEN status IN ('approved', 'disbursed', 'active') THEN loan_amount ELSE 0 END) as active_balance,
                        AVG(CASE WHEN status IN ('approved', 'disbursed', 'active', 'completed') THEN loan_amount ELSE NULL END) as avg_loan_amount
                    FROM loans 
                    WHERE member_id = ?
                ");
                $stmt->execute([$member_id]);
                $stats = $stmt->fetch(PDO::FETCH_ASSOC);
                
                // Calculate total charges from loan_charges table
                $stmt = $pdo->prepare("
                    SELECT SUM(lc.charge_amount) as total_charges_paid
                    FROM loans l
                    JOIN loan_charges lc ON l.id = lc.loan_id
                    WHERE l.member_id = ? 
                    AND l.status IN ('approved', 'disbursed', 'active', 'completed')
                ");
                $stmt->execute([$member_id]);
                $chargesStats = $stmt->fetch(PDO::FETCH_ASSOC);
                $stats['total_charges_paid'] = $chargesStats['total_charges_paid'] ?? 0;
                $stats['total_charges_paid_formatted'] = 'Ksh ' . number_format($stats['total_charges_paid'], 2);
                
                echo json_encode([
                    'success' => true,
                    'data' => $stats
                ], JSON_NUMERIC_CHECK);
                break;
                
            case 'repayment_schedule':
                $loanId = $_GET['loan_id'] ?? null;
                if (!$loanId) {
                    http_response_code(400);
                    echo json_encode([
                        'success' => false,
                        'error' => 'Loan ID is required'
                    ]);
                    return;
                }
                
                // Verify loan belongs to member
                $stmt = $pdo->prepare("
                    SELECT id, loan_amount, loan_period, interest_rate
                    FROM loans 
                    WHERE id = ? AND member_id = ?
                ");
                $stmt->execute([$loanId, $member_id]);
                $loan = $stmt->fetch(PDO::FETCH_ASSOC);
                
                if (!$loan) {
                    http_response_code(404);
                    echo json_encode([
                        'success' => false,
                        'error' => 'Loan not found'
                    ]);
                    return;
                }
                
                // Get total charges from loan_charges table
                $totalCharges = $chargesManager->getTotalChargesForLoan($loanId);
                
                // Calculate repayment schedule
                $loanAmount = (float)$loan['loan_amount'];
                $interestRate = (float)$loan['interest_rate'];
                $loanPeriod = (int)$loan['loan_period'];
                
                // Simple interest calculation
                $totalInterest = ($loanAmount * $interestRate * $loanPeriod) / (12 * 100);
                $totalPayable = $loanAmount + $totalInterest + $totalCharges;
                $monthlyPayment = $totalPayable / $loanPeriod;
                
                // Generate schedule
                $schedule = [];
                $remainingBalance = $totalPayable;
                $currentDate = date('Y-m-d'); // Start from today
                
                for ($i = 1; $i <= $loanPeriod; $i++) {
                    $dueDate = date('Y-m-d', strtotime("+$i months", strtotime($currentDate)));
                    $principalPortion = $loanAmount / $loanPeriod;
                    $interestPortion = $totalInterest / $loanPeriod;
                    $chargesPortion = $totalCharges / $loanPeriod;
                    
                    $schedule[] = [
                        'installment_number' => $i,
                        'due_date' => $dueDate,
                        'due_date_formatted' => date('M j, Y', strtotime($dueDate)),
                        'amount_due' => round($monthlyPayment, 2),
                        'amount_due_formatted' => 'Ksh ' . number_format(round($monthlyPayment, 2), 2),
                        'principal' => round($principalPortion, 2),
                        'interest' => round($interestPortion, 2),
                        'charges' => round($chargesPortion, 2),
                        'remaining_balance' => round($remainingBalance - $monthlyPayment, 2),
                        'status' => 'pending'
                    ];
                    
                    $remainingBalance -= $monthlyPayment;
                }
                
                echo json_encode([
                    'success' => true,
                    'data' => [
                        'loan_amount' => $loanAmount,
                        'loan_amount_formatted' => 'Ksh ' . number_format($loanAmount, 2),
                        'interest_rate' => $interestRate,
                        'loan_period' => $loanPeriod,
                        'total_charges' => $totalCharges,
                        'total_charges_formatted' => 'Ksh ' . number_format($totalCharges, 2),
                        'total_interest' => round($totalInterest, 2),
                        'total_interest_formatted' => 'Ksh ' . number_format(round($totalInterest, 2), 2),
                        'total_payable' => round($totalPayable, 2),
                        'total_payable_formatted' => 'Ksh ' . number_format(round($totalPayable, 2), 2),
                        'monthly_payment' => round($monthlyPayment, 2),
                        'monthly_payment_formatted' => 'Ksh ' . number_format(round($monthlyPayment, 2), 2),
                        'schedule' => $schedule
                    ]
                ], JSON_NUMERIC_CHECK);
                break;
                
            default:
                // Get all loans with full details including individual charges
                $loans = getLoansWithCharges($pdo, $member_id);
                
                echo json_encode([
                    'success' => true,
                    'data' => $loans,
                    'count' => count($loans)
                ], JSON_NUMERIC_CHECK);
                break;
        }
    } catch (PDOException $e) {
        apiLog("GET request error: " . $e->getMessage(), 'ERROR');
        http_response_code(500);
        echo json_encode([
            'success' => false,
            'error' => 'Failed to fetch loan data',
            'message' => ENVIRONMENT === 'development' ? $e->getMessage() : null
        ]);
    } catch (Exception $e) {
        apiLog("GET request error: " . $e->getMessage(), 'ERROR');
        http_response_code(500);
        echo json_encode([
            'success' => false,
            'error' => 'Failed to fetch loan data',
            'message' => ENVIRONMENT === 'development' ? $e->getMessage() : null
        ]);
    }
}

// Handle POST requests
function handlePostRequest($pdo, $member_id, $action) {
    $input = json_decode(file_get_contents('php://input'), true);
    
    if (json_last_error() !== JSON_ERROR_NONE) {
        http_response_code(400);
        echo json_encode([
            'success' => false,
            'error' => 'Invalid JSON input',
            'json_error' => json_last_error_msg()
        ]);
        return;
    }
    
    try {
        $pdo->beginTransaction();
        $chargesManager = new LoanChargesManager($pdo);
        
        switch ($action) {
            case 'cancel_application':
                $loanId = $input['loan_id'] ?? null;
                if (!$loanId) {
                    http_response_code(400);
                    echo json_encode([
                        'success' => false,
                        'error' => 'Loan ID is required'
                    ]);
                    $pdo->rollBack();
                    return;
                }
                
                // Verify loan belongs to member and is in cancellable state
                $stmt = $pdo->prepare("
                    SELECT id, status 
                    FROM loans 
                    WHERE id = ? AND member_id = ?
                ");
                $stmt->execute([$loanId, $member_id]);
                $loan = $stmt->fetch(PDO::FETCH_ASSOC);
                
                if (!$loan) {
                    http_response_code(404);
                    echo json_encode([
                        'success' => false,
                        'error' => 'Loan not found'
                    ]);
                    $pdo->rollBack();
                    return;
                }
                
                $cancellableStatuses = ['pending', 'pending_approval'];
                if (!in_array($loan['status'], $cancellableStatuses)) {
                    http_response_code(400);
                    echo json_encode([
                        'success' => false,
                        'error' => "Loan cannot be cancelled in current status: {$loan['status']}"
                    ]);
                    $pdo->rollBack();
                    return;
                }
                
                // Update loan status
                $stmt = $pdo->prepare("
                    UPDATE loans 
                    SET status = 'cancelled', updated_at = NOW()
                    WHERE id = ? AND member_id = ?
                ");
                $stmt->execute([$loanId, $member_id]);
                
                // Clear any session data for this loan
                if (isset($_SESSION['loan_application']) && $_SESSION['loan_application']['loan_id'] == $loanId) {
                    unset($_SESSION['loan_application'], $_SESSION['temp_guarantors']);
                }
                
                $pdo->commit();
                apiLog("Loan application cancelled: " . $loanId . " by member: " . $member_id);
                
                echo json_encode([
                    'success' => true,
                    'message' => 'Loan application cancelled successfully'
                ]);
                break;
                
            case 'request_disbursement':
                $loanId = $input['loan_id'] ?? null;
                if (!$loanId) {
                    http_response_code(400);
                    echo json_encode([
                        'success' => false,
                        'error' => 'Loan ID is required'
                    ]);
                    $pdo->rollBack();
                    return;
                }
                
                // Verify loan belongs to member and is approved
                $stmt = $pdo->prepare("
                    SELECT id, status 
                    FROM loans 
                    WHERE id = ? AND member_id = ? AND status = 'approved'
                ");
                $stmt->execute([$loanId, $member_id]);
                $loan = $stmt->fetch(PDO::FETCH_ASSOC);
                
                if (!$loan) {
                    http_response_code(404);
                    echo json_encode([
                        'success' => false,
                        'error' => 'Loan not found or not approved'
                    ]);
                    $pdo->rollBack();
                    return;
                }
                
                // Check if all guarantors have approved
                $stmt = $pdo->prepare("
                    SELECT COUNT(*) as count 
                    FROM loan_guarantors 
                    WHERE loan_id = ? AND status != 'approved'
                ");
                $stmt->execute([$loanId]);
                $pendingGuarantors = $stmt->fetch(PDO::FETCH_ASSOC);
                
                if ($pendingGuarantors['count'] > 0) {
                    http_response_code(400);
                    echo json_encode([
                        'success' => false,
                        'error' => 'All guarantors must approve before requesting disbursement'
                    ]);
                    $pdo->rollBack();
                    return;
                }
                
                // For now, just log the request
                apiLog("Disbursement requested for loan: " . $loanId . " by member: " . $member_id);
                $pdo->commit();
                
                echo json_encode([
                    'success' => true,
                    'message' => 'Disbursement request submitted. You will be notified once processed.'
                ]);
                break;
                
            default:
                // Create new loan application
                $required = ['loan_amount', 'loan_period', 'loan_purpose_id', 'account_type_id', 'savings_account_id'];
                foreach ($required as $field) {
                    if (!isset($input[$field]) || empty($input[$field])) {
                        http_response_code(400);
                        echo json_encode([
                            'success' => false,
                            'error' => "Missing required field: $field"
                        ]);
                        $pdo->rollBack();
                        return;
                    }
                }
                
                // Generate loan number
                $loan_number = 'LN' . date('Ymd') . str_pad(rand(0, 9999), 4, '0', STR_PAD_LEFT);
                
                // Get charges for the loan type from account_charges table
                $charges = $chargesManager->getLoanCharges($input['account_type_id']);
                $chargesInfo = $chargesManager->calculateCharges((float)$input['loan_amount'], $charges);
                
                // Get interest rate from loan type
                $stmt = $pdo->prepare("SELECT interest_rate FROM account_types WHERE id = ?");
                $stmt->execute([$input['account_type_id']]);
                $loanType = $stmt->fetch(PDO::FETCH_ASSOC);
                $interestRate = $loanType['interest_rate'] ?? 12.0;
                
                // Insert loan application (NO total_charges field)
                $stmt = $pdo->prepare("
                    INSERT INTO loans (
                        member_id, loan_amount, loan_period, loan_purpose_id,
                        loan_number, status, application_date,
                        account_type_id, savings_account_id,
                        interest_rate, 
                        self_guaranteed_amount, total_guaranteed_amount
                    ) VALUES (?, ?, ?, ?, ?, 'pending', NOW(), ?, ?, ?, 0, 0)
                ");
                
                $stmt->execute([
                    $member_id,
                    $input['loan_amount'],
                    $input['loan_period'],
                    $input['loan_purpose_id'],
                    $loan_number,
                    $input['account_type_id'],
                    $input['savings_account_id'],
                    $interestRate
                ]);
                
                $loan_id = $pdo->lastInsertId();
                
                // Save charges to loan_charges table (NOT in loans table)
                $chargesManager->saveLoanCharges($loan_id, $chargesInfo['charges']);
                
                $pdo->commit();
                
                // Format individual charges for response
                $formattedCharges = [];
                foreach ($chargesInfo['charges'] as $charge) {
                    $formattedCharges[] = [
                        'charge_id' => $charge['charge_id'],
                        'charge_type' => $charge['charge_type'],
                        'charge_amount' => $charge['charge_amount'],
                        'formatted_amount' => 'Ksh ' . number_format($charge['charge_amount'], 2),
                        'value_type' => $charge['value_type'],
                        'charge_value' => $charge['charge_value'],
                        'description' => $charge['description'],
                        'calculation' => $charge['value_type'] === 'percentage' 
                            ? $charge['charge_value'] . '% of loan amount' 
                            : 'Fixed amount'
                    ];
                }
                
                echo json_encode([
                    'success' => true,
                    'message' => 'Loan application submitted successfully',
                    'loan_id' => $loan_id,
                    'loan_number' => $loan_number,
                    'charges_info' => [
                        'total_charges' => $chargesInfo['total_charges'],
                        'total_charges_formatted' => 'Ksh ' . number_format($chargesInfo['total_charges'], 2),
                        'total_with_charges' => $chargesInfo['total_loan_amount'],
                        'total_with_charges_formatted' => 'Ksh ' . number_format($chargesInfo['total_loan_amount'], 2),
                        'charges_breakdown' => $formattedCharges,
                        'charges_count' => count($formattedCharges)
                    ]
                ], JSON_NUMERIC_CHECK);
                break;
        }
    } catch (PDOException $e) {
        $pdo->rollBack();
        apiLog("POST request error: " . $e->getMessage(), 'ERROR');
        http_response_code(500);
        echo json_encode([
            'success' => false,
            'error' => 'Database error: ' . (ENVIRONMENT === 'development' ? $e->getMessage() : 'Failed to process request')
        ]);
    } catch (Exception $e) {
        $pdo->rollBack();
        apiLog("POST request error: " . $e->getMessage(), 'ERROR');
        http_response_code(500);
        echo json_encode([
            'success' => false,
            'error' => 'Failed to process request',
            'message' => ENVIRONMENT === 'development' ? $e->getMessage() : null
        ]);
    }
}

// Handle DELETE requests
function handleDeleteRequest($pdo, $member_id, $action) {
    try {
        $pdo->beginTransaction();
        
        switch ($action) {
            case 'remove_guarantor':
                $loanId = $_GET['loan_id'] ?? null;
                $guarantorId = $_GET['guarantor_id'] ?? null;
                
                if (!$loanId || !$guarantorId) {
                    http_response_code(400);
                    echo json_encode([
                        'success' => false,
                        'error' => 'Loan ID and Guarantor ID are required'
                    ]);
                    $pdo->rollBack();
                    return;
                }
                
                // Verify loan belongs to member and is in pending state
                $stmt = $pdo->prepare("
                    SELECT id, status 
                    FROM loans 
                    WHERE id = ? AND member_id = ? AND status = 'pending'
                ");
                $stmt->execute([$loanId, $member_id]);
                $loan = $stmt->fetch(PDO::FETCH_ASSOC);
                
                if (!$loan) {
                    http_response_code(404);
                    echo json_encode([
                        'success' => false,
                        'error' => 'Loan not found or cannot be modified'
                    ]);
                    $pdo->rollBack();
                    return;
                }
                
                // Remove guarantor
                $stmt = $pdo->prepare("
                    DELETE FROM loan_guarantors 
                    WHERE loan_id = ? AND guarantor_member_id = ?
                ");
                $stmt->execute([$loanId, $guarantorId]);
                
                // Update guarantor count
                $stmt = $pdo->prepare("
                    SELECT COUNT(*) as count 
                    FROM loan_guarantors 
                    WHERE loan_id = ?
                ");
                $stmt->execute([$loanId]);
                $guarantorCount = $stmt->fetch(PDO::FETCH_ASSOC);
                
                $stmt = $pdo->prepare("
                    UPDATE loans 
                    SET guarantor_count = ?, updated_at = NOW()
                    WHERE id = ?
                ");
                $stmt->execute([$guarantorCount['count'] ?? 0, $loanId]);
                
                $pdo->commit();
                apiLog("Guarantor removed: " . $guarantorId . " from loan: " . $loanId);
                
                echo json_encode([
                    'success' => true,
                    'message' => 'Guarantor removed successfully'
                ]);
                break;
                
            default:
                $pdo->rollBack();
                http_response_code(400);
                echo json_encode([
                    'success' => false,
                    'error' => 'Invalid action specified'
                ]);
                break;
        }
    } catch (PDOException $e) {
        $pdo->rollBack();
        apiLog("DELETE request error: " . $e->getMessage(), 'ERROR');
        http_response_code(500);
        echo json_encode([
            'success' => false,
            'error' => 'Failed to process request',
            'message' => ENVIRONMENT === 'development' ? $e->getMessage() : null
        ]);
    } catch (Exception $e) {
        $pdo->rollBack();
        apiLog("DELETE request error: " . $e->getMessage(), 'ERROR');
        http_response_code(500);
        echo json_encode([
            'success' => false,
            'error' => 'Failed to process request',
            'message' => ENVIRONMENT === 'development' ? $e->getMessage() : null
        ]);
    }
}

// ============================================
// MAIN EXECUTION
// ============================================

try {
    apiLog("Request received: " . $method . " " . $_SERVER['REQUEST_URI'] . " Action: " . ($action ?? 'none'));
    
    switch ($method) {
        case 'GET':
            handleGetRequest($pdo, $member_id, $action);
            break;
            
        case 'POST':
            handlePostRequest($pdo, $member_id, $action);
            break;
            
        case 'DELETE':
            handleDeleteRequest($pdo, $member_id, $action);
            break;
            
        case 'PUT':
            http_response_code(501);
            echo json_encode([
                'success' => false,
                'error' => 'PUT method not implemented for this endpoint'
            ]);
            break;
            
        default:
            http_response_code(405);
            echo json_encode([
                'success' => false,
                'error' => 'Method not allowed',
                'allowed_methods' => ['GET', 'POST', 'DELETE']
            ]);
            break;
    }
} catch (PDOException $e) {
    apiLog("Database connection error: " . $e->getMessage(), 'ERROR');
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'error' => 'Database connection failed'
    ]);
} catch (Exception $e) {
    apiLog("Top-level exception: " . $e->getMessage(), 'ERROR');
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'error' => 'Internal server error',
        'message' => ENVIRONMENT === 'development' ? $e->getMessage() : 'Something went wrong'
    ]);
}
?>