<?php
/**
 * Process order from public store page
 * Creates pending orders with 4-letter unique reference for manual payment confirmation
 */

session_start();
require_once 'config.php';
require_once 'config_paystack.php';
require_once 'app/classes/StoreManager.php';
require_once 'app/classes/StorePricingManager.php';
require_once 'app/classes/StoreCustomerPricingManager.php';
require_once 'app/classes/ExternalAPIPricingManager.php';

use App\classes\ExternalAPIPricingManager;

header('Content-Type: application/json');

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    echo json_encode(['success' => false, 'message' => 'Method not allowed']);
    exit;
}

$storeId = intval($_POST['store_id'] ?? 0);
$network = $_POST['network'] ?? '';
$package = $_POST['package'] ?? '';
$phone = $_POST['phone'] ?? '';

// Validation
if ($storeId <= 0) {
    echo json_encode(['success' => false, 'message' => 'Invalid store']);
    exit;
}

if ($network !== 'mtn') {
    echo json_encode(['success' => false, 'message' => 'Invalid network. Only MTN is supported.']);
    exit;
}

if (empty($package)) {
    echo json_encode(['success' => false, 'message' => 'Please select a package']);
    exit;
}

// Validate phone number - must be exactly 10 digits starting with 0
$cleanPhone = preg_replace('/\D/', '', $phone);
if (strlen($cleanPhone) !== 10 || substr($cleanPhone, 0, 1) !== '0') {
    echo json_encode(['success' => false, 'message' => 'Invalid phone number. Must be exactly 10 digits starting with 0 (e.g., 0247965501)']);
    exit;
}
$phone = $cleanPhone;

// Verify store exists and is active
$storeManager = new StoreManager($conn);
$store = $storeManager->getStoreById($storeId);

// Debug: Log store data to check if momo_name exists
error_log("Store data: " . json_encode(['phone' => $store['phone'] ?? 'N/A', 'momo_name' => $store['momo_name'] ?? 'N/A']));

if (!$store || $store['status'] !== 'active') {
    echo json_encode(['success' => false, 'message' => 'Store is not available']);
    exit;
}

// Store the store slug in session when order is created
// This ensures customers can always return to the correct store
if (!empty($store['store_slug'])) {
    $_SESSION['last_store_slug'] = $store['store_slug'];
}

// Calculate price using CUSTOMER pricing (not agent pricing)
// Regular customers use package-specific pricing, not range-based pricing
$customerPricingManager = new StoreCustomerPricingManager($conn);
$priceInfo = $customerPricingManager->getPriceForPackage($storeId, $package, $network);

if ($priceInfo['price'] === null || $priceInfo['price'] <= 0) {
    echo json_encode(['success' => false, 'message' => 'Price not available for this package. Please contact the store owner.']);
    exit;
}

$amount = $priceInfo['price'];
$ownerId = $store['owner_id'];

/**
 * Generate a unique 4-letter order reference
 */
function generateOrderReference($conn) {
    $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $maxAttempts = 100;
    $attempts = 0;
    
    do {
        $reference = '';
        for ($i = 0; $i < 4; $i++) {
            $reference .= $characters[rand(0, strlen($characters) - 1)];
        }
        
        // Check if reference already exists
        $checkStmt = $conn->prepare("SELECT id FROM orders WHERE order_reference = ?");
        $checkStmt->bind_param("s", $reference);
        $checkStmt->execute();
        $result = $checkStmt->get_result();
        $exists = $result->num_rows > 0;
        $checkStmt->close();
        
        $attempts++;
        
        if (!$exists) {
            return $reference;
        }
    } while ($attempts < $maxAttempts);
    
    // Fallback: add numbers if all letters are taken
    $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    do {
        $reference = '';
        for ($i = 0; $i < 4; $i++) {
            $reference .= $characters[rand(0, strlen($characters) - 1)];
        }
        
        $checkStmt = $conn->prepare("SELECT id FROM orders WHERE order_reference = ?");
        $checkStmt->bind_param("s", $reference);
        $checkStmt->execute();
        $result = $checkStmt->get_result();
        $exists = $result->num_rows > 0;
        $checkStmt->close();
        
        $attempts++;
        
        if (!$exists) {
            return $reference;
        }
    } while ($attempts < $maxAttempts * 2);
    
    throw new Exception("Failed to generate unique order reference");
}

// Start transaction
$conn->begin_transaction();

