<?php
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../config/config.php';

header('Content-Type: application/json; charset=utf-8');

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    jsonResponse(false, 'Invalid request method', [], 405);
}

$input = json_decode(file_get_contents('php://input'), true);
if (!$input) {
    $input = $_POST;
}

$action = $input['action'] ?? '';
$csrfToken = $input['csrf_token'] ?? '';

$csrf = new CSRF();
if (!$csrf->verify($csrfToken)) {
    jsonResponse(false, 'Invalid security token');
}

$auth = new Auth();
if (!$auth->check()) {
    jsonResponse(false, 'Unauthorized', [], 401);
}

$restaurantId = $auth->restaurantId();
if (!$restaurantId) {
    jsonResponse(false, 'No restaurant associated', [], 403);
}

$db = Database::getInstance();
$pdo = $db->getConnection();

switch ($action) {
    case 'process_payment':
        handleProcessPayment($pdo, $input, $restaurantId, $auth);
        break;
    case 'get_order_details':
        handleGetOrderDetails($pdo, $input, $restaurantId);
        break;
    case 'get_receipt':
        handleGetReceipt($pdo, $input, $restaurantId);
        break;
    default:
        jsonResponse(false, 'Invalid action');
}

function handleProcessPayment($pdo, $input, $restaurantId, $auth)
{
    $orderId = (int) ($input['order_id'] ?? 0);
    $amount = (float) ($input['amount'] ?? 0);
    $paymentMethod = $input['payment_method'] ?? 'cash';
    $transactionRef = trim($input['transaction_ref'] ?? '');
    $notes = trim($input['notes'] ?? '');

    if (!$orderId) {
        jsonResponse(false, 'Invalid order ID');
    }

    if ($amount <= 0) {
        jsonResponse(false, 'Invalid payment amount');
    }

    if (!in_array($paymentMethod, ['cash', 'card', 'bank_transfer', 'manual', 'online'])) {
        jsonResponse(false, 'Invalid payment method');
    }

    $stmt = $pdo->prepare(
        "SELECT id, restaurant_id, grand_total, payment_status, payment_method
         FROM orders WHERE id = ? AND restaurant_id = ? LIMIT 1"
    );
    $stmt->execute([$orderId, $restaurantId]);
    $order = $stmt->fetch();

    if (!$order) {
        jsonResponse(false, 'Order not found');
    }

    $paidStmt = $pdo->prepare(
        "SELECT COALESCE(SUM(amount), 0) AS total_paid FROM payments WHERE order_id = ? AND status = 'paid'"
    );
    $paidStmt->execute([$orderId]);
    $paidResult = $paidStmt->fetch();
    $totalPaid = (float) ($paidResult['total_paid'] ?? 0);
    $balance = (float) $order['grand_total'] - $totalPaid;

    if ($amount > $balance + 0.01) {
        jsonResponse(false, 'Amount exceeds balance. Balance: ' . number_format($balance, 2));
    }

    $pdo->beginTransaction();

    try {
        $payStmt = $pdo->prepare(
            "INSERT INTO payments (order_id, restaurant_id, amount, payment_method, transaction_ref, status, notes, created_at)
             VALUES (?, ?, ?, ?, ?, 'paid', ?, NOW())"
        );
        $payStmt->execute([
            $orderId,
            $restaurantId,
            $amount,
            $paymentMethod,
            $transactionRef ?: null,
            $notes ?: null,
        ]);

        $newTotalPaid = $totalPaid + $amount;
        $newBalance = (float) $order['grand_total'] - $newTotalPaid;

        if ($newBalance <= 0.01) {
            $paymentStatus = 'paid';
        } else {
            $paymentStatus = 'partial';
        }

        $updateOrder = $pdo->prepare(
            "UPDATE orders SET payment_status = ?, payment_method = ?, updated_at = NOW() WHERE id = ?"
        );
        $updateOrder->execute([$paymentStatus, $paymentMethod, $orderId]);

        if ($paymentStatus === 'paid' && $order['order_status'] !== 'completed') {
            $completeStmt = $pdo->prepare(
                "UPDATE orders SET order_status = 'completed', updated_at = NOW() WHERE id = ? AND order_status = 'served'"
            );
            $completeStmt->execute([$orderId]);

            $orderCheck = $pdo->prepare("SELECT table_id FROM orders WHERE id = ?");
            $orderCheck->execute([$orderId]);
            $orderData = $orderCheck->fetch();
            if ($orderData && $orderData['table_id']) {
                $tableReset = $pdo->prepare(
                    "UPDATE tables SET status = 'available', updated_at = NOW() WHERE id = ? AND restaurant_id = ?"
                );
                $tableReset->execute([$orderData['table_id'], $restaurantId]);
            }
        }

        $historyStmt = $pdo->prepare(
            "INSERT INTO order_status_history (order_id, from_status, to_status, notes, changed_by, created_at)
             VALUES (?, ?, ?, ?, ?, NOW())"
        );
        $historyStmt->execute([
            $orderId,
            $order['payment_status'],
            $paymentStatus,
            'Payment of ' . number_format($amount, 2) . ' via ' . $paymentMethod,
            $auth->userId()
        ]);

        $pdo->commit();

        jsonResponse(true, 'Payment processed successfully', [
            'order_id'       => $orderId,
            'amount_paid'    => $amount,
            'total_paid'     => $newTotalPaid,
            'balance'        => max(0, $newBalance),
            'payment_status' => $paymentStatus,
        ]);

    } catch (Exception $e) {
        $pdo->rollBack();
        error_log('Cashier payment error: ' . $e->getMessage());
        jsonResponse(false, 'Failed to process payment', [], 500);
    }
}

