<?php
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}
require_once 'mail/MailService.php';
require_once 'includes/init.php';
require_once 'includes/auth.php';
require_login();
require_once 'includes/helpers.php';
require_once 'includes/currency.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: checkout.php');
    exit;
}

$cart = $_SESSION['cart'] ?? [];
if (empty($cart)) {
    header('Location: index.php');
    exit;
}

$pdo = db();

try {
    $pdo->beginTransaction();

    // 1. Get product details from the database
    $product_ids = array_keys($cart);
    $placeholders = implode(',', array_fill(0, count($product_ids), '?'));
    $stmt = $pdo->prepare("SELECT id, price, units_per_pallet, name FROM products WHERE id IN ($placeholders)");
    $stmt->execute($product_ids);
    $products_by_id = $stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC);

    // 2. Calculate total amount
    $total_amount = 0;
    $client_id = $_SESSION['client_id'] ?? null;
    $lang = $_SESSION['lang'] ?? 'pl';
    
    $order_items_data = [];

    $is_supplier_delivery = false;
    foreach ($cart as $product_id => $quantity) {
        if (isset($products_by_id[$product_id])) {
            $product = $products_by_id[$product_id];
            
            $price_info = getEffectivePrice($pdo, $product_id, $client_id);
            $price_net = $price_info['net'];
            $price_gross = $price_info['gross'];

            if ($lang === 'en') {
                $unit_price = $price_net;
            } else {
                $unit_price = $price_gross;
            }

            $line_total = $unit_price * $quantity;
            $total_amount += $line_total;

            $order_items_data[] = [
                'product_id' => $product_id,
                'quantity' => $quantity,
                'unit_price' => $unit_price, 
                'line_total' => $line_total,
                'name' => $product['name'],
            ];

            $units_per_pallet = $product['units_per_pallet'];
            if (isset($units_per_pallet) && $units_per_pallet > 0) {
                if ($quantity >= $units_per_pallet) {
                    $is_supplier_delivery = true;
                }
            }
        }
    }
    
    $delivery_source = $is_supplier_delivery ? 'supplier' : 'cs';

    if ($_POST['payment_method'] === 'credit') {
        $stmt = $pdo->prepare('SELECT credit_balance, credit_enabled FROM clients WHERE id = ? FOR UPDATE');
        $stmt->execute([$client_id]);
        $credit_info = $stmt->fetch();

        if (!$credit_info || !$credit_info['credit_enabled'] || $credit_info['credit_balance'] < $total_amount) {
            throw new Exception('Invalid payment method or insufficient credit.');
        }

        $new_balance = $credit_info['credit_balance'] - $total_amount;
        $stmt = $pdo->prepare('UPDATE clients SET credit_balance = ? WHERE id = ?');
        $stmt->execute([$new_balance, $client_id]);
    }

    // 3. Create the order
    $stmt = $pdo->prepare(
        'INSERT INTO orders (client_id, total_amount, payment_method, delivery_source, notes, status) VALUES (?, ?, ?, ?, ?, ?)'
    );
    $stmt->execute([
        $client_id,
        $total_amount,
        $_POST['payment_method'],
        $delivery_source,
        $_POST['notes'],
        $_POST['payment_method'] === 'credit' ? 'in_progress' : 'pending_payment'
    ]);
    $order_id = $pdo->lastInsertId();

    // 4. Insert order items
    $stmt = $pdo->prepare(
        'INSERT INTO order_items (order_id, product_id, quantity, unit_price, line_total) VALUES (?, ?, ?, ?, ?)'
    );
    foreach ($order_items_data as $item) {
        $stmt->execute([
            $order_id,
            $item['product_id'],
            $item['quantity'],
            $item['unit_price'],
            $item['line_total'],
        ]);
    }

    // Handle Przelewy24 payment
    if ($_POST['payment_method'] === 'przelewy24') {
        require_once 'includes/Przelewy24.php';
        $p24 = new Przelewy24();

        // Unique session ID for this payment attempt
        $p24_session_id = uniqid('order_' . $order_id . '_', true);

        // Update order with the session ID
        $stmt = $pdo->prepare('UPDATE orders SET p24_session_id = ? WHERE id = ?');
        $stmt->execute([$p24_session_id, $order_id]);

        $user_id = $_SESSION['user_id'] ?? null;
        $stmt = $pdo->prepare('SELECT email, name FROM users WHERE id = ?');
        $stmt->execute([$user_id]);
        $user = $stmt->fetch();
        $client_email = $user['email'] ?? '';
        $client_name = $user['name'] ?? 'Customer';

        // Register transaction with P24
        $p24_data = [
            'sessionId' => $p24_session_id,
            'amount' => (int)($total_amount * 100), // Amount in grosze
            'description' => "Order #" . $order_id,
            'email' => $client_email,
            'client' => $client_name,
        ];

        $response = $p24->registerTransaction($p24_data);

        if (isset($response['data']['token'])) {
            $token = $response['data']['token'];
            
            // update order with p24_order_id
            $stmt = $pdo->prepare("UPDATE orders SET p24_order_id = ? WHERE id = ?");
            $stmt->execute([$token, $order_id]);
            
            $pdo->commit();

            $redirect_url = $p24->getRedirectUrl($token);
            header('Location: ' . $redirect_url);
            exit;
        } else {
            $pdo->rollBack();
            $error_message = 'There is no active transaction';
            if (!empty($response['errors'])) {
                $error_message = '';
                foreach ($response['errors'] as $field => $error) {
                    $error_message .= "$field: $error<br>";
                }
            } elseif (isset($response['error'])) {
                $error_message = $response['error'];
            }
            redirect_with_error('checkout.php', 'Error processing order: ' . $error_message);
        }
    }

    $pdo->commit();

    // 6. Send email notifications
    $user_id = $_SESSION['user_id'] ?? null;
    $stmt = $pdo->prepare('SELECT email FROM users WHERE id = ?');
    $stmt->execute([$user_id]);
    $user = $stmt->fetch();
    $client_email = $user['email'] ?? null;

    $stmt = $pdo->prepare('SELECT name FROM clients WHERE id = ?');
    $stmt->execute([$client_id]);
    $client = $stmt->fetch();
    $client_company_name = $client['name'] ?? 'N/A';

    $order_details_link = get_site_url() . '/order_details.php?id=' . $order_id;
    $admin_order_details_link = get_site_url() . '/admin/order_details.php?id=' . $order_id;
    $admin_email = getenv('MAIL_TO') ?: 'admin@example.com';

    $site_name = get_site_url();
    $lang = get_lang();

    $products_by_id_for_email = [];
    foreach($order_items_data as $item){
        $products_by_id_for_email[$item['product_id']] = $item['name'];
    }

    if ($client_email) {
        $data_client = [
            'order_id' => $order_id,
            'order_items' => $order_items_data,
            'products' => $products_by_id_for_email,
            'total_amount' => $total_amount,
            'payment_method' => $_POST['payment_method'],
            'order_details_link' => $order_details_link,
            'site_name' => $site_name,
            'pdo' => $pdo,
        ];
        MailService::sendTemplatedMail($client_email, $lang, 'order_confirmation', $data_client);

        if ($_POST['payment_method'] === 'bank_transfer') {
            $stmt = $pdo->query("SELECT `key`, `value` FROM settings WHERE `key` IN ('bank_name', 'bank_account_number')");
            $settings = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
            
            $bank_name = $settings['bank_name'] ?? '';
            $bank_account_number = $settings['bank_account_number'] ?? '';

            $bank_account_details = "Bank: " . $bank_name . "
Account Number: " . $bank_account_number;
            $transfer_title = "Order #{$order_id}";
            $payment_deadline = date('Y-m-d', strtotime('+7 days'));

            $data_bank = [
                'order_id' => $order_id,
                'total_amount' => $total_amount,
                'bank_account_details' => $bank_account_details,
                'transfer_title' => $transfer_title,
                'payment_deadline' => $payment_deadline,
                'site_name' => $site_name,
                'pdo' => $pdo,
            ];
            MailService::sendTemplatedMail($client_email, $lang, 'payment_instructions', $data_bank);
        }

        if ($_POST['payment_method'] === 'credit') {
            $data_credit = [
                'order_id' => $order_id,
                'total_amount' => $total_amount,
                'new_balance' => $new_balance,
                'order_details_link' => $order_details_link,
                'site_name' => $site_name,
                'pdo' => $pdo,
            ];
            MailService::sendTemplatedMail($client_email, $lang, 'credit_payment_confirmation', $data_credit);
        }
    }

    $data_admin = [
        'order_id' => $order_id,
        'client_company_name' => $client_company_name,
        'total_amount' => $total_amount,
        'payment_method' => $_POST['payment_method'],
        'delivery_source' => $delivery_source,
        'admin_order_details_link' => $admin_order_details_link,
        'site_name' => $site_name,
        'pdo' => $pdo,
    ];
    MailService::sendTemplatedMail($admin_email, 'en', 'admin_new_order', $data_admin);

    $stmt = $pdo->prepare("
        SELECT p.supplier_id, s.name as supplier_name, s.email as supplier_email, p.name as product_name, oi.quantity
        FROM order_items oi
        JOIN products p ON oi.product_id = p.id
        JOIN suppliers s ON p.supplier_id = s.id
        WHERE oi.order_id = ? AND p.supplier_id IS NOT NULL
    ");
    $stmt->execute([$order_id]);
    $supplier_items = $stmt->fetchAll(PDO::FETCH_ASSOC);

    $items_by_supplier = [];
    foreach ($supplier_items as $item) {
        $items_by_supplier[$item['supplier_id']]['name'] = $item['supplier_name'];
        $items_by_supplier[$item['supplier_id']]['email'] = $item['supplier_email'];
        $items_by_supplier[$item['supplier_id']]['items'][] = [
            'name' => $item['product_name'],
            'quantity' => $item['quantity'],
        ];
    }

    foreach ($items_by_supplier as $supplier_id => $supplier_data) {
        if (!empty($supplier_data['email'])) {


            $data_supplier = [
                'order_id' => $order_id,
                'supplier_items' => $supplier_data['items'],
                'site_name' => $site_name,
                'pdo' => $pdo,
            ];
            MailService::sendTemplatedMail($supplier_data['email'], 'en', 'supplier_new_order_items', $data_supplier);
        }
    }


    unset($_SESSION['cart']);
    $_SESSION['latest_order_id'] = $order_id;

    header('Location: order_confirmation.php');
    exit;

} catch (Exception $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    error_log("Error in order_process.php: " . $e->getMessage());
    die("Error processing order. Please try again later.");
} catch (PDOException $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    error_log("PDOError in order_process.php: " . $e->getMessage());
    die("Error processing order. Please try again later.");
} catch (Throwable $t) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    error_log("Fatal error in order_process.php: " . $t->getMessage());
    die("An unexpected error occurred. Please try again later.");
}