try {
    // Generate unique order reference
    $orderReference = generateOrderReference($conn);
    
    // Create order as PENDING (no balance deduction, no API call)
    // Check if order_reference column exists
    $checkColStmt = $conn->query("SHOW COLUMNS FROM orders LIKE 'order_reference'");
    $hasOrderReference = $checkColStmt && $checkColStmt->num_rows > 0;
    if ($checkColStmt) $checkColStmt->close();
    
    if ($hasOrderReference) {
        $stmt = $conn->prepare("
            INSERT INTO orders (order_reference, agent_id, store_id, network_type, package_size, beneficiary_number, amount, status, created_at)
            VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', NOW())
        ");
        $stmt->bind_param("siisssd", 
            $orderReference,
            $ownerId, 
            $storeId, 
            $network, 
            $package, 
            $phone, 
            $amount
        );
    } else {
        // Fallback if column doesn't exist yet
        $stmt = $conn->prepare("
            INSERT INTO orders (agent_id, store_id, network_type, package_size, beneficiary_number, amount, status, created_at)
            VALUES (?, ?, ?, ?, ?, ?, 'pending', NOW())
        ");
        $stmt->bind_param("iisssd", 
            $ownerId, 
            $storeId, 
            $network, 
            $package, 
            $phone, 
            $amount
        );
    }
    
    if (!$stmt->execute()) {
        throw new Exception("Failed to create order: " . $stmt->error);
    }
    
    $orderId = $conn->insert_id;
    $stmt->close();
    
    // Create external API order entry for MTN orders (for profit tracking)
    // Note: This is for profit tracking even though the order is pending payment
    if (strtolower($network) === 'mtn') {
        try {
            $externalPricingManager = new ExternalAPIPricingManager($conn);
            $adminPrice = $externalPricingManager->getAdminPrice($package, 'mtn');
            $externalPrice = $externalPricingManager->getExternalPrice($package, 'mtn');
            
            // Only create external API order if pricing is available
            if ($adminPrice !== null && $externalPrice !== null) {
                $profit = $adminPrice - $externalPrice;
                
                // Parse package size to GB
                $packageSizeGb = 0;
                if (preg_match('/(\d+(?:\.\d+)?)\s*GB/i', $package, $matches)) {
                    $packageSizeGb = (float)$matches[1];
                } elseif (preg_match('/(\d+(?:\.\d+)?)\s*MB/i', $package, $matches)) {
                    $packageSizeGb = round(((float)$matches[1]) / 1024, 4);
                } else {
                    $num = floatval(preg_replace('/[^0-9.]/', '', $package));
                    $packageSizeGb = $num > 0 ? $num : 0;
                }
                
                $externalOrderStmt = $conn->prepare("
                    INSERT INTO external_api_orders 
                    (agent_id, network_type, package_size, package_size_gb, beneficiary_number, 
                     admin_price, external_api_price, profit, status, created_at)
                    VALUES (?, 'mtn', ?, ?, ?, ?, ?, ?, 'pending', NOW())
                ");
                
                if ($externalOrderStmt) {
                    $externalOrderStmt->bind_param("isddsdd", $ownerId, $package, $packageSizeGb, $phone, $adminPrice, $externalPrice, $profit);
                    if ($externalOrderStmt->execute()) {
                        $externalOrderId = $conn->insert_id;
                        error_log("External API Order created: ID $externalOrderId for store order $orderId");
                    } else {
                        error_log("Failed to create external API order: " . $externalOrderStmt->error);
                    }
                    $externalOrderStmt->close();
                }
            } else {
                error_log("External API pricing not available for package: $package (MTN). Admin: " . ($adminPrice ?? 'null') . ", External: " . ($externalPrice ?? 'null'));
            }
        } catch (Exception $e) {
            error_log("Error creating external API order: " . $e->getMessage());
            // Don't fail the main order if external API order creation fails
        }
    }
    
    // Check if store has Paystack enabled
    // IMPORTANT: This check always runs to determine payment method
    $usePaystack = false;
    $paystackAuthUrl = '';
    $paystackReference = '';
    $paystackCreds = null;
    
    try {
        $paystackStmt = $conn->prepare("SELECT public_key, secret_key, is_active FROM store_paystack_credentials WHERE store_id = ? AND is_active = 1");
        if ($paystackStmt) {
            $paystackStmt->bind_param("i", $storeId);
            if ($paystackStmt->execute()) {
                $paystackResult = $paystackStmt->get_result();
                $paystackCreds = $paystackResult->fetch_assoc();
            }
            $paystackStmt->close();
        }
    } catch (Exception $e) {
        error_log("Error checking Paystack credentials: " . $e->getMessage());
        // Continue with mobile money if check fails
        $paystackCreds = null;
    }
    
    // Only use Paystack if credentials exist and are valid
    if ($paystackCreds && !empty($paystackCreds['public_key']) && !empty($paystackCreds['secret_key'])) {
        // Store has Paystack enabled - initialize payment
        $usePaystack = true;
        
        // Generate Paystack reference
        $paystackReference = 'STORE_' . $orderReference . '_' . time();
        
        // Generate a unique fabricated email for every order
        // IMPORTANT: Each payment must have a unique email to prevent Paystack from flagging
        // repeated payments from the same email address
        // Format: order{orderId}_{orderReference}_{timestamp}@gmail.com
        // Using Gmail domain format that Paystack accepts
        $customerEmail = 'order' . $orderId . '_' . strtolower($orderReference) . '_' . time() . '@gmail.com';
        
        // Update order with Paystack reference BEFORE initializing payment
        $checkPaystackCol = $conn->query("SHOW COLUMNS FROM orders LIKE 'paystack_reference'");
        $hasPaystackCol = $checkPaystackCol && $checkPaystackCol->num_rows > 0;
        if ($checkPaystackCol) $checkPaystackCol->close();
        
        if ($hasPaystackCol) {
            $updatePaystackStmt = $conn->prepare("UPDATE orders SET paystack_reference = ? WHERE id = ?");
            $updatePaystackStmt->bind_param("si", $paystackReference, $orderId);
            if (!$updatePaystackStmt->execute()) {
                throw new Exception("Failed to update order with Paystack reference: " . $updatePaystackStmt->error);
            }
            $updatePaystackStmt->close();
        }
        
        // Initialize Paystack payment using store-specific credentials
        $paystackConfig = getPaystackConfig(true, $storeId);
        $amountKobo = intval(round($amount * 100)); // Convert to pesewas
        
        // Build callback URL
        $callbackBase = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
        $callbackPath = rtrim(str_replace('\\', '/', dirname($_SERVER['PHP_SELF'])), '/');
        $callbackUrl = $callbackBase . ($callbackPath ? $callbackPath : '') . '/store_paystack_callback.php';
        
        $metadata = [
            'order_id' => $orderId,
            'order_reference' => $orderReference,
            'store_id' => $storeId,
            'package' => $package,
            'phone' => $phone
        ];
        
        $payload = [
            'email' => $customerEmail,
            'amount' => $amountKobo,
            'reference' => $paystackReference,
            'currency' => 'GHS',
            'callback_url' => $callbackUrl,
            'metadata' => $metadata
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $paystackConfig['base_url'] . '/transaction/initialize');
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $paystackConfig['secret_key'],
            'Content-Type: application/json'
        ]);
        
        // Try with SSL verification first
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        
        // If SSL fails, retry without SSL verification (for local development)
        if ($response === false) {
            $err = curl_error($ch);
            error_log('Paystack init SSL error: ' . $err);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        }
        
        if ($response === false) {
            $err = curl_error($ch);
            curl_close($ch);
            error_log('Paystack init error (final): ' . $err);
            // Fall back to mobile money
            $usePaystack = false;
        } else {
            $data = json_decode($response, true);
            curl_close($ch);
            
            if ($httpCode === 200 && ($data['status'] ?? false) === true) {
                $paystackAuthUrl = $data['data']['authorization_url'] ?? '';
                if (empty($paystackAuthUrl)) {
                    error_log('Paystack initialization succeeded but no authorization URL returned');
                    $usePaystack = false;
                } else {
                    error_log("Paystack payment initialized - Order: $orderId, Reference: $paystackReference, Store: $storeId");
                }
            } else {
                $errorMsg = $data['message'] ?? 'Unknown error';
                error_log('Paystack initialization failed: ' . $errorMsg . ' (HTTP: ' . $httpCode . ')');
                $usePaystack = false;
            }
        }
    }
    
    // Commit transaction
    $conn->commit();
    
    // Get store owner's phone number and MoMo name for payment instructions (if not using Paystack)
    $ownerPhone = '';
    $momoName = '';
    if (!$usePaystack) {
    if (!empty($store['phone'])) {
        $ownerPhone = $store['phone'];
        $momoName = $store['momo_name'] ?? '';
    } else {
        $ownerStmt = $conn->prepare("SELECT phone FROM agents WHERE id = ?");
        $ownerStmt->bind_param("i", $ownerId);
        $ownerStmt->execute();
        $ownerResult = $ownerStmt->get_result();
        $ownerData = $ownerResult->fetch_assoc();
        $ownerPhone = $ownerData['phone'] ?? '';
        $ownerStmt->close();
    }
    }
    
    if ($usePaystack && !empty($paystackAuthUrl)) {
        // Return Paystack payment URL
        echo json_encode([
            'success' => true,
            'message' => 'Order created. Redirecting to payment...',
            'order_id' => $orderId,
            'order_reference' => $orderReference,
            'amount' => number_format($amount, 2),
            'payment_method' => 'paystack',
            'paystack_auth_url' => $paystackAuthUrl,
            'package' => $package,
            'phone' => $phone
        ]);
    } else {
        // Return mobile money payment instructions
    echo json_encode([
        'success' => true,
        'message' => 'Order created successfully',
        'order_id' => $orderId,
        'order_reference' => $orderReference,
        'amount' => number_format($amount, 2),
            'payment_method' => 'mobile_money',
        'owner_phone' => $ownerPhone,
        'momo_name' => $momoName,
        'package' => $package,
        'phone' => $phone
    ]);
    }
    
} catch (Exception $e) {
    $conn->rollback();
    echo json_encode([
        'success' => false,
        'message' => 'Failed to process order: ' . $e->getMessage()
    ]);
}
?>