function handleGetOrderDetails($pdo, $input, $restaurantId)
{
    $orderId = (int) ($input['order_id'] ?? 0);
    if (!$orderId) {
        jsonResponse(false, 'Invalid order ID');
    }

    $stmt = $pdo->prepare(
        "SELECT o.*, t.table_number, t.table_name
         FROM orders o
         LEFT JOIN tables t ON o.table_id = t.id
         WHERE o.id = ? AND o.restaurant_id = ? LIMIT 1"
    );
    $stmt->execute([$orderId, $restaurantId]);
    $order = $stmt->fetch();

    if (!$order) {
        jsonResponse(false, 'Order not found');
    }

    $itemStmt = $pdo->prepare(
        "SELECT id, item_name, variation_name, quantity, unit_price, variation_price,
                addons_total, item_total, item_notes
         FROM order_items WHERE order_id = ?"
    );
    $itemStmt->execute([$orderId]);
    $order['items'] = $itemStmt->fetchAll();

    foreach ($order['items'] as &$item) {
        $addonStmt = $pdo->prepare(
            "SELECT addon_name, addon_price FROM order_item_addons WHERE order_item_id = ?"
        );
        $addonStmt->execute([$item['id']]);
        $item['addons'] = $addonStmt->fetchAll();
    }
    unset($item);

    $paidStmt = $pdo->prepare(
        "SELECT COALESCE(SUM(amount), 0) AS total_paid FROM payments WHERE order_id = ? AND status = 'paid'"
    );
    $paidStmt->execute([$orderId]);
    $paidResult = $paidStmt->fetch();
    $order['total_paid'] = (float) ($paidResult['total_paid'] ?? 0);
    $order['balance'] = (float) $order['grand_total'] - $order['total_paid'];

    jsonResponse(true, 'Order loaded', ['order' => $order]);
}

function handleGetReceipt($pdo, $input, $restaurantId)
{
    $orderId = (int) ($input['order_id'] ?? 0);
    if (!$orderId) {
        jsonResponse(false, 'Invalid order ID');
    }

    $stmt = $pdo->prepare(
        "SELECT o.*, t.table_number, t.table_name
         FROM orders o
         LEFT JOIN tables t ON o.table_id = t.id
         WHERE o.id = ? AND o.restaurant_id = ? LIMIT 1"
    );
    $stmt->execute([$orderId, $restaurantId]);
    $order = $stmt->fetch();

    if (!$order) {
        jsonResponse(false, 'Order not found');
    }

    $itemStmt = $pdo->prepare(
        "SELECT id, item_name, variation_name, quantity, unit_price, variation_price,
                addons_total, item_total, item_notes
         FROM order_items WHERE order_id = ?"
    );
    $itemStmt->execute([$orderId]);
    $order['items'] = $itemStmt->fetchAll();

    foreach ($order['items'] as &$item) {
        $addonStmt = $pdo->prepare(
            "SELECT addon_name, addon_price FROM order_item_addons WHERE order_item_id = ?"
        );
        $addonStmt->execute([$item['id']]);
        $item['addons'] = $addonStmt->fetchAll();
    }
    unset($item);

    $restStmt = $pdo->prepare("SELECT name, logo, phone, email, address FROM restaurants WHERE id = ?");
    $restStmt->execute([$restaurantId]);
    $restaurant = $restStmt->fetch();

    jsonResponse(true, 'Receipt loaded', [
        'order'      => $order,
        'restaurant' => $restaurant,
    ]);
}
