<?php
/**
 * M-Pesa Callback URL Handler
 * This file receives payment notifications from Safaricom
 * Register this URL in your Daraja portal
 */

require_once '../layouts/dbconn.php';

// Get callback data from M-Pesa
$callback_json = file_get_contents('php://input');
$callback_data = json_decode($callback_json, true);

// Log raw callback for debugging
$log_file = '../logs/mpesa_callback_' . date('Y-m-d') . '.log';
file_put_contents($log_file, date('Y-m-d H:i:s') . " - " . $callback_json . "\n", FILE_APPEND);

try {
    if (!isset($callback_data['Body']['stkCallback'])) {
        throw new Exception('Invalid callback data');
    }
    
    $callback = $callback_data['Body']['stkCallback'];
    $merchant_request_id = $callback['MerchantRequestID'];
    $checkout_request_id = $callback['CheckoutRequestID'];
    $result_code = $callback['ResultCode'];
    $result_desc = $callback['ResultDesc'];
    
    // Find the transaction
    $find_sql = "SELECT transaction_id, visit_id, amount, phone_number 
                FROM mpesa_transactions 
                WHERE checkout_request_id = ?";
    $stmt = $conn->prepare($find_sql);
    $stmt->bind_param("s", $checkout_request_id);
    $stmt->execute();
    $transaction = $stmt->get_result()->fetch_assoc();
    
    if (!$transaction) {
        throw new Exception('Transaction not found');
    }
    
    $conn->begin_transaction();
    
    if ($result_code == 0) {
        // Payment successful
        $callback_metadata = $callback['CallbackMetadata']['Item'];
        
        $mpesa_receipt = '';
        $transaction_date = '';
        $phone_number = '';
        
        foreach ($callback_metadata as $item) {
            if ($item['Name'] === 'MpesaReceiptNumber') {
                $mpesa_receipt = $item['Value'];
            } elseif ($item['Name'] === 'TransactionDate') {
                $transaction_date = $item['Value'];
            } elseif ($item['Name'] === 'PhoneNumber') {
                $phone_number = $item['Value'];
            }
        }
        
        // Format transaction date
        $formatted_date = null;
        if ($transaction_date) {
            $formatted_date = date('Y-m-d H:i:s', strtotime($transaction_date));
        }
        
        // Update M-Pesa transaction
        $update_mpesa_sql = "UPDATE mpesa_transactions SET 
                            status = 'COMPLETED',
                            mpesa_receipt_number = ?,
                            transaction_date = ?,
                            result_code = ?,
                            result_description = ?,
                            callback_data = ?
                            WHERE transaction_id = ?";
        $stmt = $conn->prepare($update_mpesa_sql);
        $callback_json_str = json_encode($callback_data);
        $stmt->bind_param("sssssi", $mpesa_receipt, $formatted_date, $result_code, 
                         $result_desc, $callback_json_str, $transaction['transaction_id']);
        $stmt->execute();
        
        // Create payment record
        $payment_number = 'PAY' . date('Ymd') . str_pad(rand(1, 9999), 4, '0', STR_PAD_LEFT);
        
        // Get patient ID from visit
        $patient_sql = "SELECT patient_id FROM patient_visits WHERE visit_id = ?";
        $stmt = $conn->prepare($patient_sql);
        $stmt->bind_param("i", $transaction['visit_id']);
        $stmt->execute();
        $patient_result = $stmt->get_result()->fetch_assoc();
        $patient_id = $patient_result['patient_id'];
        
        $payment_sql = "INSERT INTO payments (payment_number, visit_id, patient_id, 
                       payment_method, payment_reference, amount, mpesa_account_number, 
                       mpesa_transaction_id, status, payment_date, received_by) 
                       VALUES (?, ?, ?, 'MOBILE_MONEY', ?, ?, ?, ?, 'COMPLETED', NOW(), 1)";
        $stmt = $conn->prepare($payment_sql);
        $stmt->bind_param("siisdsi", $payment_number, $transaction['visit_id'], $patient_id,
                         $mpesa_receipt, $transaction['amount'], $phone_number, 
                         $transaction['transaction_id']);
        $stmt->execute();
        $payment_id = $conn->insert_id();
        
        // Update visit payment info
        $update_visit_sql = "UPDATE patient_visits SET 
                            amount_paid = amount_paid + ?,
                            balance = patient_portion - (amount_paid + ?)
                            WHERE visit_id = ?";
        $stmt = $conn->prepare($update_visit_sql);
        $stmt->bind_param("ddi", $transaction['amount'], $transaction['amount'], 
                         $transaction['visit_id']);
        $stmt->execute();
        
        // Send SMS confirmation (if SMS enabled)
        $sms_enabled = getSetting($conn, 'sms_enabled');
        if ($sms_enabled == '1') {
            sendPaymentSMS($conn, $payment_id, $phone_number, $transaction['amount'], $mpesa_receipt);
        }
        
        $conn->commit();
        
    } else {
        // Payment failed
        $update_sql = "UPDATE mpesa_transactions SET 
                      status = 'FAILED',
                      result_code = ?,
                      result_description = ?,
                      callback_data = ?
                      WHERE transaction_id = ?";
        $stmt = $conn->prepare($update_sql);
        $callback_json_str = json_encode($callback_data);
        $stmt->bind_param("sssi", $result_code, $result_desc, $callback_json_str, 
                         $transaction['transaction_id']);
        $stmt->execute();
        
        $conn->commit();
    }
    
    // Send acknowledgment to Safaricom
    header('Content-Type: application/json');
    echo json_encode([
        'ResultCode' => 0,
        'ResultDesc' => 'Accepted'
    ]);
    
} catch (Exception $e) {
    if ($conn->inTransaction()) {
        $conn->rollback();
    }
    
    // Log error
    file_put_contents($log_file, date('Y-m-d H:i:s') . " - ERROR: " . $e->getMessage() . "\n", FILE_APPEND);
    
    // Send error acknowledgment
    header('Content-Type: application/json');
    echo json_encode([
        'ResultCode' => 1,
        'ResultDesc' => 'Error processing callback'
    ]);
}

function getSetting($conn, $key) {
    $sql = "SELECT setting_value FROM system_settings WHERE setting_key = ?";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("s", $key);
    $stmt->execute();
    $result = $stmt->get_result();
    $row = $result->fetch_assoc();
    return $row['setting_value'] ?? '';
}

function sendPaymentSMS($conn, $payment_id, $phone, $amount, $receipt) {
    // Get payment details
    $sql = "SELECT p.payment_number, u.first_name, u.last_name 
            FROM payments p
            INNER JOIN patient_visits pv ON p.visit_id = pv.visit_id
            INNER JOIN patients pt ON pv.patient_id = pt.patient_id
            INNER JOIN users u ON pt.user_id = u.user_id
            WHERE p.payment_id = ?";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("i", $payment_id);
    $stmt->execute();
    $result = $stmt->get_result()->fetch_assoc();
    
    if ($result) {
        $message = "Dear {$result['first_name']}, your payment of KES " . number_format($amount, 2) . 
                   " has been received. M-Pesa Ref: {$receipt}. Thank you for choosing ENT Hospital.";
        
        // Queue SMS for sending
        $sms_sql = "INSERT INTO communication_log (recipient_type, recipient_id, communication_type, 
                   message, recipient_contact, status, sent_by) 
                   VALUES ('PATIENT', ?, 'SMS', ?, ?, 'PENDING', 1)";
        $stmt = $conn->prepare($sms_sql);
        $stmt->bind_param("iss", $payment_id, $message, $phone);
        $stmt->execute();
    }
}
?>