<?php
/**
 * Stripe Payment Processing
 * Handles payment intent creation and processing
 */

// Apply secure CORS configuration
require_once 'cors_security.php';
applySecureCORS();

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

// Only allow POST requests
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['success' => false, 'error' => 'Method not allowed']);
    exit;
}

require_once 'stripe_config.php';
require_once 'db_config.php';

// First, download Stripe PHP library if not already installed
// You can install via Composer: composer require stripe/stripe-php
// Or download manually from: https://github.com/stripe/stripe-php

try {
    require_once 'vendor/autoload.php'; // If using Composer
} catch (Exception $e) {
    // Fallback: include Stripe library manually
    // require_once 'stripe-php/init.php';
    die('Stripe PHP library not found. Please install via Composer or download manually.');
}

use Stripe\Stripe;
use Stripe\PaymentIntent;
use Stripe\Checkout\Session;
use Stripe\Exception\ApiErrorException;

class StripePaymentHandler {
    private $stripe;
    private $db;
    
    public function __construct() {
        // Set Stripe API key
        Stripe::setApiKey(StripeConfig::getSecretKey());
        
        // Database connection
        $this->db = new PDO(
            "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME,
            DB_USER,
            DB_PASS,
            [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
        );
    }
    
    /**
     * Create a checkout session for the registration
     */
    public function createCheckoutSession($registrationData) {
        try {
            // Calculate total amount in cents (Stripe uses cents)
            $amountInCents = $this->calculateTotalAmount($registrationData) * 100;
            
            // Prepare line items for checkout
            $lineItems = [];
            
            // Load config for live product data
            $configResponse = file_get_contents('api.php?action=get_config');
            $config = json_decode($configResponse, true);

            // Add delegate passes
            $delegatePrice = $this->getDelegatePrice($registrationData['delegateType']);
            $lineItems[] = [
                'price_data' => [
                    'currency' => StripeConfig::getCurrency(),
                    'product_data' => [
                        'name' => 'XChange 2025 Delegate Pass (' . ucfirst($registrationData['delegateType']) . ')',
                        'description' => 'Registration: ' . $registrationData['registrationNumber'] . ' | Access to all sessions, exhibits, and networking',
                    ],
                    'unit_amount' => $delegatePrice * 100,
                ],
                'quantity' => $registrationData['delegateCount'],
            ];
            
            // Add table-top presentations if selected
            if (isset($registrationData['tables']) && !empty($registrationData['tables'])) {
                foreach ($registrationData['tables'] as $tableType) {
                    $tablePrice = $this->getTablePrice($tableType);
                    $tableName = $tableType === 'standard' ? 'Standard Table-top Presentation' : 'Double Table-top Presentation';
                    $tableDescription = $tableType === 'standard' ? '1 table, 4 chairs, up to 2 banners' : 'Double table, 8 chairs, up to 2 banners';
                    
                    $lineItems[] = [
                        'price_data' => [
                            'currency' => StripeConfig::getCurrency(),
                            'product_data' => [
                                'name' => $tableName,
                                'description' => 'Registration: ' . $registrationData['registrationNumber'] . ' | ' . $tableDescription,
                            ],
                            'unit_amount' => $tablePrice * 100,
                        ],
                        'quantity' => 1,
                    ];
                }
            }

            // Add sponsorships
            if (isset($registrationData['sponsorships']) && is_array($registrationData['sponsorships'])) {
                foreach ($registrationData['sponsorships'] as $sponsorship) {
                    $productCode = $sponsorship['type'];
                    $quantity = intval($sponsorship['count']);
                    $product = null;
                    if (isset($config['frontend']['sponsorship']['products'])) {
                        foreach ($config['frontend']['sponsorship']['products'] as $prod) {
                            if ($prod['product_code'] === $productCode) {
                                $product = $prod;
                                break;
                            }
                        }
                    }
                    if ($product && $quantity > 0) {
                        $lineItems[] = [
                            'price_data' => [
                                'currency' => StripeConfig::getCurrency(),
                                'product_data' => [
                                    'name' => $product['name'],
                                    'description' => 'Registration: ' . $registrationData['registrationNumber'] . ' | ' . ($product['description'] ?? ''),
                                ],
                                'unit_amount' => floatval($product['base_price']) * 100,
                            ],
                            'quantity' => $quantity,
                        ];
                    }
                }
            }

            // Add other sponsorships
            if (isset($registrationData['otherSponsorships']) && is_array($registrationData['otherSponsorships'])) {
                foreach ($registrationData['otherSponsorships'] as $otherSponsorship) {
                    $productCode = $otherSponsorship['type'];
                    $quantity = intval($otherSponsorship['count']);
                    $product = null;
                    if (isset($config['frontend']['otherSponsorship']['products'])) {
                        foreach ($config['frontend']['otherSponsorship']['products'] as $prod) {
                            if ($prod['product_code'] === $productCode) {
                                $product = $prod;
                                break;
                            }
                        }
                    }
                    if ($product && $quantity > 0) {
                        $lineItems[] = [
                            'price_data' => [
                                'currency' => StripeConfig::getCurrency(),
                                'product_data' => [
                                    'name' => $product['name'],
                                    'description' => 'Registration: ' . $registrationData['registrationNumber'] . ' | ' . ($product['description'] ?? ''),
                                ],
                                'unit_amount' => floatval($product['base_price']) * 100,
                            ],
                            'quantity' => $quantity,
                        ];
                    }
                }
            }
            
            // Create checkout session
            $session = Session::create([
                'payment_method_types' => ['card'],
                'line_items' => $lineItems,
                'mode' => 'payment',
                'success_url' => StripeConfig::getSuccessUrl() . '?session_id={CHECKOUT_SESSION_ID}&registration_number=' . $registrationData['registrationNumber'],
                'cancel_url' => StripeConfig::getCancelUrl() . '?registration_number=' . $registrationData['registrationNumber'],
                'metadata' => [
                    'registration_number' => $registrationData['registrationNumber'],
                    'delegate_count' => $registrationData['delegateCount'],
                    'delegate_type' => $registrationData['delegateType'],
                    'tables' => implode(',', $registrationData['tables'] ?? []),
                    'contact_email' => $registrationData['contact']['email'] ?? '',
                    'university' => $registrationData['contact']['university'] ?? ''
                ],
                'customer_email' => $registrationData['contact']['email'] ?? null,
                'billing_address_collection' => 'auto',
                'payment_intent_data' => [
                    'description' => 'XChange 2025 Registration: ' . $registrationData['registrationNumber'],
                    'statement_descriptor_suffix' => substr($registrationData['registrationNumber'], -10), // Last 10 chars for bank statement
                    'metadata' => [
                        'registration_number' => $registrationData['registrationNumber'],
                        'event' => 'XChange 2025',
                        'university' => $registrationData['contact']['university'] ?? ''
                    ]
                ],
            ]);
            
            // Store checkout session in database
            $this->storePaymentSession($registrationData['registrationNumber'], $session->id, $amountInCents);
            
            return [
                'success' => true,
                'session_id' => $session->id,
                'checkout_url' => $session->url,
                'amount' => $amountInCents / 100
            ];
            
        } catch (ApiErrorException $e) {
            error_log('Stripe API Error: ' . $e->getMessage());
            return [
                'success' => false,
                'error' => 'Payment setup failed. Please try again.',
                'details' => $e->getMessage()
            ];
        } catch (Exception $e) {
            error_log('Checkout Session Error: ' . $e->getMessage());
            return [
                'success' => false,
                'error' => 'Payment setup failed. Please try again.',
                'details' => $e->getMessage()
            ];
        }
    }
    
    /**
     * Calculate total amount based on registration data
     */
    private function calculateTotalAmount($registrationData) {
        // Get pricing and live product data from config
        $configResponse = file_get_contents('api.php?action=get_config');
        $config = json_decode($configResponse, true);
        
        if (!$config || !isset($config['pricing'])) {
            throw new Exception('Unable to load pricing configuration');
        }
        
        $pricing = $config['pricing'];
        
        // Calculate delegate cost
        $delegatePrice = $pricing[$registrationData['delegateType'] . 'Price'];
        $delegateTotal = $delegatePrice * $registrationData['delegateCount'];
        
        // Calculate table cost
        $tableTotal = 0;
        if (isset($registrationData['tables']) && !empty($registrationData['tables'])) {
            foreach ($registrationData['tables'] as $tableType) {
                if ($tableType === 'standard') {
                    $tableTotal += $pricing['standardTablePrice'];
                } elseif ($tableType === 'double') {
                    $tableTotal += $pricing['doubleTablePrice'];
                }
            }
        }

        // Calculate sponsorship cost
        $sponsorshipTotal = 0;
        if (isset($registrationData['sponsorships']) && is_array($registrationData['sponsorships'])) {
            foreach ($registrationData['sponsorships'] as $sponsorship) {
                $productCode = $sponsorship['type'];
                $quantity = intval($sponsorship['count']);
                $product = null;
                if (isset($config['frontend']['sponsorship']['products'])) {
                    foreach ($config['frontend']['sponsorship']['products'] as $prod) {
                        if ($prod['product_code'] === $productCode) {
                            $product = $prod;
                            break;
                        }
                    }
                }
                if ($product && $quantity > 0) {
                    $sponsorshipTotal += floatval($product['base_price']) * $quantity;
                }
            }
        }

        // Calculate other sponsorship cost
        $otherSponsorshipTotal = 0;
        if (isset($registrationData['otherSponsorships']) && is_array($registrationData['otherSponsorships'])) {
            foreach ($registrationData['otherSponsorships'] as $otherSponsorship) {
                $productCode = $otherSponsorship['type'];
                $quantity = intval($otherSponsorship['count']);
                $product = null;
                if (isset($config['frontend']['otherSponsorship']['products'])) {
                    foreach ($config['frontend']['otherSponsorship']['products'] as $prod) {
                        if ($prod['product_code'] === $productCode) {
                            $product = $prod;
                            break;
                        }
                    }
                }
                if ($product && $quantity > 0) {
                    $otherSponsorshipTotal += floatval($product['base_price']) * $quantity;
                }
            }
        }

        return $delegateTotal + $tableTotal + $sponsorshipTotal + $otherSponsorshipTotal;
    }
    
    /**
     * Get delegate price from config
     */
    private function getDelegatePrice($delegateType) {
        $configResponse = file_get_contents('api.php?action=get_config');
        $config = json_decode($configResponse, true);
        return $config['pricing'][$delegateType . 'Price'];
    }
    
    /**
     * Get table price from config
     */
    private function getTablePrice($tableType) {
        $configResponse = file_get_contents('api.php?action=get_config');
        $config = json_decode($configResponse, true);
        return $config['pricing'][$tableType . 'TablePrice'];
    }

    /**
     * Store payment session in database
     */
    private function storePaymentSession($registrationNumber, $sessionId, $amountInCents) {
        // Get registration_id from registration_number
        $regStmt = $this->db->prepare("SELECT id FROM registrations WHERE registration_number = ?");
        $regStmt->execute([$registrationNumber]);
        $registration = $regStmt->fetch(PDO::FETCH_ASSOC);
        $registrationId = $registration ? $registration['id'] : null;
        
        // Generate payment reference for gateway payments
        $paymentReference = 'PAY-' . $registrationNumber . '-' . date('YmdHis');
        
        $stmt = $this->db->prepare("
            INSERT INTO payment_transactions 
            (registration_id, registration_number, transaction_type, transaction_reference, 
             gateway_transaction_id, amount, currency, transaction_status, created_at) 
            VALUES (?, ?, 'gateway', ?, ?, ?, ?, 'pending', NOW())
        ");
        
        $stmt->execute([
            $registrationId,
            $registrationNumber,
            $paymentReference,
            $sessionId,
            $amountInCents / 100, // Store in dollars
            StripeConfig::getCurrency()
        ]);
    }
    
    /**
     * Confirm payment and update database
     */
    public function confirmPayment($paymentIntentId) {
        try {
            // Retrieve payment intent from Stripe
            $paymentIntent = PaymentIntent::retrieve($paymentIntentId);
            
            if ($paymentIntent->status === 'succeeded') {
                // Update payment status in database
                $stmt = $this->db->prepare("
                    UPDATE payment_transactions 
                    SET transaction_status = 'paid', 
                        transaction_reference = ?,
                        updated_at = NOW()
                    WHERE gateway_transaction_id = ?
                ");
                
                $stmt->execute([
                    $paymentIntent->charges->data[0]->balance_transaction ?? $paymentIntentId,
                    $paymentIntentId
                ]);
                
                // Update registration status
                $stmt = $this->db->prepare("
                    UPDATE registrations 
                    SET payment_status = 'paid', 
                        updated_at = NOW()
                    WHERE registration_number = ?
                ");
                
                $registrationNumber = $paymentIntent->metadata->registration_number;
                $stmt->execute([$registrationNumber]);
                
                // Auto-confirm stock status for all products in this registration
                $stockStmt = $this->db->prepare("
                    UPDATE registration_products 
                    SET stock_status = 'confirmed', 
                        confirmed_at = NOW(),
                        updated_at = NOW()
                    WHERE registration_id = (
                        SELECT id FROM registrations WHERE registration_number = ?
                    ) AND stock_status = 'reserved'
                ");
                $stockResult = $stockStmt->execute([$registrationNumber]);
                $stockRowsUpdated = $stockStmt->rowCount();
                error_log("Stripe Payment: Auto-confirmed $stockRowsUpdated product stock items for registration $registrationNumber");
                
                // Update product stock counts
                if ($stockRowsUpdated > 0) {
                    $productStmt = $this->db->prepare("
                        SELECT DISTINCT rp.product_id 
                        FROM registration_products rp
                        JOIN registrations r ON rp.registration_id = r.id
                        WHERE r.registration_number = ?
                    ");
                    $productStmt->execute([$registrationNumber]);
                    $productIds = $productStmt->fetchAll(PDO::FETCH_COLUMN);
                    
                    foreach ($productIds as $productId) {
                        $updateStockStmt = $this->db->prepare("
                            UPDATE products SET 
                                sold_stock = (
                                    SELECT COALESCE(SUM(quantity), 0) 
                                    FROM registration_products 
                                    WHERE product_id = ? AND stock_status = 'confirmed'
                                ),
                                reserved_stock = (
                                    SELECT COALESCE(SUM(quantity), 0) 
                                    FROM registration_products 
                                    WHERE product_id = ? AND stock_status = 'reserved'
                                ),
                                available_stock = GREATEST(0, total_stock - (
                                    SELECT COALESCE(SUM(quantity), 0) 
                                    FROM registration_products 
                                    WHERE product_id = ? AND stock_status IN ('confirmed', 'reserved')
                                ))
                            WHERE id = ?
                        ");
                        $updateStockStmt->execute([$productId, $productId, $productId, $productId]);
                    }
                    error_log("Stripe Payment: Updated stock counts for " . count($productIds) . " products");
                }
                
                return [
                    'success' => true,
                    'registration_number' => $registrationNumber,
                    'amount_paid' => $paymentIntent->amount / 100
                ];
            } else {
                return [
                    'success' => false,
                    'error' => 'Payment not completed',
                    'status' => $paymentIntent->status
                ];
            }
            
        } catch (ApiErrorException $e) {
            error_log('Stripe Confirm Error: ' . $e->getMessage());
            return [
                'success' => false,
                'error' => 'Payment confirmation failed',
                'details' => $e->getMessage()
            ];
        }
    }
}

// Handle API requests
$input = json_decode(file_get_contents('php://input'), true);
$action = $input['action'] ?? '';

try {
    $stripeHandler = new StripePaymentHandler();
    
    switch ($action) {
        case 'create_payment_intent':
            $result = $stripeHandler->createCheckoutSession($input['registrationData']);
            echo json_encode($result);
            break;
            
        case 'confirm_payment':
            $result = $stripeHandler->confirmPayment($input['payment_intent_id']);
            echo json_encode($result);
            break;
            
        default:
            echo json_encode(['success' => false, 'error' => 'Invalid action: ' . $action]);
            break;
    }
} catch (Exception $e) {
    error_log('Stripe Payment Error: ' . $e->getMessage());
    echo json_encode([
        'success' => false, 
        'error' => 'Payment processing failed: ' . $e->getMessage()
    ]);
}
?>
