<?php

session_start();
//include '../../includes/header.php';

require_once __DIR__ . '/../../includes/auth.php';
require_once __DIR__ . '/../../includes/dashboard_helper.php';
require_once __DIR__ . '/../../classes/Database.php';
require_once __DIR__ . '/../../classes/SystemSettings.php';
require_once __DIR__ . '/../../classes/Logger.php';
require_once __DIR__ . '/../../classes/Inventory.php';
require_once __DIR__ . '/../../classes/Sales.php';
require_once __DIR__ . '/../../classes/Branch.php';
require_once __DIR__ . '/../../classes/MraEisCompliance.php';
require_once __DIR__ . '/../../classes/DiscountPolicy.php';
require_once __DIR__ . '/../../classes/CreditSales.php';
require_once __DIR__ . '/../../classes/Customers.php';
require_once __DIR__ . '/../../includes/payment_options.php';

if (!isset($_SESSION['user_id']) || !isset($_SESSION['username']) || !isset($_SESSION['role'])) {
    header('Location: /IMS/login.php');
    exit();
}

$database = new Database();
$conn = $database->getConnection();
$systemSettings = new SystemSettings(null, $conn);
$vatPercentage = $systemSettings->vatPercentage();
$vatRate = $systemSettings->vatRate();
$profitPercentageDefault = $systemSettings->profitPercentage();
$eisEnabled = $systemSettings->eisEnabled();
$eisManualOfflineMode = $eisEnabled && $systemSettings->eisOfflineMode();
$eisOfflineMode = $eisManualOfflineMode;
$allowManualSaleDate = $systemSettings->allowManualSaleDate();

$logger = new Logger($conn, $_SESSION['user_id'], $_SESSION['username'], $_SESSION['role']);

$auth = new Auth($conn);
$inventory = new Inventory($conn, $logger);
$sales = new Sales($conn, $logger);
$discountPolicy = new DiscountPolicy($conn);
$discountRules = $discountPolicy->getActiveRules();
$creditSales = new CreditSales($conn);
$customers = new Customers($conn);

if (
    !$auth->isSalesAssistant($_SESSION['user_id']) &&
    !$auth->isBranchManager($_SESSION['user_id']) &&
    !$auth->isWarehousePersonnel($_SESSION['user_id']) &&
    ($_SESSION['role'] ?? '') !== 'super_admin'
) {
    die("Access denied. You must be a sales assistant, branch manager, or warehouse personnel to access this page.");
}

$branchId = $auth->getUserBranch($_SESSION['user_id']);
if (!$branchId) {
    die("Error: You are not assigned to any branch.");
}
$eisOfflineStatus = null;
if ($eisEnabled) {
    try {
        $eisCompliance = new MraEisCompliance($conn);
        $eisOfflineStatus = $eisCompliance->offlineStatusForSale($branchId, $_SESSION['user_id']);
        $eisOfflineMode = $eisManualOfflineMode
            || ($eisOfflineStatus['connection_status'] ?? '') === 'offline';
    } catch (Throwable $e) {
        error_log('Unable to load MRA EIS offline status: ' . $e->getMessage());
    }
}

$successMessage = '';
$saleData = [];
$errors = [];

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['record_sale'])) {

    $saleDate = date('Y-m-d');
    if ($allowManualSaleDate && !empty($_POST['sale_date'])) {
        $postedSaleDate = trim((string)$_POST['sale_date']);
        $parsedSaleDate = DateTime::createFromFormat('Y-m-d', $postedSaleDate);
        if (!$parsedSaleDate || $parsedSaleDate->format('Y-m-d') !== $postedSaleDate) {
            $errors[] = 'Invalid sale date.';
        } else {
            // Only takes effect for offline/credit/non-EIS sales below — any
            // online MRA EIS submission overwrites this with the live server
            // time, since invoice dates can't be backdated with MRA.
            $saleDate = $postedSaleDate;
        }
    }
    $transactionId = '';
    $userId = $_SESSION['user_id'];

    $quantity = isset($_POST['quantity']) ? (int)$_POST['quantity'] : 0;
    $uniqueCodes = isset($_POST['unique_code']) ? $_POST['unique_code'] : [];
    $itemNames = isset($_POST['item_name']) ? $_POST['item_name'] : [];
    $itemDetails = isset($_POST['item_details']) ? $_POST['item_details'] : [];
    $prices = isset($_POST['price']) ? array_map('floatval', $_POST['price']) : [];
    $amountPaid = isset($_POST['amount_paid']) ? (float)$_POST['amount_paid'] : 0;
    $paymentMethod = normalizePaymentMethodValue($_POST['payment_method'] ?? 'cash');
    $saleMode = strtolower(trim((string)($_POST['sale_mode'] ?? 'cash')));
    $isCreditSale = $saleMode === 'credit';
    $discountType = strtolower(trim((string)($_POST['discount_type'] ?? 'none')));
    $discountValue = isset($_POST['discount_value']) ? (float)$_POST['discount_value'] : 0.0;
    if (!in_array($discountType, ['none', 'percentage', 'fixed'], true)) {
        $discountType = 'none';
    }
    if ($isCreditSale) {
        $discountType = 'none';
        $discountValue = 0.0;
    }
    $postedCustomerId = isset($_POST['customer_id']) ? (int)$_POST['customer_id'] : 0;
    $customerName = isset($_POST['customer_name']) ? trim($_POST['customer_name']) : null;
    $customerPhone = isset($_POST['customer_phone']) ? trim($_POST['customer_phone']) : null;
    $vatRelief = !empty($_POST['apply_vat_relief']);
    $eisTransactionType = strtoupper(trim($_POST['eis_transaction_type'] ?? 'B2C'));
    $buyerTin = isset($_POST['buyer_tin']) ? trim($_POST['buyer_tin']) : null;
    $buyerAuthorizationCode = isset($_POST['buyer_authorization_code']) ? trim($_POST['buyer_authorization_code']) : null;
    $vat5CertificateNumber = isset($_POST['vat5_certificate_number']) ? trim($_POST['vat5_certificate_number']) : null;
    if ($vat5CertificateNumber === '') {
        $vat5CertificateNumber = null;
    }
    $vat5ProjectNumber = isset($_POST['vat5_project_number']) ? trim($_POST['vat5_project_number']) : null;
    if ($vat5ProjectNumber === '') {
        $vat5ProjectNumber = null;
    }

    if (!in_array($eisTransactionType, ['B2C', 'B2B'], true)) {
        $errors[] = 'Select a valid EIS transaction type.';
        $eisTransactionType = 'B2C';
    }
    if ($vatRelief && $eisTransactionType !== 'B2B') {
        $errors[] = 'VAT relief requires a B2B transaction with a valid buyer TIN.';
    }
    if ($isCreditSale) {
        $eisTransactionType = 'B2C';
        $buyerTin = null;
        $buyerAuthorizationCode = null;
        $vatRelief = false;
        $vat5ProjectNumber = null;
    } elseif ($eisTransactionType === 'B2C') {
        $buyerTin = null;
        $buyerAuthorizationCode = null;
    }
    if ($vatRelief && $vat5ProjectNumber === null) {
        // MRA ties a VAT-5 relief exemption to the specific approved project it was
        // issued for — the certificate-validation response can't be relied on to
        // supply this (and never persists it), so the cashier must enter it.
        $errors[] = 'VAT relief requires the VAT-5 project number the certificate was issued for.';
    }
    if ($vatRelief && $vat5CertificateNumber === null) {
        $errors[] = 'VAT relief requires the VAT-5 certificate number.';
    }

    $eisCompliance = null;
    $onlineContext = null;
    if (!$isCreditSale && $eisEnabled && !$eisOfflineMode) {
        try {
            $eisCompliance = new MraEisCompliance($conn);
            $onlineContext = $eisCompliance->prepareOnlineSaleContext($branchId, $userId);
            $serverDateTime = new DateTimeImmutable((string)$onlineContext['server_datetime']);
            $saleDate = $serverDateTime->format('Y-m-d H:i:s');
        } catch (Throwable $e) {
            $eisOfflineStatus = $eisCompliance
                ? $eisCompliance->offlineStatusForSale($branchId, $userId)
                : null;
            if ($eisTransactionType === 'B2C' && ($eisOfflineStatus['connection_status'] ?? '') === 'offline') {
                $eisOfflineMode = true;
            } else {
                $errors[] = $e->getMessage();
            }
        }
    }

    // $saleDate is either a bare 'Y-m-d' (manual/offline entry) or a full
    // 'Y-m-d H:i:s' (set from the live MRA server time for an online sale) — use
    // whichever the cashier/system actually recorded as the offline-threshold
    // reference time, instead of the wall clock, everywhere below.
    $saleDateTime = strpos($saleDate, ':') !== false ? $saleDate : ($saleDate . ' ' . date('H:i:s'));

    if ($quantity <= 0) {
        $errors[] = "Quantity must be greater than zero.";
    }

    if (count($uniqueCodes) != $quantity) {
        $errors[] = "Number of unique codes does not match quantity.";
    }

    if (count($prices) != $quantity) {
        $errors[] = "Number of prices does not match quantity.";
    }

    $uniqueCodes = array_map(static function ($code) {
        return trim((string)$code);
    }, $uniqueCodes);
    $prices = array_map(static function ($price) {
        return round((float)$price, 2);
    }, $prices);

    if (count(array_unique(array_filter($uniqueCodes, 'strlen'))) !== count(array_filter($uniqueCodes, 'strlen'))) {
        $errors[] = 'The same item cannot be added to a receipt more than once.';
    }
    foreach ($prices as $index => $price) {
        if ($price <= 0) {
            $errors[] = 'Item ' . ($index + 1) . ' must have a valid price greater than zero.';
        }
    }

    $originalPrices = $prices;
    if (!$isCreditSale && $vatRelief && empty($errors)) {
        try {
            $eisCompliance = $eisCompliance ?: new MraEisCompliance($conn);
            $prices = $eisCompliance->reliefAdjustedPrices($branchId, $userId, $uniqueCodes, $prices);
        } catch (Throwable $e) {
            $errors[] = $e->getMessage();
        }
    }

    // Do all authoritative money calculations in integer tambala to avoid
    // floating-point drift across multi-item invoices.
    $grossCents = array_sum(array_map(static function ($price) {
        return (int)round($price * 100);
    }, $prices));
    $totalCents = $grossCents;
    $amountPaidCents = (int)round($amountPaid * 100);
    $grossTotal = $grossCents / 100;
    $total = $totalCents / 100;
    $amountPaid = $amountPaidCents / 100;
    if ($discountType === 'percentage') {
        if ($discountValue < 0 || $discountValue > 100) {
            $errors[] = 'Percentage discount must be between 0% and 100%.';
        } else {
            $amountPaidCents = (int)round($totalCents * (1 - ($discountValue / 100)));
        }
    } elseif ($discountType === 'fixed') {
        $fixedDiscountCents = (int)round($discountValue * 100);
        if ($fixedDiscountCents < 0 || $fixedDiscountCents > $totalCents) {
            $errors[] = 'Fixed discount cannot exceed the sale total.';
        } else {
            $amountPaidCents = max(0, $totalCents - $fixedDiscountCents);
        }
    }

    // A discount only takes effect once a controller has approved it — either as a
    // standing rule (discount_rules) or this exact request. Otherwise the sale is
    // blocked and a request is filed automatically so a controller can review it.
    if ($discountType !== 'none' && $discountValue > 0 && empty($errors)) {
        if (!$discountPolicy->isDiscountAllowed($discountType, $discountValue, $total)) {
            $discountPolicy->requestApproval(
                $branchId,
                $userId,
                $discountType,
                $discountValue,
                $total,
                trim((string)($_POST['discount_reason'] ?? ''))
            );
            $errors[] = 'This discount has not been approved by a controller. A request has been sent for review — complete the sale without a discount, or try again once it is approved.';
        }
    }

    $amountPaid = $amountPaidCents / 100;

    if (empty($customerName)) {
        $errors[] = "Customer name is required.";
    }

    if ($customerPhone && !preg_match('/^\+?[0-9]{7,15}$/', $customerPhone)) {
        $errors[] = "Invalid phone number format.";
    }

    if ($eisTransactionType === 'B2B' && ($buyerTin === null || !preg_match('/^[A-Za-z0-9-]{5,30}$/', $buyerTin))) {
        $errors[] = 'A valid buyer TIN is required for a B2B transaction.';
    }

    if (empty($errors)) {
        try {
            $transactionId = ($eisEnabled && !$isCreditSale)
                ? $sales->generateMraEisInvoiceNumber($branchId, $saleDate)
                : $sales->generateLocalTransactionNumber();
        } catch (Throwable $e) {
            $errors[] = $e->getMessage();
        }
    }

    if (!$isCreditSale && $eisTransactionType === 'B2B' && empty($errors)) {
        if ($eisOfflineMode) {
            $errors[] = 'B2B transactions are online-only. Turn off EIS Offline and reconnect to MRA before continuing.';
        } elseif (!$eisEnabled) {
            $errors[] = 'B2B transactions are online-only and require MRA EIS to be enabled.';
        } else {
            try {
                $eisCompliance = new MraEisCompliance($conn);
                $b2bValidation = $eisCompliance->validateOnlineB2BBuyer(
                    $branchId,
                    $userId,
                    $buyerTin,
                    $buyerAuthorizationCode
                );
                $buyerTin = $b2bValidation['buyer_tin'];
                $buyerAuthorizationCode = $b2bValidation['buyer_authorization_code'];
            } catch (Throwable $e) {
                $errors[] = $e->getMessage();
            }
        }
    }

    if (!$isCreditSale && $vatRelief && empty($errors)) {
        try {
            $eisCompliance = $eisCompliance ?: new MraEisCompliance($conn);
            $vat5Details = $eisCompliance->validateVat5Certificate(
                $branchId,
                $userId,
                $vat5CertificateNumber,
                $vat5ProjectNumber
            );
            $vat5CertificateNumber = $vat5Details['certificateNumber'];
            // The cashier-entered project number is authoritative — it's what the
            // certificate was actually issued for — so it overrides whatever (if
            // anything) MRA's validation response reports.
            $vat5Details['projectNumber'] = $vat5ProjectNumber;
        } catch (Throwable $e) {
            $errors[] = $e->getMessage();
        }
    }

    if (!$isCreditSale && $eisOfflineMode && $eisTransactionType === 'B2C' && empty($errors)) {
        try {
            $eisCompliance = $eisCompliance ?: new MraEisCompliance($conn);
            $eisCompliance->assertOfflineSaleAllowed(
                $branchId,
                $userId,
                $total,
                $saleDateTime,
                $transactionId
            );
        } catch (Throwable $e) {
            $errors[] = $e->getMessage();
        }
    }

    if (empty($errors)) {

        $finalTotalCents = $isCreditSale ? $totalCents : min($amountPaidCents, $totalCents);
        $changeCents = max(0, $amountPaidCents - $totalCents);
        $discountCents = max(0, $totalCents - $finalTotalCents);
        $vatApplies = !$vatRelief && ($onlineContext['is_vat_registered'] ?? null) !== false;

        // Allocate the actual invoice total proportionally to the selected item
        // prices. An average price corrupts mixed-price sales, and independently
        // rounded lines can otherwise differ from the receipt total.
        $allocatedPrices = [];
        $remainingCents = $finalTotalCents;
        foreach ($prices as $index => $price) {
            if ($index === count($prices) - 1) {
                $allocatedCents = $remainingCents;
            } else {
                $priceCents = (int)round($price * 100);
                $allocatedCents = $grossCents > 0
                    ? (int)round($finalTotalCents * ($priceCents / $grossCents))
                    : 0;
                $allocatedCents = min(max(0, $allocatedCents), $remainingCents);
            }
            $allocatedPrices[] = $allocatedCents / 100;
            $remainingCents -= $allocatedCents;
        }

        // VAT is computed per line against its own MRA tax rate group (standard
        // vs. zero-rated/exempt) instead of one blended rate across the whole
        // cart, so mixed-tax-group sales aren't over- or under-taxed by averaging.
        $zeroRatedTaxIds = $systemSettings->eisZeroRatedTaxIds();
        $vatCents = 0;
        if ($vatApplies) {
            foreach ($uniqueCodes as $index => $uniqueCode) {
                $lineCents = (int)round(($allocatedPrices[$index] ?? 0) * 100);
                if ($lineCents <= 0) {
                    continue;
                }
                $lineItem = $inventory->getItemByUniqueCode(trim((string)$uniqueCode));
                // Use the tax group stored against the exact row in `items`.
                $taxRateId = strtoupper(trim((string)($lineItem['tax_rate_id'] ?? '')));
                if ($taxRateId === '') {
                    $taxRateId = 'A';
                }
                if (in_array($taxRateId, $zeroRatedTaxIds, true)) {
                    continue;
                }
                $vatCents += (int)round(($lineCents * $vatRate) / (1 + $vatRate));
            }
        }
        $subtotalCents = $finalTotalCents - $vatCents;

        $finalTotal = $finalTotalCents / 100;
        $change = $changeCents / 100;
        $discount = $discountCents / 100;
        $discountPercentage = $totalCents > 0 ? (($discountCents / $totalCents) * 100) : 0;
        $subtotal = $subtotalCents / 100;
        $vatAmount = $vatCents / 100;

        $saleData = [
            'transaction_id' => $transactionId,
            'sale_date' => $saleDate,
            'sale_time' => (new DateTimeImmutable($saleDate))->format('H:i:s'),
            'quantity' => $quantity,
            'unique_codes' => $uniqueCodes,
            'item_names' => $itemNames,
            'item_details' => $itemDetails,
            'prices' => $allocatedPrices,
            'original_total' => $total,
            'subtotal' => $subtotal,
            'include_vat' => !$vatRelief,
            'vat_relief' => $vatRelief,
            'buyer_tin' => $buyerTin,
            'eis_transaction_type' => $eisTransactionType,
            'buyer_authorization_code' => $buyerAuthorizationCode,
            'vat5_certificate_number' => $vat5CertificateNumber,
            'vat5_project_number' => $vat5Details['projectNumber'] ?? $vat5ProjectNumber,
            'is_vat_registered' => $onlineContext['is_vat_registered'] ?? null,
            'vat_amount' => $vatAmount,
            'total' => $finalTotal,
            'amount_paid' => $amountPaid,
            'payment_method' => $paymentMethod,
            'payment_method_label' => paymentMethodLabel($paymentMethod),
            'change_due' => $change,
            'discount' => $discount,
            'discount_percentage' => $discountPercentage,
            'discount_type' => $discountType,
            'discount_value' => $discountValue,
            'sale_mode' => $isCreditSale ? 'credit' : 'cash',
            'credit_balance' => $isCreditSale ? max(0, ($totalCents - $amountPaidCents) / 100) : 0,
            'customer_id' => null,
            'customer_name' => $customerName,
            'customer_phone' => $customerPhone
        ];

        $allSalesSuccessful = true;
        $restoreOfflineAfterRollback = false;
        $startedTransaction = false;
        if (!$conn->inTransaction()) {
            $conn->beginTransaction();
            $startedTransaction = true;
        }
        if (!$isCreditSale && $eisEnabled && $eisOfflineMode) {
            try {
                $eisCompliance = $eisCompliance ?: new MraEisCompliance($conn);
                $eisCompliance->assertOfflineSaleAllowed(
                    $branchId,
                    $userId,
                    $finalTotal,
                    $saleDateTime,
                    $transactionId
                );
            } catch (Throwable $e) {
                $allSalesSuccessful = false;
                $errors[] = $e->getMessage();
            }
        }

        $customerId = null;
        $firstSaleId = null;
        try {
            $customerId = $customers->findOrCreate($postedCustomerId, (string)$customerName, $customerPhone, $buyerTin, $userId);
            $saleData['customer_id'] = $customerId;
        } catch (Throwable $e) {
            $allSalesSuccessful = false;
            $errors[] = $e->getMessage();
        }

        $creditSaleItems = [];
        for ($i = 0; $i < $quantity && $allSalesSuccessful; $i++) {
            try {
                $itemPrice = $originalPrices[$i] ?? $prices[$i];
                $effectivePriceForItem = $allocatedPrices[$i];
                $currentUniqueCode = trim($uniqueCodes[$i]);
                $currentItemName = $itemNames[$i] ?? '';

                $item = $inventory->getItemByUniqueCode($currentUniqueCode);
                if (!$item) {
                    throw new Exception("Item with unique code {$currentUniqueCode} not found");
                }

                if ($sales->isItemSold($currentUniqueCode)) {
                    throw new Exception("Item {$currentItemName} (Code: {$currentUniqueCode}) has already been sold");
                }

                if ($item['current_location_id'] != $branchId) {
                    $locationStmt = $conn->prepare("SELECT branch_name FROM branches WHERE branch_id = ?");
                    $locationStmt->execute([$item['current_location_id']]);
                    $itemBranchName = $locationStmt->fetchColumn();
                    $locationName = $itemBranchName ?: 'another branch';
                    throw new Exception("Item {$currentItemName} (Code: {$currentUniqueCode}) has been transferred to {$locationName} and cannot be sold from this branch");
                }

                $saleSuccess = $sales->createSale(
                    $saleDate,
                    $currentUniqueCode,
                    $itemPrice,
                    $branchId,
                    $userId,
                    $transactionId,
                    $effectivePriceForItem,
                    $customerName,
                    $customerPhone,
                    $vatRelief,
                    $buyerTin,
                    $eisTransactionType,
                    $buyerAuthorizationCode,
                    $vat5CertificateNumber,
                    !$isCreditSale,
                    $isCreditSale ? 'credit' : $paymentMethod,
                    $customerId,
                    $vatRelief ? ($vat5Details ?? null) : null
                );

                if ($firstSaleId === null) {
                    $firstSaleId = (int)$saleSuccess;
                }

                if ($isCreditSale) {
                    $creditSaleItems[] = [
                        'sale_id' => (int)$saleSuccess,
                        'item_id' => (int)$item['item_id'],
                        'unique_code' => $currentUniqueCode,
                        'item_name' => $currentItemName,
                        'unit_price' => $effectivePriceForItem,
                    ];
                }

                if (!$saleSuccess) {
                    $allSalesSuccessful = false;
                    $errors[] = "Failed to record sale for item: {$currentItemName} (Code: {$currentUniqueCode})";
                    break;
                }
            } catch (Exception $e) {
                $allSalesSuccessful = false;
                $errors[] = $e->getMessage();
                break;
            }
        }

        if ($startedTransaction && !$allSalesSuccessful && $conn->inTransaction()) {
            $conn->rollBack();
        }
        if ($allSalesSuccessful && $isCreditSale) {
            try {
                $creditId = $creditSales->createCreditSale([
                    'branch_id' => $branchId,
                    'transaction_id' => $transactionId,
                    'customer_id' => $customerId,
                    'customer_name' => $customerName,
                    'customer_phone' => $customerPhone,
                    'total_amount' => $total,
                    'amount_paid' => $amountPaid,
                    'payment_method' => $paymentMethod,
                    'created_by' => $userId,
                ], $creditSaleItems);
                if ($startedTransaction && $conn->inTransaction()) {
                    $conn->commit();
                }
                $_SESSION['sale_data'] = $saleData;
                header('Location: sale_receipt.php?credit_id=' . (int)$creditId);
                exit();
            } catch (Throwable $e) {
                if ($startedTransaction && $conn->inTransaction()) {
                    $conn->rollBack();
                }
                $allSalesSuccessful = false;
                $errors[] = $e->getMessage();
            }
        }
        if ($allSalesSuccessful) {
            if (!$eisEnabled) {
                $saleData['eis_status'] = 'disabled';
                $saleData['eis_outbox_id'] = null;
                $saleData['eis_acknowledged'] = false;
                $saleData['eis_message'] = 'MRA EIS connection and validation were disabled when this sale was recorded.';
            } else try {
                $eisCompliance = $eisCompliance ?: new MraEisCompliance($conn);
                $eisResult = $eisCompliance->prepareSale($transactionId, $branchId, $userId, [
                    'vat5_certificate_details' => $vat5Details ?? null,
                ]);
                $saleData['eis_status'] = $eisResult['status'] ?? 'pending';
                $saleData['eis_outbox_id'] = $eisResult['id'] ?? null;

                if ($eisOfflineMode && ($eisResult['status'] ?? '') === 'ready' && !empty($eisResult['id'])) {
                    $offlinePayload = json_decode((string)($eisResult['payload_json'] ?? ''), true);
                    $offlineAudit = json_decode((string)($eisResult['local_audit_json'] ?? ''), true);
                    $saleData['eis_status'] = 'offline';
                    $saleData['eis_acknowledged'] = false;
                    $saleData['eis_offline_signature'] = $offlinePayload['invoiceSummary']['offlineSignature'] ?? null;
                    $saleData['eis_offline_qr_data'] = $offlineAudit['offline_receipt_data'] ?? null;
                    $saleData['eis_message'] = 'Offline B2C sale signed and queued. Reconnect MRA EIS to submit it.';
                } elseif (($eisResult['status'] ?? '') === 'ready' && !empty($eisResult['id'])) {
                    $submitResult = $eisCompliance->submitOutbox((int)$eisResult['id'], $userId);
                    $saleData['eis_status'] = !empty($submitResult['success']) ? 'submitted' : (!empty($submitResult['queued']) ? 'queued' : 'failed');
                    $saleData['eis_response'] = $submitResult['body'] ?? null;
                    $saleData['eis_validation_url'] = $submitResult['validation_url'] ?? null;
                    $saleData['eis_acknowledged'] = !empty($submitResult['acknowledged']);
                    if (!empty($submitResult['success'])) {
                        $mraInvoiceNumber = trim((string)($submitResult['mra_reference'] ?? ''));
                        $mraInvoiceSynced = false;
                        if ($mraInvoiceNumber !== '' && $mraInvoiceNumber !== $transactionId) {
                            try {
                                $sales->replaceTransactionId($transactionId, $mraInvoiceNumber, $branchId);
                                if (!empty($saleData['eis_outbox_id'])) {
                                    $conn->prepare('UPDATE mra_eis_outbox SET source_key = :new_key WHERE id = :id AND source_key = :old_key')
                                        ->execute([
                                            ':new_key' => $mraInvoiceNumber,
                                            ':id' => (int)$saleData['eis_outbox_id'],
                                            ':old_key' => $transactionId,
                                        ]);
                                }
                                $transactionId = $mraInvoiceNumber;
                                $saleData['transaction_id'] = $mraInvoiceNumber;
                                $mraInvoiceSynced = true;
                            } catch (Exception $syncException) {
                                error_log('MRA EIS invoice number sync failed for transaction ' . $transactionId . ': ' . $syncException->getMessage());
                            }
                        } elseif ($mraInvoiceNumber !== '') {
                            $mraInvoiceSynced = true;
                        }
                        $saleData['eis_message'] = 'Sale submitted to MRA EIS successfully.';
                        if ($mraInvoiceSynced) {
                            $saleData['eis_message'] .= ' MRA EIS invoice number: ' . $mraInvoiceNumber . '.';
                        } elseif ($mraInvoiceNumber !== '') {
                            $saleData['eis_message'] .= ' MRA EIS returned invoice number ' . $mraInvoiceNumber . ', but the local transaction ID could not be updated.';
                        }
                    } elseif (!empty($submitResult['queued'])) {
                        $eisOfflineStatus = $eisCompliance->offlineStatusForSale($branchId, $userId);
                        if (($eisOfflineStatus['connection_status'] ?? '') === 'offline') {
                            $eisOfflineMode = true;
                            $restoreOfflineAfterRollback = true;
                            $eisCompliance->assertOfflineSaleAllowed(
                                $branchId,
                                $userId,
                                $finalTotal,
                                $saleDateTime,
                                $transactionId
                            );
                            $eisResult = $eisCompliance->prepareSale($transactionId, $branchId, $userId, [
                                'vat5_certificate_details' => $vat5Details ?? null,
                            ]);
                            $offlinePayload = json_decode((string)($eisResult['payload_json'] ?? ''), true);
                            $offlineAudit = json_decode((string)($eisResult['local_audit_json'] ?? ''), true);
                            $saleData['eis_status'] = 'offline';
                            $saleData['eis_offline_signature'] = $offlinePayload['invoiceSummary']['offlineSignature'] ?? null;
                            $saleData['eis_offline_qr_data'] = $offlineAudit['offline_receipt_data'] ?? null;
                        }
                        $saleData['eis_message'] = $submitResult['message'] ?? 'MRA EIS is not available right now. The sale has been saved in the EIS outbox and can be submitted later.';
                    } elseif ((int)($submitResult['status'] ?? 0) === 401) {
                        $saleData['eis_message'] = 'Sale recorded, but MRA EIS rejected the selected terminal token/signature. Check that the sale product site, branch terminal, and activated terminal token match.';
                    } else {
                        $submissionMessage = trim((string)($submitResult['message'] ?? ''));
                        $responseSummary = trim(strip_tags((string)($submitResult['body'] ?? '')));
                        $responseSummary = preg_replace('/\s+/', ' ', $responseSummary);
                        if (strlen($responseSummary) > 220) {
                            $responseSummary = substr($responseSummary, 0, 220) . '...';
                        }
                        $saleData['eis_message'] = $submissionMessage !== ''
                            ? $submissionMessage
                            : 'Sale recorded, but MRA EIS submission failed with HTTP ' . ($submitResult['status'] ?? 0) . '.'
                                . ($responseSummary !== '' ? ' MRA response: ' . $responseSummary : '');
                    }
                } elseif (($eisResult['status'] ?? '') === 'submitted') {
                    $saleData['eis_status'] = 'submitted';
                    $saleData['eis_validation_url'] = $eisResult['validation_url'] ?? null;
                    $saleData['eis_acknowledged'] = filter_var((string)($eisResult['validation_url'] ?? ''), FILTER_VALIDATE_URL) !== false;
                    $saleData['eis_message'] = 'This sale was already submitted to MRA EIS; the existing acknowledgement was reused.';
                } else {
                    $saleData['eis_message'] = $eisResult['last_error'] ?? 'Sale recorded, but EIS preparation needs attention.';
                }

                if (
                    $eisTransactionType === 'B2B'
                    && (
                        ($saleData['eis_status'] ?? '') !== 'submitted'
                        || empty($saleData['eis_acknowledged'])
                    )
                ) {
                    $mraFailure = trim((string)($saleData['eis_message'] ?? ''));
                    throw new RuntimeException(
                        ($mraFailure !== '' ? $mraFailure . ' ' : '')
                        . 'MRA EIS did not acknowledge the B2B transaction. The local sale was cancelled.'
                    );
                }
            } catch (Throwable $e) {
                error_log('MRA EIS sale preparation/submission failed for transaction ' . $transactionId . ': ' . $e->getMessage());
                $saleData['eis_status'] = 'failed';
                $saleData['eis_outbox_id'] = null;
                $terminalBlocked = stripos($e->getMessage(), 'terminal is blocked') !== false
                    || stripos($e->getMessage(), 'has blocked this terminal') !== false;
                // $eisOfflineMode is a page-load snapshot; prepareSale() re-checks live
                // connectivity/threshold state internally, so a terminal that looked
                // online when the form was rendered can still throw an offline-threshold
                // violation here. Re-probe live status instead of trusting the stale
                // flag, or an expired-threshold sale would be silently downgraded to a
                // warning and still commit.
                $liveOfflineMode = $eisOfflineMode;
                if (!$liveOfflineMode && $eisEnabled && $eisCompliance) {
                    try {
                        $liveStatus = $eisCompliance->offlineStatusForSale($branchId, $userId);
                        $liveOfflineMode = ($liveStatus['connection_status'] ?? '') === 'offline';
                    } catch (Throwable $statusError) {
                        error_log('Unable to re-check MRA EIS offline status after preparation failure: ' . $statusError->getMessage());
                    }
                }
                if ($eisTransactionType === 'B2B' || $terminalBlocked || $liveOfflineMode) {
                    $allSalesSuccessful = false;
                    $errors[] = ($eisTransactionType === 'B2B' ? 'B2B sale cancelled: ' : 'Sale cancelled: ') . $e->getMessage();
                } else {
                    $saleData['eis_message'] = 'Sale recorded, but MRA EIS submission failed: ' . $e->getMessage();
                }
            }

            if ($startedTransaction && $conn->inTransaction()) {
                if ($allSalesSuccessful) {
                    if (!$isCreditSale && $eisEnabled && $eisOfflineMode) {
                        $eisCompliance->recordOfflineSaleAccepted($branchId, $userId, $transactionId);
                    }
                    $customers->recordInvoice((int)$customerId, (int)$branchId, 'sale', (string)$transactionId, (string)$transactionId, null, $firstSaleId, (float)$saleData['total'], (int)$userId, 'Sales invoice');
                    $customers->recordPayment((int)$customerId, (int)$branchId, 'sale', (string)$transactionId, (string)$transactionId, null, $firstSaleId, min((float)$saleData['amount_paid'], (float)$saleData['total']), (string)$paymentMethod, (int)$userId, 'Sale payment');
                    $conn->commit();
                } else {
                    $conn->rollBack();
                    if ($restoreOfflineAfterRollback && $eisCompliance) {
                        try {
                            $eisCompliance->preserveOfflinePeriodAfterRollback($branchId, $userId);
                            $eisOfflineStatus = $eisCompliance->offlineStatusForSale($branchId, $userId);
                        } catch (Throwable $offlineStateError) {
                            error_log('Unable to preserve MRA EIS offline state after sale rollback: ' . $offlineStateError->getMessage());
                        }
                    }
                }
            }

            if ($allSalesSuccessful) {
                $_SESSION['sale_data'] = $saleData;
                header('Location: sale_receipt.php');
                exit();
            }
        }
    }
}

$branchId = $auth->getUserBranch($_SESSION['user_id']);

if (!isset($inventory)) {
    $inventory = new Inventory($conn, $logger);
}

$stmt = $conn->prepare("SELECT branch_name FROM branches WHERE branch_id = ?");
$stmt->execute([$branchId]);
$branchName = $stmt->fetchColumn();
$recentSales = $sales->getRecentBranchTransactions($branchId, 10);

$itemType = isset($_GET['item_type']) ? $_GET['item_type'] : 'simple';
$searchTerm = isset($_GET['search_term']) ? trim($_GET['search_term']) : '';
$searchField = isset($_GET['search_field']) ? $_GET['search_field'] : 'item_name';

function getItems($inventory, $conn, $branchId, $itemType, $searchTerm, $searchField) {
    $hasSearch = !empty($searchTerm) && !empty($searchField);

    try {
        return $hasSearch
            ? $inventory->searchDetailedItems($branchId, $searchField, $searchTerm)
            : $inventory->getDetailedItems($branchId);
    } catch (PDOException $e) {
        // Do not blank the POS while optional inventory migrations are pending.
        if ($e->getCode() !== '42S22') {
            throw $e;
        }
        error_log('Sale stock list is using the legacy item schema: ' . $e->getMessage());
        return [];
    }
}

$items = getItems($inventory, $conn, $branchId, $itemType, $searchTerm, $searchField);

function getSearchFieldOptions($itemType, $currentField) {
    $commonOptions = [
        'unique_id' => 'Unique Code',
        'item_name' => 'Item Name',
        'item_details' => 'Item Details',
        'unit_price' => 'Price'
    ];

    $detailedOptions = [
        'serial_number' => 'Serial Number',
        'technical_specs' => 'Technical Specs'
    ];

    $options = array_merge($commonOptions, $detailedOptions);

    $html = '';
    foreach ($options as $value => $label) {
        $selected = $currentField === $value ? 'selected' : '';
        $html .= "<option value=\"{$value}\" {$selected}>{$label}</option>";
    }

    return $html;
}

function getTableHeaders($itemType) {
    return ['Unique Code', 'Item Name', 'Item Details', 'Price', 'Serial Number', 'Technical Specs'];
}

function generateTableRow($item, $itemType) {
    $html = '<tr>';
    $html .= '<td>' . htmlspecialchars($item['unique_id'] ?? 'N/A') . '</td>';
    $html .= '<td>' . htmlspecialchars($item['item_name'] ?? 'N/A') . '</td>';
    $html .= '<td>' . htmlspecialchars(trim((string)($item['item_details'] ?? '')) ?: 'N/A') . '</td>';
    $html .= '<td>' . htmlspecialchars(isset($item['unit_price']) ? number_format((float)$item['unit_price'], 2) : 'N/A') . '</td>';
    $html .= '<td>' . htmlspecialchars($item['serial_number'] ?? 'N/A') . '</td>';
    $html .= '<td>' . htmlspecialchars($item['technical_specs'] ?? 'N/A') . '</td>';
    $html .= '</tr>';
    return $html;
}
?>
<?php include __DIR__ . '/../../includes/header.php'; ?>
    <style>
        /* ── Google Font ─────────────────────────────── */
        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap');

        /* ── Design Tokens ───────────────────────────── */
        *, *::before, *::after { box-sizing: border-box; }
        :root {
            /* Brand — indigo */
            --brand:          #4F46E5;
            --brand-dark:     #3730A3;
            --brand-light:    #EEF2FF;
            --brand-ring:     rgba(79,70,229,.18);

            /* Semantic */
            --success:        #059669;
            --success-bg:     #ECFDF5;
            --success-border: #A7F3D0;
            --success-ring:   rgba(5,150,105,.18);
            --danger:         #DC2626;
            --danger-bg:      #FEF2F2;
            --danger-border:  #FECACA;
            --warning:        #D97706;
            --warning-bg:     #FFFBEB;
            --warning-border: #FDE68A;
            --info:           #0284C7;
            --info-bg:        #E0F2FE;

            /* Neutrals — slate scale */
            --n900: #0F172A;
            --n800: #1E293B;
            --n700: #334155;
            --n600: #475569;
            --n500: #64748B;
            --n400: #94A3B8;
            --n300: #CBD5E1;
            --n200: #E2E8F0;
            --n100: #F1F5F9;
            --n50:  #F8FAFC;
            --white: #FFFFFF;

            /* Layout */
            --topbar-h: 58px;
            --r-sm:  6px;
            --r:     10px;
            --r-lg:  14px;
            --s1: 0 1px 2px rgba(0,0,0,.05);
            --s2: 0 1px 3px rgba(0,0,0,.07), 0 1px 2px rgba(0,0,0,.04);
            --s3: 0 4px 6px -1px rgba(0,0,0,.07), 0 2px 4px -1px rgba(0,0,0,.04);
        }

        html, body {
            height: 100%; margin: 0;
            font-family: 'Inter', system-ui, -apple-system, sans-serif;
            font-size: 16px; line-height: 1.5;
            color: var(--n800);
            background: var(--n100);
            -webkit-font-smoothing: antialiased;
        }

        /* ── Top Bar ────────────────────────────────── */
        .pos-topbar {
            display: flex; align-items: center; gap: 0;
            background: var(--n900); color: var(--white);
            height: var(--topbar-h);
            position: sticky; top: 0; z-index: 300; flex-shrink: 0;
            border-bottom: 3px solid var(--brand);
        }
        .pos-topbar-brand {
            display: flex; align-items: center; gap: 10px;
            padding: 0 20px; height: 100%;
            border-right: 1px solid rgba(255,255,255,.08);
            flex-shrink: 0;
        }
        .pos-topbar-brand .brand-icon {
            width: 32px; height: 32px; border-radius: var(--r-sm);
            background: var(--brand); display: flex; align-items: center;
            justify-content: center; font-size: 14px; color: #fff; flex-shrink: 0;
        }
        .pos-topbar-brand .brand-text { line-height: 1.2; }
        .pos-topbar-brand .brand-name  { font-size: .78rem; font-weight: 700; color: var(--white); display: block; }
        .pos-topbar-brand .brand-sub   { font-size: .67rem; color: var(--n400); display: block; }
        .pos-topbar-center { flex: 1; display: flex; align-items: center; padding: 0 16px; overflow: hidden; }
        .pos-topbar-center .pos-title {
            font-size: .88rem; font-weight: 600; color: var(--n300);
            overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
        }
        .pos-topbar-right {
            display: flex; align-items: center; gap: 10px;
            padding: 0 16px; flex-shrink: 0; height: 100%;
        }
        .pos-topbar .badge { font-size: .67rem; font-weight: 600; letter-spacing: .03em; padding: 3px 8px; border-radius: 20px; }
        .pos-topbar .pos-user-chip {
            display: flex; align-items: center; gap: 7px;
            background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.1);
            border-radius: 20px; padding: 4px 10px 4px 4px;
        }
        .pos-topbar .pos-user-avatar {
            width: 24px; height: 24px; border-radius: 50%;
            background: var(--brand); color: #fff;
            display: flex; align-items: center; justify-content: center;
            font-size: .68rem; font-weight: 700; flex-shrink: 0;
        }
        .pos-topbar .pos-user-name { font-size: .75rem; color: var(--n300); }
        .pos-topbar .pos-back {
            display: flex; align-items: center; gap: 6px;
            color: var(--n400); text-decoration: none; font-size: .78rem; font-weight: 500;
            padding: 6px 12px; border-radius: var(--r-sm);
            border: 1px solid rgba(255,255,255,.1);
            transition: all .15s; white-space: nowrap;
        }
        .pos-topbar .pos-back:hover { background: rgba(255,255,255,.08); color: var(--white); border-color: rgba(255,255,255,.2); }

        /* ── App Shell ──────────────────────────────── */
        .pos-app { display: flex; flex-direction: column; min-height: 100vh; }
        .pos-alerts { padding: 10px 14px 0; }
        .pos-alerts .alert { margin-bottom: 6px; font-size: .85rem; border-radius: var(--r); }

        /* ── Main Split ─────────────────────────────── */
        .pos-main { display: flex; flex: 1; min-height: 0; }

        /* ════════════════════════════════════════════
           CART PANEL — LEFT (58%)
           ════════════════════════════════════════════ */
        .pos-cart-panel {
            flex: 0 0 58%;
            display: flex; flex-direction: column;
            background: var(--white);
            border-right: 1px solid var(--n200);
            min-height: calc(100vh - var(--topbar-h));
        }
        .pos-cart-header {
            display: flex; align-items: center; justify-content: space-between;
            padding: 12px 18px; border-bottom: 1px solid var(--n200);
            background: var(--n50); gap: 12px; flex-shrink: 0;
        }
        .pos-cart-header-left { display: flex; align-items: center; gap: 10px; }
        .pos-cart-header h2 {
            margin: 0; font-size: .92rem; font-weight: 700;
            color: var(--n800); letter-spacing: -.01em;
        }
        .pos-cart-count {
            background: var(--brand-light); color: var(--brand);
            font-size: .67rem; font-weight: 700;
            padding: 2px 7px; border-radius: 20px;
        }
        .pos-mode-toggle {
            display: flex; background: var(--n200); border-radius: var(--r-sm);
            padding: 3px; gap: 2px;
        }
        .pos-mode-toggle .btn {
            padding: 5px 12px; font-size: .75rem; font-weight: 600;
            border-radius: 4px; border: none; background: transparent;
            color: var(--n500); transition: all .15s;
        }
        .pos-mode-toggle .btn.active, .pos-mode-toggle .btn.btn-primary {
            background: var(--white); color: var(--n800);
            box-shadow: 0 1px 3px rgba(0,0,0,.12);
        }
        .pos-mode-toggle .btn.btn-outline-success { background: transparent; color: var(--n500); border: none; }
        .pos-mode-toggle .btn.btn-success { background: var(--white); color: var(--success); box-shadow: 0 1px 3px rgba(0,0,0,.12); }

        /* ── Items list ─────────────────────────────── */
        .pos-items-list { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; }

        /* ── Empty cart state ───────────────────────── */
        .cart-empty {
            display: flex; flex-direction: column; align-items: center;
            justify-content: center; padding: 48px 24px; color: var(--n400);
        }
        .cart-empty-icon {
            width: 64px; height: 64px; border-radius: 50%;
            background: var(--n100); display: flex; align-items: center;
            justify-content: center; font-size: 1.6rem; margin-bottom: 14px; color: var(--n300);
        }
        .cart-empty p { margin: 0; font-size: .88rem; text-align: center; }

        /* ── Cart item row ──────────────────────────── */
        .item-row {
            display: flex; align-items: flex-start; gap: 10px;
            padding: 12px 18px; border-bottom: 1px solid var(--n100);
            transition: background .12s;
        }
        .item-row:hover { background: #FAFBFF; }
        .item-row-num {
            flex-shrink: 0; width: 24px; height: 24px;
            background: var(--brand-light); color: var(--brand);
            border-radius: 50%; display: flex; align-items: center;
            justify-content: center; font-size: .67rem; font-weight: 800;
            margin-top: 10px; letter-spacing: 0;
        }
        .item-row-fields { flex: 1; min-width: 0; }
        .item-row-code-wrap { display: flex; gap: 6px; margin-bottom: 6px; align-items: center; }

        /* Inputs */
        .form-control {
            border-color: var(--n300); border-radius: var(--r-sm);
            font-family: 'Inter', system-ui, sans-serif; font-size: .88rem;
            color: var(--n800); transition: border-color .15s, box-shadow .15s;
        }
        .form-control:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-ring); outline: none; }

        .unique-code-input, .barcode-input {
            font-family: 'JetBrains Mono', 'Fira Code', monospace;
            font-size: .85rem; letter-spacing: .04em;
            border-color: var(--n300); min-height: 42px; border-radius: var(--r-sm);
            background: var(--white);
        }
        .unique-code-input:focus, .barcode-input:focus {
            border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-ring);
        }
        .barcode-input {
            background: #F0F4FF !important;
            border-color: #A5B4FC !important;
        }
        .is-valid.unique-code-input, .is-valid.barcode-input {
            border-color: var(--success) !important;
            background-image: none !important;
        }
        .is-invalid.unique-code-input, .is-invalid.barcode-input {
            border-color: var(--danger) !important;
            background-image: none !important;
        }
        .scanner-indicator {
            font-size: .67rem; font-weight: 600; letter-spacing: .04em;
            color: var(--info); background: var(--info-bg);
            padding: 3px 8px; border-radius: 20px; white-space: nowrap; flex-shrink: 0;
        }
        .item-name-input {
            background: var(--n50) !important; border-color: var(--n200) !important;
            font-size: .85rem; color: var(--n700); min-height: 36px;
            font-style: italic;
        }
        .item-name-input:not([value=""]):not([placeholder-shown]) { font-style: normal; font-weight: 500; }
        .lookup-feedback { font-size: .75rem; color: var(--danger); min-height: .9rem; margin-top: 2px; }
        .item-details-input {
            margin-top: 4px; min-height: 32px; background: #fff !important;
            border-color: var(--n200) !important; color: var(--n500);
            font-size: .76rem;
        }
        .item-row-price { flex-shrink: 0; width: 108px; }
        .price-input {
            font-weight: 700; font-size: .95rem; text-align: right;
            min-height: 42px; border-color: var(--n300); border-radius: var(--r-sm);
            letter-spacing: -.02em;
        }
        .price-input:focus { border-color: var(--success); box-shadow: 0 0 0 3px var(--success-ring); }
        .tax-group-badge {
            display: block; text-align: right; margin-top: 3px;
            font-size: .64rem; font-weight: 700; letter-spacing: .03em;
            color: var(--n400); min-height: 12px;
        }
        .tax-group-badge:not(:empty)::before { content: 'VAT '; font-weight: 500; opacity: .7; }
        .tax-group-badge.tax-zero { color: var(--success); }
        .tax-group-badge.tax-zero::before { content: ''; }
        .tax-group-badge.tax-zero::after { content: ' (0%)'; }
        .btn-remove-item {
            flex-shrink: 0; width: 36px; height: 36px;
            border: 1px solid var(--danger-border); background: var(--danger-bg);
            color: var(--danger); border-radius: var(--r-sm);
            display: flex; align-items: center; justify-content: center;
            font-size: .8rem; margin-top: 3px; cursor: pointer;
            transition: background .12s, border-color .12s;
            padding: 0; line-height: 1;
        }
        .btn-remove-item:hover { background: #FEE2E2; border-color: #F87171; }

        /* ── Add bar ────────────────────────────────── */
        .pos-add-bar {
            display: flex; align-items: stretch; gap: 8px;
            padding: 12px 18px; border-bottom: 1px solid var(--n200);
            background: var(--n50); flex-shrink: 0;
        }
        .btn-add-item {
            flex: 1; min-height: 46px; font-size: .88rem; font-weight: 600;
            border-radius: var(--r-sm); letter-spacing: -.01em;
        }
        .btn-browse {
            min-height: 46px; padding: 0 16px; border-radius: var(--r-sm);
            white-space: nowrap; font-weight: 500; font-size: .85rem;
        }

        /* ════════════════════════════════════════════
           PAYMENT PANEL — RIGHT (42%)
           ════════════════════════════════════════════ */
        .pos-pay-panel {
            flex: 0 0 42%; background: var(--n100);
            overflow-y: auto; -webkit-overflow-scrolling: touch;
        }
        .pos-pay-inner { padding: 14px 12px; display: flex; flex-direction: column; gap: 10px; }

        /* ── Totals card ────────────────────────────── */
        .pos-totals-card {
            background: linear-gradient(135deg, var(--n900) 0%, var(--n800) 100%);
            border-radius: var(--r-lg); padding: 16px 18px;
            border: 1px solid rgba(255,255,255,.05);
            box-shadow: 0 8px 24px rgba(15,23,42,.18);
            position: relative; overflow: hidden;
        }
        .pos-totals-card::before {
            content: ''; position: absolute;
            top: -30px; right: -30px;
            width: 120px; height: 120px; border-radius: 50%;
            background: radial-gradient(circle, rgba(79,70,229,.25) 0%, transparent 70%);
            pointer-events: none;
        }
        .pos-total-row {
            display: flex; justify-content: space-between; align-items: center;
            font-size: .8rem; color: var(--n400); margin-bottom: 4px;
            font-weight: 500;
        }
        .pos-total-row span:last-child { font-variant-numeric: tabular-nums; }
        .pos-total-divider {
            height: 1px; background: rgba(255,255,255,.08);
            margin: 10px 0;
        }
        .pos-total-grand {
            display: flex; justify-content: space-between; align-items: baseline;
        }
        .pos-total-label {
            font-size: .75rem; font-weight: 700; color: var(--n400);
            text-transform: uppercase; letter-spacing: .08em;
        }
        .pos-total-amount {
            font-size: 2.1rem; font-weight: 900; color: var(--white);
            letter-spacing: -.03em; font-variant-numeric: tabular-nums;
        }

        /* ── Section card ───────────────────────────── */
        .pos-card {
            background: var(--white); border-radius: var(--r);
            padding: 14px 16px; box-shadow: var(--s2);
            border: 1px solid var(--n200);
        }
        .pos-card-title {
            display: flex; align-items: center; gap: 6px;
            font-size: .68rem; font-weight: 700;
            text-transform: uppercase; letter-spacing: .08em;
            color: var(--n400); margin-bottom: 10px;
        }
        .pos-card-title i { font-size: .75rem; }

        /* ── Customer card inputs ───────────────────── */
        #customer_name, #customer_phone {
            min-height: 44px; font-size: .88rem;
            border-radius: var(--r-sm); border-color: var(--n300);
            font-weight: 500;
        }
        #customer_name { margin-bottom: 8px; }
        #customerSearchResults {
            border-radius: var(--r-sm); border: 1px solid var(--n200);
            box-shadow: 0 8px 24px rgba(0,0,0,.12); max-height: 220px; overflow-y: auto;
            background: var(--white);
        }
        #customerSearchResults .list-group-item {
            padding: 10px 14px; font-size: .85rem; cursor: pointer;
            border-left: none; border-right: none; font-weight: 500;
            color: var(--n700); transition: background .1s;
        }
        #customerSearchResults .list-group-item:first-child { border-top: none; border-radius: var(--r-sm) var(--r-sm) 0 0; }
        #customerSearchResults .list-group-item:last-child { border-bottom: none; border-radius: 0 0 var(--r-sm) var(--r-sm); }
        #customerSearchResults .list-group-item:hover { background: var(--brand-light); color: var(--brand); }

        /* ── EIS row ────────────────────────────────── */
        .pos-eis-row { display: flex; gap: 8px; align-items: center; }
        .pos-eis-row select { flex: 1; min-height: 42px; border-radius: var(--r-sm); font-size: .85rem; font-weight: 500; }
        .pos-vat-label {
            display: flex; align-items: center; gap: 7px; cursor: pointer;
            font-size: .82rem; font-weight: 600; color: var(--n600); white-space: nowrap;
            user-select: none;
        }
        .pos-vat-label input[type=checkbox] {
            width: 17px; height: 17px; cursor: pointer;
            accent-color: var(--brand);
        }
        #buyerBusinessFields { margin-top: 10px; border-top: 1px solid var(--n100); padding-top: 10px; }
        #buyerBusinessFields label { font-size: .75rem; font-weight: 600; color: var(--n500); margin-bottom: 4px; display: block; }
        #buyerBusinessFields input { min-height: 42px; border-radius: var(--r-sm); font-size: .85rem; margin-bottom: 8px; }

        /* ── Sale mode ──────────────────────────────── */
        .pos-salemode-btns {
            display: flex; gap: 0;
            background: var(--n100); border: 1px solid var(--n200);
            border-radius: var(--r-sm); padding: 3px; overflow: hidden;
        }
        .pos-salemode-btn {
            flex: 1; min-height: 42px; font-size: .82rem; font-weight: 600;
            border: none; border-radius: 5px;
            background: transparent; color: var(--n500); cursor: pointer;
            transition: all .2s; letter-spacing: -.01em;
            display: flex; align-items: center; justify-content: center; gap: 6px;
        }
        .pos-salemode-btn i { font-size: .85rem; }
        .pos-salemode-btn.active-cash {
            background: var(--white); color: var(--success);
            box-shadow: 0 1px 4px rgba(0,0,0,.1); font-weight: 700;
        }
        .pos-salemode-btn.active-credit {
            background: var(--white); color: var(--warning);
            box-shadow: 0 1px 4px rgba(0,0,0,.1); font-weight: 700;
        }

        /* ── Payment method grid ────────────────────── */
        .pay-method-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px; }
        .pay-method-btn {
            min-height: 56px; border: 1.5px solid var(--n200);
            border-radius: var(--r-sm); background: var(--n50); color: var(--n500);
            font-size: .75rem; font-weight: 600; cursor: pointer;
            transition: all .15s; display: flex; flex-direction: column;
            align-items: center; justify-content: center; gap: 4px;
            padding: 6px 4px; letter-spacing: -.01em; line-height: 1.2;
        }
        .pay-method-btn i { font-size: 1.05rem; }
        .pay-method-btn:hover:not(.selected) { border-color: var(--brand); color: var(--brand); background: var(--brand-light); }
        .pay-method-btn.selected {
            border-color: var(--brand); background: var(--brand-light);
            color: var(--brand); font-weight: 700;
            box-shadow: 0 0 0 3px var(--brand-ring);
        }

        /* ── Discount ───────────────────────────────── */
        .pos-discount-row { display: flex; gap: 8px; align-items: flex-end; }
        .pos-discount-row select, .pos-discount-row input { min-height: 42px; border-radius: var(--r-sm); font-size: .85rem; }
        .pos-discount-row .form-group { flex: 1; margin: 0; }
        #discountInfo {
            font-size: .82rem; color: var(--success); font-weight: 600;
            padding: 5px 0; display: flex; align-items: center; gap: 4px;
        }

        /* ── Amount paid ────────────────────────────── */
        #amount_paid {
            min-height: 68px; font-size: 1.6rem; font-weight: 800;
            border-radius: var(--r); text-align: right; padding-right: 16px;
            border: 2px solid var(--success); letter-spacing: -.03em;
            font-variant-numeric: tabular-nums;
            background: var(--success-bg);
        }
        #amount_paid::placeholder { color: var(--n300); font-weight: 400; }
        #amount_paid:focus {
            border-color: var(--brand); background: var(--white);
            box-shadow: 0 0 0 3px var(--brand-ring);
        }
        #minAmountInfo { font-size: .75rem; color: var(--n400); padding: 4px 0; font-weight: 500; }
        #changeInfo {
            background: var(--success-bg); border: 1.5px solid var(--success-border);
            border-radius: var(--r-sm); padding: 10px 14px; margin-top: 8px;
            display: flex; justify-content: space-between; align-items: center;
        }
        #changeInfo .lbl { font-weight: 700; color: var(--success); font-size: .82rem; display: flex; align-items: center; gap: 6px; }
        #changeInfo .val { font-size: 1.2rem; font-weight: 800; color: var(--success); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
        #errorInfo {
            background: var(--danger-bg); border: 1.5px solid var(--danger-border);
            border-radius: var(--r-sm); padding: 10px 14px; margin-top: 8px;
            color: var(--danger); font-size: .82rem; font-weight: 500;
            display: flex; align-items: flex-start; gap: 6px;
        }
        #vatRecalcInfo { font-size: .75rem; color: var(--brand); padding: 4px 0; font-weight: 500; }
        .vat-recalculated { color: var(--brand) !important; font-weight: 700 !important; }

        /* ── Record Sale CTA ────────────────────────── */
        #recordSaleBtn {
            min-height: 66px; font-size: 1rem; font-weight: 800;
            letter-spacing: .02em; border-radius: var(--r);
            border: none; color: var(--white);
            background: linear-gradient(135deg, var(--success) 0%, #047857 100%);
            box-shadow: 0 4px 14px rgba(5,150,105,.35);
            transition: opacity .15s, transform .12s, box-shadow .15s;
        }
        #recordSaleBtn:not(:disabled):hover {
            opacity: .94; transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(5,150,105,.45);
        }
        #recordSaleBtn:not(:disabled):active { transform: translateY(0); box-shadow: 0 2px 8px rgba(5,150,105,.3); }
        #recordSaleBtn:disabled {
            background: linear-gradient(135deg, var(--n300), var(--n400));
            box-shadow: none; cursor: not-allowed; opacity: 1;
        }

        /* ── Recent sales panel ─────────────────────── */
        .pos-recent {
            background: var(--white); margin: 14px 12px;
            border-radius: var(--r); box-shadow: var(--s2);
            border: 1px solid var(--n200); overflow: hidden;
        }
        .pos-recent-header {
            display: flex; align-items: center; justify-content: space-between;
            padding: 12px 16px; border-bottom: 1px solid var(--n200);
            background: var(--n50);
        }
        .pos-recent-header h2 {
            margin: 0; font-size: .85rem; font-weight: 700; color: var(--n700);
            display: flex; align-items: center; gap: 7px;
        }
        .pos-recent .table { margin: 0; font-size: .8rem; }
        .pos-recent .table thead th {
            background: var(--n800); color: var(--white);
            white-space: nowrap; font-size: .72rem; font-weight: 600;
            letter-spacing: .04em; text-transform: uppercase; border: none;
        }
        .pos-recent .table tbody td { vertical-align: middle; border-color: var(--n100); }
        .pos-recent .table tbody tr:hover { background: #F5F7FF; }

        /* ── Stock DataTable modal ───────────────────── */
        .dataTables_wrapper .row { margin: 0; }
        .dataTables_wrapper .dataTables_filter,
        .dataTables_wrapper .dataTables_length { padding: 10px 14px; }
        .dataTables_wrapper .dataTables_filter input { min-height: 36px; border-radius: var(--r-sm); }
        .dataTables_wrapper .table thead th {
            background: var(--n800); color: var(--white);
            white-space: nowrap; font-size: .78rem; border: none;
        }
        .dataTables_wrapper .table tbody tr { cursor: pointer; }
        .dataTables_wrapper .table tbody tr:hover { background: var(--brand-light); }

        /* ── EIS badges ─────────────────────────────── */
        .eis-badge {
            font-size: .67rem; font-weight: 600; padding: 2px 7px;
            border-radius: 20px; white-space: nowrap; letter-spacing: .02em;
        }
        .eis-badge-submitted { background:#DCFCE7; color:#166534; }
        .eis-badge-queued    { background:#FEF9C3; color:#854D0E; }
        .eis-badge-failed    { background:#FEE2E2; color:#991B1B; }
        .eis-badge-offline   { background:#DBEAFE; color:#1E40AF; }
        .eis-badge-disabled  { background:var(--n100); color:var(--n500); }
        .eis-badge-pending   { background:#FEF9C3; color:#854D0E; }
        .eis-badge-unknown   { background:var(--n100); color:var(--n500); }
        .eis-action-btn { font-size: .72rem; padding: 3px 9px; border-radius: var(--r-sm); font-weight: 500; }
        .eis-validation-link { font-size: .68rem; display: block; margin-top: 2px; color: var(--brand); }
        .eis-error-tip { font-size: .67rem; color: var(--danger); display: block; max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 1px; }

        /* ── Modal polish ───────────────────────────── */
        .modal-content { border: none; border-radius: var(--r-lg); overflow: hidden; box-shadow: 0 20px 60px rgba(0,0,0,.18); }
        .modal-header { border-bottom: 1px solid var(--n100); padding: 16px 20px; }
        .modal-footer { border-top: 1px solid var(--n100); padding: 12px 20px; }
        .modal-title { font-size: .95rem; font-weight: 700; }
        .modal-body { padding: 20px; }

        /* ── Responsive ─────────────────────────────── */
        @media (max-width: 860px) {
            .pos-main { flex-direction: column; }
            .pos-cart-panel { flex: none; width: 100%; min-height: auto; border-right: none; border-bottom: 1px solid var(--n200); }
            .pos-items-list { max-height: 52vh; }
            .pos-pay-panel { flex: none; width: 100%; overflow-y: visible; }
            .pay-method-grid { grid-template-columns: repeat(3, 1fr); }
            .pos-total-amount { font-size: 1.7rem; }
        }
        @media (max-width: 520px) {
            .pos-topbar-brand .brand-text { display: none; }
            .pos-topbar .pos-user-name { display: none; }
            .pos-items-list { max-height: 42vh; }
            .pay-method-grid { grid-template-columns: repeat(2, 1fr); }
            .pos-total-amount { font-size: 1.5rem; }
            #amount_paid { font-size: 1.3rem; min-height: 58px; }
        }
        .hidden { display: none !important; }

        /* ── Scrollbar polish ───────────────────────── */
        .pos-items-list::-webkit-scrollbar,
        .pos-pay-panel::-webkit-scrollbar { width: 5px; }
        .pos-items-list::-webkit-scrollbar-track,
        .pos-pay-panel::-webkit-scrollbar-track { background: transparent; }
        .pos-items-list::-webkit-scrollbar-thumb,
        .pos-pay-panel::-webkit-scrollbar-thumb { background: var(--n200); border-radius: 3px; }
        .pos-items-list::-webkit-scrollbar-thumb:hover,
        .pos-pay-panel::-webkit-scrollbar-thumb:hover { background: var(--n300); }
    </style>
<div class="pos-app">

    <!-- ── Stock Browse Modal ─────────────────────────── -->
    <div class="modal fade" id="modal_stock" tabindex="-1" role="dialog">
        <div class="modal-dialog modal-xl" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Branch Stock</h5>
                    <button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <table class="table table-bordered table-sm" id="example3" width="100%" cellspacing="0">
                        <thead>
                            <tr><th>Code</th><th>Name</th><th>Item Details</th><th>Price</th><th>S/N</th><th>Specs</th></tr>
                        </thead>
                        <tbody>
                            <?php if ($items && count($items) > 0): ?>
                                <?php foreach ($items as $item): echo generateTableRow($item, $itemType); endforeach; ?>
                            <?php else: ?>
                                <tr><td colspan="6" class="text-center">No items found</td></tr>
                            <?php endif; ?>
                        </tbody>
                    </table>
                    <div id="stockLookupError" class="alert alert-danger mt-3 d-none" role="alert"></div>
                </div>
            </div>
        </div>
    </div>

    <!-- ── EIS Modals ────────────────────────────────── -->
    <?php if ($eisEnabled): ?>
    <div class="modal fade" id="eisCancelModal" tabindex="-1" role="dialog">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Cancel EIS Receipt</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <p>Voiding receipt <strong id="cancelTxnDisplay"></strong>.</p>
                    <p class="text-muted small">MRA will review the request. Approval is not immediate.</p>
                    <div class="form-group">
                        <label for="cancelReason">Reason <span class="text-danger">*</span></label>
                        <textarea class="form-control" id="cancelReason" rows="3" maxlength="500" placeholder="Enter reason"></textarea>
                        <div class="invalid-feedback" id="cancelReasonError">A reason is required.</div>
                    </div>
                    <div id="cancelModalResult" class="alert d-none mt-2" role="alert"></div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                    <button type="button" class="btn btn-danger" id="confirmCancelBtn">Submit Cancellation</button>
                </div>
            </div>
        </div>
    </div>
    <div class="modal fade" id="eisRecallModal" tabindex="-1" role="dialog">
        <div class="modal-dialog modal-lg" role="document">
            <div class="modal-content">
                <div class="modal-header bg-info text-white">
                    <h5 class="modal-title">Recall / Adjust Invoice</h5>
                    <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <p class="mb-2 text-muted small">Adjusting <strong id="rcInvoiceRef"></strong>. Enter corrected quantities.</p>
                    <div id="eisRecallSpinner" class="text-center py-3">
                        <div class="spinner-border text-info" role="status"><span class="sr-only">Loading…</span></div>
                        <p class="mt-2 text-muted">Loading invoice lines…</p>
                    </div>
                    <div id="eisRecallError" class="alert alert-danger d-none"></div>
                    <div id="eisRecallForm" class="d-none">
                        <div class="table-responsive mb-3">
                            <table class="table table-sm table-bordered" id="rcLinesTable">
                                <thead class="table-light">
                                    <tr><th>Code</th><th>Description</th><th class="text-end">Unit Price</th><th class="text-center">Orig Qty</th><th class="text-center" style="min-width:90px">Adj Qty</th><th class="text-end">Line Total</th><th class="text-end">VAT</th></tr>
                                </thead>
                                <tbody id="rcLinesTbody"></tbody>
                                <tfoot>
                                    <tr class="fw-bold"><td colspan="5" class="text-end">Adjusted Total:</td><td class="text-end" id="rcAdjTotal">0.00</td><td class="text-end" id="rcAdjVat">0.00</td></tr>
                                </tfoot>
                            </table>
                        </div>
                        <div class="form-group">
                            <label for="rcReason">Reason <span class="text-danger">*</span></label>
                            <textarea class="form-control" id="rcReason" rows="3" maxlength="500" placeholder="Describe why this invoice is being adjusted"></textarea>
                            <div class="invalid-feedback">A reason is required.</div>
                        </div>
                        <div id="rcSubmitResult" class="alert d-none mt-2" role="alert"></div>
                    </div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                    <button type="button" class="btn btn-info d-none" id="rcSubmitBtn">Submit Adjustment</button>
                </div>
            </div>
        </div>
    </div>
    <?php endif; ?>

    <!-- ── Top Bar ─────────────────────────────────────── -->
    <div class="pos-topbar">
        <div class="pos-topbar-brand">
            <div class="brand-icon"><i class="fas fa-cash-register"></i></div>
            <div class="brand-text">
                <span class="brand-name">Point of Sale</span>
                <span class="brand-sub"><?php echo htmlspecialchars($branchName ?? 'Branch', ENT_QUOTES, 'UTF-8'); ?></span>
            </div>
        </div>
        <div class="pos-topbar-center">
            <?php if ($eisOfflineMode): ?>
                <span class="badge bg-warning"><i class="fas fa-wifi-slash me-1"></i>EIS Offline Mode</span>
            <?php elseif ($eisEnabled): ?>
                <span class="badge bg-success"><i class="fas fa-check-circle me-1"></i>EIS Connected</span>
            <?php endif; ?>
        </div>
        <div class="pos-topbar-right">
            <div class="pos-user-chip">
                <div class="pos-user-avatar"><?php echo strtoupper(substr($_SESSION['username'] ?? 'U', 0, 1)); ?></div>
                <span class="pos-user-name"><?php echo htmlspecialchars($_SESSION['username'] ?? '', ENT_QUOTES, 'UTF-8'); ?></span>
            </div>
            <a href="<?php echo getDashboardLink(); ?>" class="pos-back"><i class="fas fa-arrow-left"></i> Back</a>
        </div>
    </div>

    <!-- ── Alerts ─────────────────────────────────────── -->
    <div class="pos-alerts">
        <?php if ($eisOfflineMode): ?>
            <?php
                $offlineExpired = !empty($eisOfflineStatus['expired']);
                $offlineStartedDisplay = !empty($eisOfflineStatus['offline_started_at'])
                    ? (new DateTimeImmutable($eisOfflineStatus['offline_started_at']))->format('d M Y H:i:s')
                    : 'Unavailable';
                $offlineExpiryDisplay = !empty($eisOfflineStatus['offline_expires_at'])
                    ? (new DateTimeImmutable($eisOfflineStatus['offline_expires_at']))->format('d M Y H:i:s')
                    : 'Unavailable';
            ?>
            <div class="alert <?php echo $offlineExpired ? 'alert-danger' : 'alert-warning'; ?>" role="alert"
                 id="eisOfflineWarning" data-remaining="<?php echo (int)($eisOfflineStatus['remaining_seconds'] ?? 0); ?>">
                <strong><?php echo $offlineExpired ? 'Offline sales blocked.' : 'MRA EIS is offline. Offline sales are temporarily allowed.'; ?></strong>
                <div class="mt-1">
                    Offline since: <?php echo htmlspecialchars($offlineStartedDisplay, ENT_QUOTES, 'UTF-8'); ?> |
                    Threshold: <?php echo htmlspecialchars((string)($eisOfflineStatus['offline_time_threshold_hours'] ?? 'Invalid'), ENT_QUOTES, 'UTF-8'); ?> hours |
                    Expires: <?php echo htmlspecialchars($offlineExpiryDisplay, ENT_QUOTES, 'UTF-8'); ?>
                </div>
                <div>
                    Time remaining: <strong id="eisOfflineCountdown"><?php echo $offlineExpired ? '00:00:00' : 'Calculating...'; ?></strong> |
                    Pending synchronization: <strong><?php echo (int)($eisOfflineStatus['pending_count'] ?? 0); ?></strong> transaction(s)
                </div>
                <?php if ($offlineExpired): ?>
                    <div>Reconnect and synchronize with MRA EIS to continue.</div>
                <?php endif; ?>
            </div>
        <?php endif; ?>
        <?php if (!empty($errors)): ?>
            <div class="alert alert-danger" role="alert">
                <ul class="mb-0 pl-3">
                    <?php foreach ($errors as $error): ?>
                        <li>
                            <?php echo htmlspecialchars($error, ENT_QUOTES, 'UTF-8'); ?>
                            <?php if (preg_match('/Item\s+(\S+)\s+has not been mapped to an MRA EIS product batch/i', $error, $unmappedMatch)): ?>
                                <button type="button" class="btn btn-sm btn-outline-danger contact-support-btn ms-2" data-unique-code="<?php echo htmlspecialchars($unmappedMatch[1], ENT_QUOTES, 'UTF-8'); ?>">
                                    <i class="fas fa-life-ring"></i> Contact Support
                                </button>
                            <?php endif; ?>
                        </li>
                    <?php endforeach; ?>
                </ul>
            </div>
        <?php endif; ?>
        <?php if (!empty($_SESSION['pos_flash_error'])): ?>
            <div class="alert alert-danger" role="alert"><?php echo htmlspecialchars($_SESSION['pos_flash_error'], ENT_QUOTES, 'UTF-8'); unset($_SESSION['pos_flash_error']); ?></div>
        <?php endif; ?>
    </div>

    <!-- ── POS Form ───────────────────────────────────── -->
    <form id="saleForm" method="POST" action="">
    <div class="pos-main">

        <!-- ════ LEFT: Cart Panel ═══════════════════════ -->
        <div class="pos-cart-panel">
            <div class="pos-cart-header">
                <div class="pos-cart-header-left">
                    <h2><i class="fas fa-shopping-cart"></i> Order</h2>
                    <span class="pos-cart-count" id="cartItemCount">0 items</span>
                </div>
                <div class="pos-mode-toggle">
                    <button type="button" id="uniqueCodeMode" class="btn btn-primary btn-sm">
                        <i class="fas fa-keyboard"></i> Manual
                    </button>
                    <button type="button" id="barcodeMode" class="btn btn-outline-success btn-sm">
                        <i class="fas fa-barcode"></i> Scanner
                    </button>
                </div>
            </div>

            <div class="pos-add-bar">
                <input type="hidden" id="quantity" name="quantity" value="<?php echo max(1, min(50, (int)($_POST['quantity'] ?? 1))); ?>">
                <button type="button" id="addItemBtn" class="btn btn-outline-primary btn-add-item">
                    <i class="fas fa-plus"></i> Add Item
                </button>
                <button type="button" id="browseStockBtn" class="btn btn-outline-secondary btn-browse">
                    <i class="fas fa-list"></i> Browse
                </button>
            </div>

            <div id="itemsContainer" class="pos-items-list">
                <div class="cart-empty" id="cartEmptyState">
                    <div class="cart-empty-icon"><i class="fas fa-shopping-basket"></i></div>
                    <p><strong>Cart is empty</strong><br>Add items using the button above or scan a barcode.</p>
                </div>
            </div>
        </div>

        <!-- ════ RIGHT: Payment Panel ═══════════════════ -->
        <div class="pos-pay-panel">
        <div class="pos-pay-inner">

            <!-- Totals -->
            <div class="pos-totals-card">
                <div class="pos-total-row">
                    <span>Subtotal</span>
                    <span><small style="opacity:.6;font-weight:500;">MWK</small> <span id="subtotalPrice">0.00</span></span>
                </div>
                <div class="pos-total-row" id="vatRow">
                    <span>VAT (<?php echo htmlspecialchars(number_format($vatPercentage, 2)); ?>%)</span>
                    <span><small style="opacity:.6;font-weight:500;">MWK</small> <span id="vatAmount">0.00</span></span>
                </div>
                <div class="pos-total-divider"></div>
                <div class="pos-total-grand">
                    <span class="pos-total-label">Total Due</span>
                    <span class="pos-total-amount"><small style="font-size:.9rem;font-weight:600;opacity:.7;vertical-align:baseline;margin-right:2px;">MWK</small><span id="totalPrice">0.00</span></span>
                </div>
            </div>

            <!-- Customer -->
            <div class="pos-card">
                <div class="pos-card-title"><i class="fas fa-user"></i> Customer</div>
                <input type="hidden" id="customer_id" name="customer_id" value="<?php echo htmlspecialchars($_POST['customer_id'] ?? '', ENT_QUOTES, 'UTF-8'); ?>">
                <div class="position-relative">
                    <input type="text" class="form-control" id="customer_name" name="customer_name"
                           value="<?php echo htmlspecialchars($_POST['customer_name'] ?? '', ENT_QUOTES, 'UTF-8'); ?>"
                           placeholder="Customer name (required)" autocomplete="off" required>
                    <div id="customerSearchResults" class="list-group position-absolute w-100 shadow-sm" style="z-index:1050; display:none;"></div>
                </div>
                <input type="text" class="form-control mt-2" id="customer_phone" name="customer_phone"
                       value="<?php echo htmlspecialchars($_POST['customer_phone'] ?? '', ENT_QUOTES, 'UTF-8'); ?>"
                       placeholder="Phone (optional, e.g. +265…)">
            </div>

            <?php if ($allowManualSaleDate): ?>
            <!-- Sale Date -->
            <div class="pos-card">
                <div class="pos-card-title"><i class="fas fa-calendar-alt"></i> Sale Date</div>
                <input type="date" class="form-control" id="sale_date" name="sale_date"
                       value="<?php echo htmlspecialchars($_POST['sale_date'] ?? date('Y-m-d'), ENT_QUOTES, 'UTF-8'); ?>">
                <small class="text-muted d-block mt-1" style="font-size:.75rem;">Past, current, and future dates are allowed for eligible sales. Online MRA EIS submissions always use the live MRA server time.</small>
            </div>
            <?php endif; ?>

            <!-- Transaction Type -->
            <div class="pos-card">
                <div class="pos-card-title"><i class="fas fa-file-invoice"></i> Transaction Type</div>
                <div class="pos-eis-row">
                    <select class="form-control" id="eis_transaction_type" name="eis_transaction_type" required>
                        <option value="B2C" <?php echo (($_POST['eis_transaction_type'] ?? 'B2C') === 'B2C') ? 'selected' : ''; ?>>B2C — Consumer</option>
                        <option value="B2B" <?php echo (($_POST['eis_transaction_type'] ?? '') === 'B2B') ? 'selected' : ''; ?>>B2B — Business</option>
                    </select>
                    <label class="pos-vat-label mb-0">
                        <input type="checkbox" id="apply_vat_relief" name="apply_vat_relief" value="1" <?php echo !empty($_POST['apply_vat_relief']) ? 'checked' : ''; ?>>
                        VAT Relief
                    </label>
                </div>
                <div id="buyerBusinessFields" style="display:none;">
                    <label for="buyer_tin">Buyer TIN</label>
                    <input type="text" class="form-control" id="buyer_tin" name="buyer_tin" maxlength="30"
                           value="<?php echo htmlspecialchars($_POST['buyer_tin'] ?? '', ENT_QUOTES, 'UTF-8'); ?>" placeholder="Buyer TIN">
                    <label for="buyer_authorization_code">Authorization Code</label>
                    <input type="text" class="form-control" id="buyer_authorization_code" name="buyer_authorization_code" maxlength="100"
                           value="<?php echo htmlspecialchars($_POST['buyer_authorization_code'] ?? '', ENT_QUOTES, 'UTF-8'); ?>" placeholder="EIS authorization code">
                    <div id="vat5CertGroup" style="display:none;">
                        <label for="vat5_certificate_number">VAT-5 Certificate</label>
                        <input type="text" class="form-control" id="vat5_certificate_number" name="vat5_certificate_number" maxlength="120"
                               value="<?php echo htmlspecialchars($_POST['vat5_certificate_number'] ?? '', ENT_QUOTES, 'UTF-8'); ?>" placeholder="VAT-5 certificate number">
                        <label for="vat5_project_number">Project Number</label>
                        <input type="text" class="form-control" id="vat5_project_number" name="vat5_project_number" maxlength="120"
                               value="<?php echo htmlspecialchars($_POST['vat5_project_number'] ?? '', ENT_QUOTES, 'UTF-8'); ?>" placeholder="Project number the certificate was issued for">
                    </div>
                </div>
            </div>

            <!-- Sale Mode -->
            <div class="pos-card">
                <div class="pos-card-title"><i class="fas fa-exchange-alt"></i> Sale Type</div>
                <input type="hidden" id="sale_mode" name="sale_mode" value="<?php echo (($_POST['sale_mode'] ?? 'cash') === 'credit') ? 'credit' : 'cash'; ?>">
                <div class="pos-salemode-btns">
                    <button type="button" class="pos-salemode-btn" id="saleModeNormal" data-mode="cash">
                        <i class="fas fa-money-bill-wave"></i>Normal Sale
                    </button>
                    <button type="button" class="pos-salemode-btn" id="saleModeCredit" data-mode="credit">
                        <i class="fas fa-credit-card"></i>Sell on Credit
                    </button>
                </div>
                <small class="text-muted d-block mt-1" style="font-size:.75rem;">Credit sales require controller approval; receipt prints after full payment.</small>
            </div>

            <!-- Payment Method -->
            <div class="pos-card" id="paymentMethodCard">
                <div class="pos-card-title"><i class="fas fa-wallet"></i> Payment Method</div>
                <select id="payment_method" name="payment_method" required class="d-none">
                    <?php echo paymentMethodSelectOptions($_POST['payment_method'] ?? 'cash'); ?>
                </select>
                <div class="pay-method-grid" id="payMethodGrid"></div>
            </div>

            <!-- Discount -->
            <div class="pos-card">
                <div class="pos-card-title"><i class="fas fa-tag"></i> Discount</div>
                <div class="pos-discount-row">
                    <div class="form-group">
                        <select class="form-control" id="discount_type" name="discount_type">
                            <option value="none"       <?php echo (($_POST['discount_type'] ?? 'none') === 'none')       ? 'selected' : ''; ?>>No Discount</option>
                            <option value="percentage" <?php echo (($_POST['discount_type'] ?? '') === 'percentage') ? 'selected' : ''; ?>>Percentage (%)</option>
                            <option value="fixed"      <?php echo (($_POST['discount_type'] ?? '') === 'fixed')      ? 'selected' : ''; ?>>Fixed Amount</option>
                        </select>
                    </div>
                    <div class="form-group" id="discountValueGroup" style="display:none;">
                        <input type="number" step="0.01" class="form-control" id="discount_value" name="discount_value"
                               min="0" value="<?php echo htmlspecialchars($_POST['discount_value'] ?? '0', ENT_QUOTES, 'UTF-8'); ?>" placeholder="0">
                    </div>
                </div>
                <div id="discountInfo" style="display:none;">
                    Discount: <strong>MWK <span id="discountAmount">0.00</span></strong> (<span id="discountPercentage">0.0</span>%)
                </div>
                <div class="form-group mt-2" id="discountReasonGroup" style="display:none;">
                    <label for="discount_reason" class="small text-muted mb-1">Reason (sent to controller if this discount needs approval)</label>
                    <input type="text" class="form-control" id="discount_reason" name="discount_reason"
                           maxlength="255" placeholder="e.g. Loyal customer, bulk purchase..."
                           value="<?php echo htmlspecialchars($_POST['discount_reason'] ?? '', ENT_QUOTES, 'UTF-8'); ?>">
                </div>
                <?php if (!empty($discountRules)): ?>
                <div class="small text-muted mt-2">
                    <i class="fas fa-check-circle" style="color:var(--success);"></i> Pre-approved:
                    <?php
                    $ruleLabels = array_map(static function ($r) {
                        $val = $r['discount_type'] === 'percentage'
                            ? rtrim(rtrim(number_format((float)$r['discount_value'], 2), '0'), '.') . '%'
                            : 'MWK ' . number_format((float)$r['discount_value'], 2);
                        return $val . (!empty($r['max_sale_amount']) ? ' (sales up to MWK ' . number_format((float)$r['max_sale_amount'], 2) . ')' : '');
                    }, $discountRules);
                    echo htmlspecialchars(implode(', ', $ruleLabels), ENT_QUOTES, 'UTF-8');
                    ?>. Anything else needs controller approval.
                </div>
                <?php else: ?>
                <div class="small text-muted mt-2">
                    <i class="fas fa-info-circle"></i> No standing discount rules yet — any discount will need controller approval.
                </div>
                <?php endif; ?>
            </div>

            <!-- Amount Paid -->
            <div class="pos-card">
                <div class="pos-card-title"><i class="fas fa-coins"></i> Amount Tendered (MWK)</div>
                <input type="number" step="0.01" class="form-control" id="amount_paid" name="amount_paid"
                       min="0" value="<?php echo htmlspecialchars($_POST['amount_paid'] ?? '', ENT_QUOTES, 'UTF-8'); ?>"
                       placeholder="0.00" required>
                <div id="minAmountInfo"></div>
                <div id="changeInfo" style="display:none;">
                    <span class="lbl"><i class="fas fa-coins"></i> Change Due</span>
                    <span class="val">MWK <span id="changeAmount">0.00</span></span>
                </div>
                <div id="errorInfo" style="display:none;"><i class="fas fa-exclamation-circle" style="flex-shrink:0;margin-top:1px;"></i> <span id="errorInfoText"></span></div>
                <div id="vatRecalcInfo" style="display:none;"><small><em>VAT recalculated based on amount paid</em></small></div>
            </div>

            <!-- Submit -->
            <button type="submit" name="record_sale" class="btn btn-block" id="recordSaleBtn" disabled>
                <i class="fas fa-cash-register me-2"></i>RECORD SALE
            </button>

        </div><!-- .pos-pay-inner -->
        </div><!-- .pos-pay-panel -->

    </div><!-- .pos-main -->
    </form>

    <!-- ── Recent Sales ──────────────────────────────── -->
    <div class="pos-recent">
        <div class="pos-recent-header">
            <h2><i class="fas fa-history"></i> Recent Sales</h2>
        </div>
        <?php if (empty($recentSales)): ?>
            <div class="p-4 text-muted text-center">No sales recorded for this branch yet.</div>
        <?php else: ?>
            <div id="eisActionResult" class="alert d-none m-3" role="alert"></div>
            <div class="table-responsive">
                <table class="table table-sm table-bordered mb-0">
                    <thead>
                        <tr>
                            <th>Date</th>
                            <th>Transaction</th>
                            <th>Customer</th>
                            <th>Type</th>
                            <th class="text-center">Items</th>
                            <th class="text-end">Total (MWK)</th>
                            <?php if ($eisEnabled): ?>
                            <th class="text-center">EIS</th>
                            <?php endif; ?>
                            <th class="text-center">Actions</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($recentSales as $recentSale):
                            $eisStatus = $recentSale['eis_status'] ?? null;
                            $eisValidationUrl = $recentSale['eis_validation_url'] ?? null;
                            $eisLastError = $recentSale['eis_last_error'] ?? null;
                            $txnId = $recentSale['transaction_id'];
                            $badgeMap = [
                                'submitted' => ['eis-badge-submitted', 'Submitted'],
                                'queued'    => ['eis-badge-queued',    'Queued'],
                                'failed'    => ['eis-badge-failed',    'Failed'],
                                'offline'   => ['eis-badge-offline',   'Offline'],
                                'pending'   => ['eis-badge-pending',   'Pending'],
                                'ready'     => ['eis-badge-pending',   'Pending'],
                                'disabled'  => ['eis-badge-disabled',  'Disabled'],
                                'blocked'   => ['eis-badge-failed',    'Blocked'],
                            ];
                            if ($eisStatus && isset($badgeMap[$eisStatus])) {
                                [$badgeClass, $badgeLabel] = $badgeMap[$eisStatus];
                            } elseif ($eisStatus === null && !$eisEnabled) {
                                $badgeClass = 'eis-badge-disabled'; $badgeLabel = 'Disabled';
                            } else {
                                $badgeClass = 'eis-badge-unknown'; $badgeLabel = $eisStatus ? ucfirst($eisStatus) : '—';
                            }
                            $canSubmit = in_array($eisStatus, ['queued', 'failed', 'offline', 'pending', 'ready', 'blocked'], true)
                                         || ($eisStatus === null && $eisEnabled);
                            $canCancel = ($eisStatus === 'submitted');
                        ?>
                            <tr data-txn-id="<?php echo htmlspecialchars($txnId, ENT_QUOTES, 'UTF-8'); ?>" data-receipt-url="view_sale_receipt.php?transaction_id=<?php echo urlencode($txnId); ?>" style="cursor:pointer;" title="Click to view receipt">
                                <td><?php echo htmlspecialchars(date('d M Y H:i', strtotime($recentSale['sold_at'])), ENT_QUOTES, 'UTF-8'); ?></td>
                                <td><?php echo htmlspecialchars($txnId, ENT_QUOTES, 'UTF-8'); ?></td>
                                <td>
                                    <?php echo htmlspecialchars($recentSale['customer_name'] ?: 'Walk-in', ENT_QUOTES, 'UTF-8'); ?>
                                    <?php if (!empty($recentSale['customer_phone'])): ?>
                                        <small class="d-block text-muted"><?php echo htmlspecialchars($recentSale['customer_phone'], ENT_QUOTES, 'UTF-8'); ?></small>
                                    <?php endif; ?>
                                </td>
                                <td><?php echo htmlspecialchars($recentSale['eis_transaction_type'] ?: 'B2C', ENT_QUOTES, 'UTF-8'); ?></td>
                                <td class="text-center"><?php echo (int)$recentSale['item_count']; ?></td>
                                <td class="text-end"><?php echo number_format((float)$recentSale['transaction_total'], 2); ?></td>
                                <?php if ($eisEnabled): ?>
                                <td class="text-center">
                                    <span class="eis-badge <?php echo $badgeClass; ?>"><?php echo htmlspecialchars($badgeLabel, ENT_QUOTES, 'UTF-8'); ?></span>
                                    <?php if ($eisValidationUrl): ?><a href="<?php echo htmlspecialchars($eisValidationUrl, ENT_QUOTES, 'UTF-8'); ?>" target="_blank" rel="noopener" class="eis-validation-link">View Receipt</a><?php endif; ?>
                                    <?php if ($eisLastError && $eisStatus !== 'submitted'): ?><span class="eis-error-tip" title="<?php echo htmlspecialchars($eisLastError, ENT_QUOTES, 'UTF-8'); ?>"><?php echo htmlspecialchars($eisLastError, ENT_QUOTES, 'UTF-8'); ?></span><?php endif; ?>
                                </td>
                                <?php endif; ?>
                                <td class="text-center" style="white-space:nowrap;">
                                    <a href="view_sale_receipt.php?transaction_id=<?php echo urlencode($txnId); ?>" class="btn btn-outline-info btn-sm eis-action-btn receipt-view-btn me-1"><i class="fas fa-eye"></i> View</a>
                                    <?php if (!empty($recentSale['sale_id'])): ?>
                                        <a href="edit_sale.php?id=<?php echo (int)$recentSale['sale_id']; ?>" class="btn btn-secondary btn-sm eis-action-btn receipt-edit-btn me-1"><i class="fas fa-edit"></i> Edit</a>
                                    <?php endif; ?>
                                    <?php if ($eisEnabled): ?>
                                        <?php if ($canSubmit): ?>
                                            <button type="button" class="btn btn-primary btn-sm eis-action-btn eis-submit-btn me-1" data-txn="<?php echo htmlspecialchars($txnId, ENT_QUOTES, 'UTF-8'); ?>">Submit</button>
                                        <?php elseif ($canCancel): ?>
                                            <button type="button" class="btn btn-info btn-sm eis-action-btn eis-recall-btn me-1" data-txn="<?php echo htmlspecialchars($txnId, ENT_QUOTES, 'UTF-8'); ?>" title="Adjust invoice (credit/debit note)">Recall</button>
                                            <button type="button" class="btn btn-danger btn-sm eis-action-btn eis-cancel-btn me-1" data-txn="<?php echo htmlspecialchars($txnId, ENT_QUOTES, 'UTF-8'); ?>">Cancel</button>
                                        <?php endif; ?>
                                    <?php endif; ?>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        <?php endif; ?>
    </div>

</div><!-- .pos-app -->

    <script>
    let currentInputMethod = 'unique_code';
    let activeInput = null;
    let stockSearchTimer = null;
    const postedItemValues = <?php echo json_encode(array_map(null, $_POST['unique_code'] ?? [], $_POST['item_name'] ?? [], $_POST['price'] ?? [], $_POST['item_details'] ?? []), JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT); ?>;
    let lastStockSearchTerm = '';
    let customerSearchTimer = null;
    let customerSearchXhr = null;
    let cartVatCents = 0; // true grouped VAT from updateTotalPrice(), used by validateAmountPaid()

    /* ── MRA tax rate groups (A=standard, B/E/etc.=zero-rated/exempt) ──
       Mirrors MraEisCompliance::vatComponent()'s server-side logic so the
       cart's live totals match what actually gets submitted to MRA, instead
       of applying one flat VAT rate to every item regardless of its group. */
    const zeroRatedTaxIds = <?php echo json_encode($systemSettings->eisZeroRatedTaxIds()); ?>;
    const standardVatPercent = <?php echo json_encode($vatPercentage); ?>;

    function vatForLine(grossCents, taxRateId) {
        const id = (taxRateId || 'A').toUpperCase();
        if (zeroRatedTaxIds.includes(id)) return 0;
        const rate = standardVatPercent;
        if (!rate || rate <= 0) return 0;
        return Math.round((grossCents * rate) / (100 + rate));
    }

    /* ── Payment method icon map ── */
    const PAY_ICONS = {
        cash: 'fas fa-money-bill-wave',
        mobile: 'fas fa-mobile-alt',
        bank: 'fas fa-university',
        card: 'fas fa-credit-card',
        cheque: 'fas fa-file-alt',
        transfer: 'fas fa-university',
    };
    function payIcon(val) {
        const v = val.toLowerCase();
        for (const k of Object.keys(PAY_ICONS)) { if (v.includes(k)) return PAY_ICONS[k]; }
        return 'fas fa-wallet';
    }

    function initPayMethodGrid() {
        const $select = $('#payment_method');
        const $grid   = $('#payMethodGrid');
        $grid.empty();
        $select.find('option').each(function() {
            const val = $(this).val(), label = $(this).text();
            const $btn = $('<button type="button" class="pay-method-btn"></button>')
                .attr('data-value', val)
                .html(`<i class="${payIcon(val)}"></i><span>${label}</span>`);
            if ($(this).is(':selected')) $btn.addClass('selected');
            $btn.on('click', function() {
                $('.pay-method-btn').removeClass('selected');
                $(this).addClass('selected');
                $select.val(val);
            });
            $grid.append($btn);
        });
    }

    function initSaleMode() {
        const cur = $('#sale_mode').val() || 'cash';
        updateSaleModeUI(cur);
        $('#saleModeNormal, #saleModeCredit').on('click', function() {
            const mode = $(this).data('mode');
            $('#sale_mode').val(mode).trigger('change');
            updateSaleModeUI(mode);
        });
    }

    function updateSaleModeUI(mode) {
        $('#saleModeNormal').removeClass('active-cash active-credit');
        $('#saleModeCredit').removeClass('active-cash active-credit');
        if (mode === 'cash') {
            $('#saleModeNormal').addClass('active-cash');
            $('#paymentMethodCard').show();
            $('#amount_paid').attr('required', 'required');
        } else {
            $('#saleModeCredit').addClass('active-credit');
            $('#paymentMethodCard').hide();
            $('#amount_paid').removeAttr('required');
            if (!$('#amount_paid').val()) $('#amount_paid').val('0');
        }
    }

    $(document).ready(function() {

        initPayMethodGrid();
        initSaleMode();

        const stockTable = $('#example3').DataTable({
            paging: true, searching: true, ordering: true, info: true,
            lengthMenu: [5, 10, 25, 50], pageLength: 10
        });

        stockTable.on('draw', function() {
            const searchTerm = stockTable.search().trim();
            const visibleRows = stockTable.page.info().recordsDisplay;
            if (!searchTerm || visibleRows > 0) {
                lastStockSearchTerm = ''; clearTimeout(stockSearchTimer); clearTableLookupError(); return;
            }
            clearTimeout(stockSearchTimer);
            stockSearchTimer = setTimeout(function() { lookupMissingStockCode(searchTerm); }, 350);
        });

        $(document).on('click', '.code_search', function() {
            activeInput = $(this);
            clearTableLookupError();
            bootstrap.Modal.getOrCreateInstance(document.getElementById('modal_stock')).show();
        });

        $('#browseStockBtn').on('click', function() {
            let $t = $('#itemsContainer .unique-code-input:focus, #itemsContainer .barcode-input:focus').first();
            if (!$t.length) $t = $('#itemsContainer .item-row').last().find('.unique-code-input, .barcode-input').first();
            activeInput = $t.length ? $t : null;
            clearTableLookupError();
            bootstrap.Modal.getOrCreateInstance(document.getElementById('modal_stock')).show();
        });

        $('#example3 tbody').on('click', 'tr', function() {
            const data = $('#example3').DataTable().row(this).data();
            if (!data) return;
            const uniqueCode = $('<div>').html(data[0]).text();
            if (activeInput) activeInput.val(uniqueCode).trigger('blur');
            bootstrap.Modal.getOrCreateInstance(document.getElementById('modal_stock')).hide();
        });

        $('#uniqueCodeMode').on('click', function() { switchInputMethod('unique_code'); });
        $('#barcodeMode').on('click',    function() { switchInputMethod('barcode'); });

        /* ── Add / Remove item rows ── */
        $('#addItemBtn').on('click', function() {
            const currentRows = $('#itemsContainer .item-row').length;
            if (currentRows >= 50) return;
            const existingValues = collectExistingValues();
            existingValues.push(['', '', '']);
            const newQty = currentRows + 1;
            $('#quantity').val(newQty);
            generateItemFields(newQty, existingValues);
            const $newRow = $('#itemsContainer .item-row').last();
            $newRow.find('.unique-code-input, .barcode-input').first().focus();
            $newRow[0].scrollIntoView({ behavior: 'smooth', block: 'nearest' });
        });

        $(document).on('click', '.btn-remove-item', function() {
            if ($('#itemsContainer .item-row').length <= 1) return;
            $(this).closest('.item-row').remove();
            renumberRows();
            $('#quantity').val($('#itemsContainer .item-row').length);
            updateRemoveBtnVisibility();
            updateTotalPrice();
        });

        generateItemFields(parseInt($('#quantity').val()) || 1, postedItemValues);

        $(document).on('blur', '.unique-code-input', function() {
            if (currentInputMethod === 'unique_code') handleItemLookup($(this), 'unique_code');
        });

        $(document).on('input', '.barcode-input', function() {
            const v = $(this).val();
            if (v && v.length >= 5) handleItemLookup($(this), 'barcode');
        });

        $(document).on('change input', '.price-input', updateTotalPrice);
        $('#amount_paid').on('input', validateAmountPaid);
        $('#customer_name, #customer_phone').on('input change', validateAmountPaid);
    });

    /* ── Customer search ── */
    $('#customer_name').on('input', function() {
        $('#customer_id').val('');
        const term = $(this).val().trim();
        clearTimeout(customerSearchTimer);
        if (customerSearchXhr) { customerSearchXhr.abort(); customerSearchXhr = null; }
        if (term.length < 2) { $('#customerSearchResults').hide().empty(); validateAmountPaid(); return; }
        customerSearchTimer = setTimeout(function() {
            customerSearchXhr = $.getJSON('../../ajax/customer_search.php', { term: term })
                .done(function(response) {
                    customerSearchXhr = null;
                    const $r = $('#customerSearchResults').empty();
                    if (!response.success || !response.customers || !response.customers.length) { $r.hide(); return; }
                    response.customers.forEach(function(c) {
                        const phone = c.customer_phone ? ' — ' + c.customer_phone : '';
                        $('<button type="button" class="list-group-item list-group-item-action"></button>')
                            .text(c.customer_name + phone).data('customer', c).appendTo($r);
                    });
                    $r.show();
                });
        }, 250);
        validateAmountPaid();
    });

    $('#customerSearchResults').on('click', '.list-group-item', function() {
        const c = $(this).data('customer');
        $('#customer_id').val(c.customer_id || '');
        $('#customer_name').val(c.customer_name || '');
        $('#customer_phone').val(c.customer_phone || '');
        if (c.buyer_tin) $('#buyer_tin').val(c.buyer_tin);
        $('#customerSearchResults').hide().empty();
        validateAmountPaid();
    });

    $(document).on('click', function(e) {
        if (!$(e.target).closest('#customer_name, #customerSearchResults').length) $('#customerSearchResults').hide();
    });

    /* ── Input method toggle ── */
    function switchInputMethod(method) {
        currentInputMethod = method;
        if (method === 'unique_code') {
            $('#uniqueCodeMode').removeClass('btn-outline-primary').addClass('btn-primary');
            $('#barcodeMode').removeClass('btn-success').addClass('btn-outline-success');
        } else {
            $('#barcodeMode').removeClass('btn-outline-success').addClass('btn-success');
            $('#uniqueCodeMode').removeClass('btn-primary').addClass('btn-outline-primary');
        }
        generateItemFields($('#itemsContainer .item-row').length || 1);
    }

    function collectExistingValues() {
        const vals = [];
        $('#itemsContainer .item-row').each(function() {
            vals.push([
                $(this).find('[name="unique_code[]"]').val() || '',
                $(this).find('[name="item_name[]"]').val() || '',
                $(this).find('[name="price[]"]').val() || '',
                $(this).find('.item-details-input').val() || ''
            ]);
        });
        return vals;
    }

    function renumberRows() {
        const $rows = $('#itemsContainer .item-row');
        $rows.each(function(i) {
            $(this).find('.item-row-num').text(i + 1);
        });
        const count = $rows.length;
        $('#cartItemCount').text(count === 0 ? '0 items' : count === 1 ? '1 item' : count + ' items');
        $('#cartEmptyState').toggle(count === 0);
    }

    function updateRemoveBtnVisibility() {
        const count = $('#itemsContainer .item-row').length;
        $('.btn-remove-item').css('visibility', count <= 1 ? 'hidden' : 'visible');
    }

    function generateItemFields(quantity, existingValues = null) {
        if (existingValues === null) existingValues = collectExistingValues();

        let html = '';
        for (let i = 0; i < quantity; i++) {
            let codeField;
            if (currentInputMethod === 'unique_code') {
                codeField = `<input type="text" class="form-control unique-code-input code_search" name="unique_code[]" placeholder="Unique code — tap to browse" required>`;
            } else {
                codeField = `<input type="text" class="form-control barcode-input" name="unique_code[]" placeholder="Scan barcode…" required>
                             <span class="scanner-indicator">Ready</span>`;
            }
            html += `
            <div class="item-row">
                <div class="item-row-num">${i + 1}</div>
                <div class="item-row-fields">
                    <div class="item-row-code-wrap">${codeField}</div>
                    <input type="text" class="form-control form-control-sm item-name-input" name="item_name[]" readonly placeholder="Item name">
                    <input type='text' class='form-control form-control-sm item-details-input' name='item_details[]' readonly placeholder='Item details'>
                    <div class="lookup-feedback"></div>
                </div>
                <div class="item-row-price">
                    <input type="number" step="0.01" class="form-control price-input" name="price[]" placeholder="0.00" required>
                    <span class="tax-group-badge" title="MRA tax rate group — resolved on lookup"></span>
                </div>
                <button type="button" class="btn-remove-item" title="Remove" style="visibility:${quantity <= 1 ? 'hidden' : 'visible'}">
                    <i class="fas fa-times"></i>
                </button>
            </div>`;
        }

        const $container = $('#itemsContainer');
        $container.find('.item-row').remove();
        $container.append(html);
        $('#itemsContainer .item-row').each(function(i) {
            const v = existingValues[i] || ['', '', ''];
            $(this).find('[name="unique_code[]"]').val(v[0] || '');
            $(this).find('[name="item_name[]"]').val(v[1] || '');
            $(this).find('[name="price[]"]').val(v[2] || '');
            $(this).find('.item-details-input').val(v[3] || '');
        });

        renumberRows();
        if (currentInputMethod === 'barcode') $('.barcode-input:first').focus();
        updateTotalPrice();
    }

    function cleanLookupJsonText(text) {
        return String(text || '').replace(/^[\uFEFF\xEF\xBB\xBF\s]+/, '');
    }

    function parseLookupJson(text) {
        return JSON.parse(cleanLookupJsonText(text));
    }
    function handleItemLookup($input, lookupType) {
        const inputValue = $input.val().trim();
        const row = $input.closest('.item-row');

        if (!inputValue) {
            clearLookupMessage($input);
            return;
        }

        const lookupData = {};
        if (lookupType === 'barcode') {
            lookupData.barcode_data = inputValue;
        } else if (lookupType === 'unique_code') {
            lookupData.unique_code = inputValue;
        }

        $.ajax({
            url: 'get_item_details.php',
            type: 'POST',
            data: lookupData,
            dataType: 'json',
            dataFilter: cleanLookupJsonText,
            success: function(response) {
                if (response.success) {
                    const item = response.item;
                    const originalPrice = parseFloat(item.unit_price) || 0;

                    if (lookupType === 'barcode') {
                        $input.val(item.unique_code);
                        $input.data('unique-code', item.unique_code);
                        $input.attr('data-unique-code', item.unique_code);
                    }

                    row.find('.item-name-input').val(item.item_name);
                    row.find('.item-details-input').val(item.item_details || '');
                    row.find('.price-input').val(originalPrice.toFixed(2));
                    row.find('.price-input').data('original-price', originalPrice);

                    // Display the exact value returned from `items.tax_rate_id`;
                    // only the VAT calculation may use A as a fallback.
                    const databaseTaxRateId = String(item.tax_rate_id ?? '').trim().toUpperCase();
                    const taxRateId = databaseTaxRateId || 'A';
                    const isZeroRated = zeroRatedTaxIds.includes(taxRateId);
                    row.find('.price-input').data('tax-rate-id', taxRateId);
                    row.find('.tax-group-badge')
                        .attr('class', 'tax-group-badge' + (isZeroRated ? ' tax-zero' : ''))
                        .attr('title', isZeroRated ? 'Zero-rated / exempt (' + taxRateId + ') — no VAT' : 'Standard-rated (' + taxRateId + ')')
                        .text(taxRateId);


                    updateTotalPrice();

                    clearLookupMessage($input);
                    $input.addClass('is-valid');
                } else {
                    showLookupError($input, row, lookupType, response.message || 'Item is not available for sale.');
                }
            },
            error: function(xhr, status, error) {
                let errorMessage = 'Error looking up item details';
                try {
                    const response = parseLookupJson(xhr.responseText);
                    if (response.message) {
                        errorMessage = response.message;
                    }
                } catch (e) {
                    errorMessage += ': ' + xhr.responseText;
                }
                showLookupError($input, row, lookupType, errorMessage);
            }
        });
    }

    function clearLookupMessage($input) {
        const row = $input.closest('.item-row');
        $input.removeClass('is-invalid');
        row.find('.lookup-feedback').text('');
        clearTableLookupError();
    }

    function showLookupError($input, row, lookupType, message) {
        row.find('.item-name-input, .item-details-input').val('');
        row.find('.price-input').val('');
        $input.removeClass('is-valid').addClass('is-invalid');
        $input.closest('.form-group').find('.lookup-feedback').text(message);
        showTableLookupError(message);
        updateTotalPrice();
    }

    function showTableLookupError(message) {
        $('#stockLookupError').text(message).removeClass('d-none');
    }

    function clearTableLookupError() {
        $('#stockLookupError').text('').addClass('d-none');
    }

    function lookupMissingStockCode(searchTerm) {
        if (!searchTerm || searchTerm === lastStockSearchTerm) {
            return;
        }

        lastStockSearchTerm = searchTerm;

        $.ajax({
            url: 'get_item_details.php',
            type: 'POST',
            data: { unique_code: searchTerm },
            dataType: 'json',
            dataFilter: cleanLookupJsonText,
            success: function(response) {
                if ($('#example3').DataTable().search().trim() !== searchTerm) {
                    return;
                }

                if (response.success) {
                    showTableLookupError('No matching records found. This code exists and is available, but it did not match the current table filter.');
                } else {
                    showTableLookupError('No matching records found. ' + (response.message || 'Unable to determine what happened to this code.'));
                }
            },
            error: function(xhr) {
                if ($('#example3').DataTable().search().trim() !== searchTerm) {
                    return;
                }

                let errorMessage = 'Unable to determine what happened to this code.';
                try {
                    const response = parseLookupJson(xhr.responseText);
                    if (response.message) {
                        errorMessage = response.message;
                    }
                } catch (e) {
                    if (xhr.responseText) {
                        errorMessage = xhr.responseText;
                    }
                }

                showTableLookupError('No matching records found. ' + errorMessage);
            }
        });
    }

    function updateTotalPrice() {
        let grossCents = 0;
        let vatCents = 0;
        const isCreditSale = $('#sale_mode').val() === 'credit';
        const isVatRelief = $('#apply_vat_relief').is(':checked');

        // Sum each line's own tax group instead of applying one flat VAT rate
        // to the whole cart — zero-rated/exempt items (B/E) contribute 0 VAT,
        // standard-rated (A) items are gross-up extracted individually, matching
        // MraEisCompliance::vatComponent()'s server-side per-item computation.
        $('.item-row').each(function() {
            const priceInput = $(this).find('.price-input');
            const lineGrossCents = Math.round((parseFloat(priceInput.val()) || 0) * 100);
            grossCents += lineGrossCents;
            if (!isVatRelief) {
                vatCents += vatForLine(lineGrossCents, priceInput.data('tax-rate-id'));
            }
        });

        const totalCents = grossCents;
        cartVatCents = vatCents;
        const subtotalCents = totalCents - vatCents;
        const total = totalCents / 100;
        const subtotal = subtotalCents / 100;
        const vatAmount = vatCents / 100;

        $('#subtotalPrice').text(subtotal.toFixed(2));
        $('#vatAmount').text(vatAmount.toFixed(2));
        $('#totalPrice').text(total.toFixed(2));
        $('#amount_paid').attr('min', '0');
        $('#amount_paid').removeAttr('max');
        $('#minAmountInfo').text('');

        $('#vatAmount').removeClass('vat-recalculated');
        $('#subtotalPrice').removeClass('vat-recalculated');
        $('#vatRecalcInfo').hide();

        validateAmountPaid();
    }

    function validateAmountPaid() {
        const originalTotalCents = Math.round((parseFloat($('#totalPrice').text()) || 0) * 100);
        const amountPaidValue = parseFloat($('#amount_paid').val());
        const amountPaidCents = Number.isFinite(amountPaidValue) ? Math.round(amountPaidValue * 100) : NaN;
        const originalTotal = originalTotalCents / 100;
        const amountPaid = amountPaidCents / 100;
        const customerName = $('#customer_name').val().trim();
        const customerPhone = $('#customer_phone').val().trim();
        const isVatRelief = $('#apply_vat_relief').is(':checked');
        const transactionType = $('#eis_transaction_type').val();
        const buyerTin = $('#buyer_tin').val().trim();
        const isCreditSale = $('#sale_mode').val() === 'credit';
        // True grouped VAT computed per-line in updateTotalPrice() — never re-derive
        // it from a flat blended rate, or mixed A/B/E carts would be wrong again.
        const originalVatCents = isVatRelief ? 0 : cartVatCents;

        $('#discountInfo').hide();
        $('#errorInfo').hide();
        $('#changeInfo').hide();
        $('#recordSaleBtn').prop('disabled', true);
        $('#amount_paid').removeClass('is-invalid is-valid');

        if (originalTotalCents <= 0 || (!isCreditSale && !Number.isFinite(amountPaidCents))) {
            const originalSubtotal = (originalTotalCents - originalVatCents) / 100;
            const originalVat = originalVatCents / 100;
            $('#subtotalPrice').text(originalSubtotal.toFixed(2));
            $('#vatAmount').text(originalVat.toFixed(2));
            $('#vatAmount').removeClass('vat-recalculated');
            $('#subtotalPrice').removeClass('vat-recalculated');
            $('#vatRecalcInfo').hide();
            return;
        }
if (customerName.length === 0) {
            $('#errorInfo').show(); $('#errorInfoText').text('Enter customer name.');
            return;
        }

        if (customerPhone.length > 0 && !/^\+?[0-9]{7,15}$/.test(customerPhone)) {
            $('#errorInfo').show(); $('#errorInfoText').text('Error in phone number. Use 7 to 15 digits, optional + at the start.');
            return;
        }

        if (!isCreditSale && isVatRelief && transactionType !== 'B2B') {
            $('#errorInfo').show(); $('#errorInfoText').text('VAT relief requires a B2B transaction.');
            return;
        }

        if (!isCreditSale && transactionType === 'B2B' && !/^[A-Za-z0-9-]{5,30}$/.test(buyerTin)) {
            $('#errorInfo').show(); $('#errorInfoText').text('Enter a valid buyer TIN for the B2B transaction.');
            return;
        }

        if (!isCreditSale && isVatRelief && $('#vat5_certificate_number').val().trim().length === 0) {
            $('#errorInfo').show(); $('#errorInfoText').text('Enter the VAT-5 certificate number.');
            return;
        }

        if (!isCreditSale && isVatRelief && $('#vat5_project_number').val().trim().length === 0) {
            $('#errorInfo').show(); $('#errorInfoText').text('Enter the VAT-5 project number the certificate was issued for.');
            return;
        }

        if (amountPaidCents > originalTotalCents) {
            const change = (amountPaidCents - originalTotalCents) / 100;
            $('#changeAmount').text(change.toFixed(2));
            $('#changeInfo').show();
            $('#amount_paid').addClass('is-valid');
            $('#recordSaleBtn').prop('disabled', false);

            const originalSubtotal = (originalTotalCents - originalVatCents) / 100;
            const originalVat = originalVatCents / 100;
            $('#subtotalPrice').text(originalSubtotal.toFixed(2));
            $('#vatAmount').text(originalVat.toFixed(2));
            $('#vatAmount').removeClass('vat-recalculated');
            $('#subtotalPrice').removeClass('vat-recalculated');
            $('#vatRecalcInfo').hide();
            return;
        }

        $('#amount_paid').addClass('is-valid');
        $('#recordSaleBtn').prop('disabled', false);

        const finalCents = isCreditSale ? originalTotalCents : Math.min(amountPaidCents, originalTotalCents);
        // A discount is applied as one blanket amount/percentage over the whole cart,
        // not per tax group, so scale each group's VAT down by the same ratio the
        // payment represents of the full (undiscounted) total.
        const payRatio = originalTotalCents > 0 ? (finalCents / originalTotalCents) : 1;
        const newVatCents = isVatRelief ? 0 : Math.round(originalVatCents * payRatio);
        const newSubtotalCents = finalCents - newVatCents;
        const newSubtotal = newSubtotalCents / 100;
        const newVat = newVatCents / 100;
        $('#subtotalPrice').text(newSubtotal.toFixed(2));
        $('#vatAmount').text(newVat.toFixed(2));

        if (!isCreditSale && amountPaidCents < originalTotalCents) {
            $('#vatAmount').addClass('vat-recalculated');
            $('#subtotalPrice').addClass('vat-recalculated');
            $('#vatRecalcInfo').show();

            const discount = (originalTotalCents - amountPaidCents) / 100;
            const discountPercentage = ((originalTotalCents - amountPaidCents) / originalTotalCents) * 100;
            $('#discountAmount').text(discount.toFixed(2));
            $('#discountPercentage').text(discountPercentage.toFixed(1));
            $('#discountInfo').show();
        } else {
            $('#vatAmount').removeClass('vat-recalculated');
            $('#subtotalPrice').removeClass('vat-recalculated');
            $('#vatRecalcInfo').hide();
        }
    }

    $('#apply_vat_relief').on('change', function() {
        if ($(this).is(':checked')) {
            $('#eis_transaction_type').val('B2B');
        }
        updateBuyerBusinessFields();
        updateTotalPrice();
    });

    function updateBuyerBusinessFields() {
        const isB2B = $('#eis_transaction_type').val() === 'B2B';
        const isVatRelief = $('#apply_vat_relief').is(':checked');
        $('#buyerBusinessFields').toggle(isB2B);
        $('#buyer_tin').prop('required', isB2B);
        $('#vat5CertGroup').toggle(isB2B && isVatRelief);
        $('#vat5_certificate_number, #vat5_project_number').prop('required', isB2B && isVatRelief);
        if (!isB2B) {
            $('#buyer_tin, #buyer_authorization_code, #vat5_certificate_number, #vat5_project_number').val('');
        }
        validateAmountPaid();
    }

    $('#eis_transaction_type').on('change', function() {
        if ($(this).val() === 'B2C' && $('#apply_vat_relief').is(':checked')) {
            $('#apply_vat_relief').prop('checked', false);
            updateTotalPrice();
        }
        updateBuyerBusinessFields();
    });
    $('#buyer_tin, #buyer_authorization_code, #vat5_certificate_number, #vat5_project_number').on('input', validateAmountPaid);

    function applyDiscountMode() {
        const discountType = $('#discount_type').val();
        const discountValue = parseFloat($('#discount_value').val()) || 0;
        const totalCents = Math.round((parseFloat($('#totalPrice').text()) || 0) * 100);
        $('#discountValueGroup').toggle(discountType !== 'none');
        $('#discountReasonGroup').toggle(discountType !== 'none');
        if (discountType === 'none' || totalCents === 0) {
            return;
        }
        let amountPaidCents;
        if (discountType === 'percentage') {
            if (discountValue <= 0) return;
            amountPaidCents = Math.round(totalCents * (1 - Math.min(discountValue, 100) / 100));
        } else {
            amountPaidCents = Math.max(0, totalCents - Math.round(discountValue * 100));
        }
        $('#amount_paid').val((amountPaidCents / 100).toFixed(2));
        validateAmountPaid();
    }

    $('#discount_type').on('change', applyDiscountMode);
    $('#discount_value').on('input', applyDiscountMode);
    applyDiscountMode();
    $('#sale_mode').on('change', function() {
        if ($(this).val() === 'credit' && !$('#amount_paid').val()) {
            $('#amount_paid').val('0.00');
        }
        validateAmountPaid();
    });
    $('#sale_mode').trigger('change');

    updateBuyerBusinessFields();
    $('#saleForm').on('submit', function(e) {
        validateAmountPaid();

        if ($('#recordSaleBtn').prop('disabled')) {
            e.preventDefault();
            return false;
        }
    });


    // ── EIS Sync Actions ─────────────────────────────────────────────────────

    let eisActionTxn = '';
    const eisEnabled = <?php echo json_encode($eisEnabled); ?>;
    const eisOfflineMode = <?php echo json_encode($eisOfflineMode); ?>;
    const eisManualOfflineMode = <?php echo json_encode($eisManualOfflineMode); ?>;
    const eisPendingCount = <?php echo (int)($eisOfflineStatus['pending_count'] ?? 0); ?>;
    const offlineWarning = document.getElementById('eisOfflineWarning');
    if (offlineWarning) {
        let remaining = Math.max(0, parseInt(offlineWarning.dataset.remaining || '0', 10));
        const countdown = document.getElementById('eisOfflineCountdown');
        const renderCountdown = function() {
            const hours = Math.floor(remaining / 3600);
            const minutes = Math.floor((remaining % 3600) / 60);
            const seconds = remaining % 60;
            countdown.textContent = [hours, minutes, seconds].map(function(value) {
                return String(value).padStart(2, '0');
            }).join(':');
            if (remaining > 0) remaining--;
        };
        renderCountdown();
        window.setInterval(renderCountdown, 1000);
    }

    function showEisActionResult(message, success) {
        const $el = $('#eisActionResult');
        $el.removeClass('d-none alert-success alert-danger')
           .addClass(success ? 'alert-success' : 'alert-danger')
           .text(message);
        $el[0].scrollIntoView({ behavior: 'smooth', block: 'nearest' });
        setTimeout(function() { $el.addClass('d-none'); }, 8000);
    }

    function escHtml(str) {
        return $('<div>').text(str).html();
    }

    function updateRowStatus(txn, newStatus, validationUrl) {
        const $row = $('tr[data-txn-id="' + escHtml(txn) + '"]');
        if (!$row.length) return;

        const badgeMap = {
            submitted: ['eis-badge-submitted', 'Submitted'],
            queued:    ['eis-badge-queued',    'Queued'],
            failed:    ['eis-badge-failed',    'Failed'],
            offline:   ['eis-badge-offline',   'Offline'],
        };
        const [badgeClass, badgeLabel] = badgeMap[newStatus] || ['eis-badge-unknown', newStatus];

        const $statusCell = $row.find('td').eq(6);
        $statusCell.html(
            '<span class="eis-badge ' + badgeClass + '">' + badgeLabel + '</span>' +
            (validationUrl ? '<a href="' + escHtml(validationUrl) + '" target="_blank" rel="noopener" class="eis-validation-link">View Receipt</a>' : '')
        );

        // Preserve View and Edit buttons, then rebuild EIS-specific actions
        const $actionCell = $row.find('td').eq(7);
        const $viewBtn = $actionCell.find('a.receipt-view-btn').clone();
        const $editBtn = $actionCell.find('a.receipt-edit-btn').clone();
        let eisHtml = '';
        if (newStatus === 'submitted') {
            eisHtml =
                '<button type="button" class="btn btn-info btn-sm eis-action-btn eis-recall-btn me-1" data-txn="' + escHtml(txn) + '" title="Adjust invoice (credit/debit note)">Recall</button>' +
                '<button type="button" class="btn btn-danger btn-sm eis-action-btn eis-cancel-btn me-1" data-txn="' + escHtml(txn) + '" title="Request EIS cancellation/void of this receipt">Cancel</button>';
        } else if (['queued', 'failed', 'offline', 'pending', 'ready', 'blocked'].indexOf(newStatus) !== -1) {
            eisHtml = '<button type="button" class="btn btn-primary btn-sm eis-action-btn eis-submit-btn me-1" data-txn="' + escHtml(txn) + '" title="Submit this pending sale to MRA EIS">Submit</button>';
        }
        $actionCell.empty();
        if ($viewBtn.length) $actionCell.append($viewBtn);
        if ($editBtn.length) $actionCell.append($editBtn);
        if (eisHtml) $actionCell.append(eisHtml);
    }

    // Row click — navigate to receipt (ignore clicks on interactive elements)
    $(document).on('click', '.pos-recent tbody tr[data-receipt-url]', function(e) {
        if ($(e.target).closest('a, button, input, select, form, label').length) return;
        window.location.href = $(this).data('receipt-url');
    });

    // Auto-submit pending EIS transactions on page load
    if (eisEnabled && !eisManualOfflineMode && (eisOfflineMode || eisPendingCount > 0)) {
        $.ajax({
            url: 'eis_sale_action.php',
            type: 'POST',
            data: { action: 'flush_pending' },
            dataType: 'json',
            success: function(res) {
                if (res.submitted > 0) {
                    showEisActionResult(
                        res.submitted + ' pending sale' + (res.submitted !== 1 ? 's' : '') + ' automatically submitted to MRA EIS.',
                        true
                    );
                    // Reload table rows to show updated statuses
                    setTimeout(function() { location.reload(); }, 1500);
                } else if (res.connection_status === 'online' && eisOfflineMode) {
                    showEisActionResult('MRA EIS connectivity has been restored.', true);
                    setTimeout(function() { location.reload(); }, 1000);
                }
            }
        });
    }

    // Submit (manual) button
    $(document).on('click', '.eis-submit-btn', function() {
        const txn = $(this).data('txn');
        const $btn = $(this);
        $btn.prop('disabled', true).text('Submitting…');

        $.ajax({
            url: 'eis_sale_action.php',
            type: 'POST',
            data: { action: 'recall', transaction_id: txn },
            dataType: 'json',
            success: function(res) {
                showEisActionResult(res.message, res.success);
                if (res.new_status) {
                    updateRowStatus(txn, res.new_status, res.validation_url || null);
                } else {
                    $btn.prop('disabled', false).text('Submit');
                }
            },
            error: function() {
                showEisActionResult('Request failed. Please try again.', false);
                $btn.prop('disabled', false).text('Submit');
            }
        });
    });

    // Recall button — open adjustment modal and load original invoice lines
    let rcOriginalLines = [];
    let rcTxn = '';

    $(document).on('click', '.eis-recall-btn', function() {
        rcTxn = $(this).data('txn');
        rcOriginalLines = [];

        // Reset modal state
        $('#rcInvoiceRef').text(rcTxn);
        $('#eisRecallSpinner').removeClass('d-none');
        $('#eisRecallError').addClass('d-none').text('');
        $('#eisRecallForm').addClass('d-none');
        $('#rcSubmitBtn').addClass('d-none').prop('disabled', false).text('Submit Adjustment');
        $('#rcReason').val('').removeClass('is-invalid');
        $('#rcSubmitResult').addClass('d-none').text('');
        bootstrap.Modal.getOrCreateInstance(document.getElementById('eisRecallModal')).show();

        $.ajax({
            url: 'eis_sale_action.php',
            type: 'POST',
            data: { action: 'get_invoice_items', transaction_id: rcTxn },
            dataType: 'json',
            success: function(res) {
                $('#eisRecallSpinner').addClass('d-none');
                if (!res.success || !res.lines || !res.lines.length) {
                    $('#eisRecallError').removeClass('d-none').text(res.message || 'No invoice lines found in local outbox.');
                    return;
                }
                rcOriginalLines = res.lines;
                renderAdjustmentLines(res.lines);
                $('#eisRecallForm').removeClass('d-none');
                $('#rcSubmitBtn').removeClass('d-none');
            },
            error: function() {
                $('#eisRecallSpinner').addClass('d-none');
                $('#eisRecallError').removeClass('d-none').text('Network error loading invoice lines. Please try again.');
            }
        });
    });

    function renderAdjustmentLines(lines) {
        let html = '';
        lines.forEach(function(line, i) {
            const origQty  = parseFloat(line.quantity)  || 0;
            const unitPrice= parseFloat(line.unitPrice) || 0;
            const origTotal= parseFloat(line.total)     || 0;
            const origVat  = parseFloat(line.totalVAT)  || 0;
            const vatRatio = origTotal > 0 ? origVat / origTotal : 0;

            html += '<tr data-line-index="' + i + '"' +
                    ' data-unit-price="' + unitPrice + '"' +
                    ' data-tax-rate-id="' + escHtml(line.taxRateId || '') + '"' +
                    ' data-vat-ratio="' + vatRatio + '"' +
                    ' data-is-product="' + (line.isProduct ? '1' : '0') + '"' +
                    ' data-product-code="' + escHtml(line.productCode || '') + '"' +
                    ' data-description="' + escHtml(line.description || '') + '"' +
                    ' data-discount="' + (parseFloat(line.discount) || 0) + '">' +
                '<td>' + escHtml(line.productCode || '') + '</td>' +
                '<td>' + escHtml(line.description || '') + '</td>' +
                '<td class="text-end">' + unitPrice.toFixed(2) + '</td>' +
                '<td class="text-center">' + origQty.toFixed(0) + '</td>' +
                '<td class="text-center">' +
                    '<input type="number" class="form-control form-control-sm text-center rc-adj-qty" min="0" step="1" value="' + origQty.toFixed(0) + '">' +
                '</td>' +
                '<td class="text-end rc-line-total">' + origTotal.toFixed(2) + '</td>' +
                '<td class="text-end rc-line-vat">'   + origVat.toFixed(2)   + '</td>' +
                '</tr>';
        });
        $('#rcLinesTbody').html(html);
        recalcAdjTotals();
    }

    $(document).on('input', '.rc-adj-qty', function() {
        const $row = $(this).closest('tr');
        const adjQty    = Math.max(0, parseFloat($(this).val()) || 0);
        const unitPrice = parseFloat($row.data('unit-price'))  || 0;
        const vatRatio  = parseFloat($row.data('vat-ratio'))   || 0;
        const lineTotal = Math.round(adjQty * unitPrice * 100) / 100;
        const lineVat   = Math.round(lineTotal * vatRatio * 100) / 100;
        $row.find('.rc-line-total').text(lineTotal.toFixed(2));
        $row.find('.rc-line-vat').text(lineVat.toFixed(2));
        recalcAdjTotals();
    });

    function recalcAdjTotals() {
        let total = 0, vat = 0;
        $('#rcLinesTbody tr').each(function() {
            total += parseFloat($(this).find('.rc-line-total').text()) || 0;
            vat   += parseFloat($(this).find('.rc-line-vat').text())   || 0;
        });
        $('#rcAdjTotal').text(total.toFixed(2));
        $('#rcAdjVat').text(vat.toFixed(2));
    }

    function buildAdjustedLines() {
        const lines = [];
        $('#rcLinesTbody tr').each(function() {
            const $row    = $(this);
            const adjQty  = Math.max(0, parseFloat($row.find('.rc-adj-qty').val()) || 0);
            const unitPrice= parseFloat($row.data('unit-price'))  || 0;
            const vatRatio = parseFloat($row.data('vat-ratio'))   || 0;
            const lineTotal= Math.round(adjQty * unitPrice * 100) / 100;
            const lineVat  = Math.round(lineTotal * vatRatio * 100) / 100;
            const idx      = parseInt($row.data('line-index'));
            const orig     = rcOriginalLines[idx] || {};
            lines.push({
                productCode: $row.data('product-code'),
                description: $row.data('description'),
                unitPrice:   unitPrice,
                quantity:    adjQty,
                discount:    parseFloat($row.data('discount')) || 0,
                total:       lineTotal,
                totalVAT:    lineVat,
                taxRateId:   $row.data('tax-rate-id'),
                isProduct:   $row.data('is-product') === '1' || $row.data('is-product') === 1,
            });
        });
        return lines;
    }

    $('#rcSubmitBtn').on('click', function() {
        const reason = $('#rcReason').val().trim();
        if (!reason) {
            $('#rcReason').addClass('is-invalid');
            return;
        }
        $('#rcReason').removeClass('is-invalid');

        const adjustedLines = buildAdjustedLines();
        if (!adjustedLines.length) {
            $('#rcSubmitResult').removeClass('d-none alert-success').addClass('alert alert-danger').text('No line items to submit.');
            return;
        }

        const $btn = $(this);
        $btn.prop('disabled', true).text('Submitting…');

        $.ajax({
            url: 'eis_sale_action.php',
            type: 'POST',
            data: {
                action: 'adjust_invoice',
                transaction_id: rcTxn,
                reason: reason,
                adjusted_lines: JSON.stringify(adjustedLines),
            },
            dataType: 'json',
            success: function(res) {
                const $result = $('#rcSubmitResult');
                $result.removeClass('d-none alert-success alert-danger')
                       .addClass('alert ' + (res.success ? 'alert-success' : 'alert-danger'));
                if (res.success) {
                    const noteType = res.note_type ? ' (' + res.note_type + ' Note)' : '';
                    const newNum   = res.new_invoice_number ? ' New note: ' + res.new_invoice_number + '.' : '';
                    $result.text('Adjustment submitted to MRA EIS' + noteType + '.' + newNum);
                    $btn.prop('disabled', true).text('Done');
                    setTimeout(function() { bootstrap.Modal.getOrCreateInstance(document.getElementById('eisRecallModal')).hide(); }, 3000);
                } else {
                    $result.text(res.message || 'Adjustment failed.');
                    $btn.prop('disabled', false).text('Submit Adjustment');
                }
            },
            error: function() {
                $('#rcSubmitResult').removeClass('d-none alert-success').addClass('alert alert-danger').text('Network error. Please try again.');
                $btn.prop('disabled', false).text('Submit Adjustment');
            }
        });
    });

    $('#eisRecallModal').on('hidden.bs.modal', function() {
        rcTxn = '';
        rcOriginalLines = [];
    });

    // Cancel Receipt button — open modal
    $(document).on('click', '.eis-cancel-btn', function() {
        eisActionTxn = $(this).data('txn');
        $('#cancelTxnDisplay').text(eisActionTxn);
        $('#cancelReason').val('').removeClass('is-invalid');
        $('#cancelModalResult').addClass('d-none').text('');
        $('#confirmCancelBtn').prop('disabled', false).text('Submit Cancellation');
        bootstrap.Modal.getOrCreateInstance(document.getElementById('eisCancelModal')).show();
    });

    $('#eisCancelModal').on('hidden.bs.modal', function() {
        eisActionTxn = '';
    });

    $('#confirmCancelBtn').on('click', function() {
        const reason = $('#cancelReason').val().trim();
        if (!reason) {
            $('#cancelReason').addClass('is-invalid');
            return;
        }
        $('#cancelReason').removeClass('is-invalid');

        const $btn = $(this);
        $btn.prop('disabled', true).text('Submitting…');

        $.ajax({
            url: 'eis_sale_action.php',
            type: 'POST',
            data: { action: 'cancel', transaction_id: eisActionTxn, reason: reason },
            dataType: 'json',
            success: function(res) {
                const $result = $('#cancelModalResult');
                $result.removeClass('d-none alert-success alert-danger')
                       .addClass(res.success ? 'alert-success' : 'alert-danger')
                       .text(res.message);
                if (res.success) {
                    $btn.prop('disabled', true).text('Done');
                    setTimeout(function() { bootstrap.Modal.getOrCreateInstance(document.getElementById('eisCancelModal')).hide(); }, 2500);
                    showEisActionResult(res.message, true);
                } else {
                    $btn.prop('disabled', false).text('Submit Cancellation');
                }
            },
            error: function() {
                $('#cancelModalResult').removeClass('d-none alert-success').addClass('alert-danger alert').text('Request failed. Please try again.');
                $btn.prop('disabled', false).text('Submit Cancellation');
            }
        });
    });

    $('.contact-support-btn').on('click', function() {
        const $btn = $(this);
        const uniqueCode = $btn.data('unique-code');
        $btn.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Notifying...');
        $.ajax({
            url: '../../ajax/report_unmapped_product.php',
            type: 'POST',
            data: { unique_code: uniqueCode },
            dataType: 'json',
            success: function(res) {
                if (res.success) {
                    $btn.removeClass('btn-outline-danger').addClass('btn-outline-success').html('<i class="fas fa-check"></i> Support Notified');
                } else {
                    $btn.prop('disabled', false).html('<i class="fas fa-life-ring"></i> Contact Support');
                    alert(res.message || 'Could not notify support. Please try again.');
                }
            },
            error: function() {
                $btn.prop('disabled', false).html('<i class="fas fa-life-ring"></i> Contact Support');
                alert('Request failed. Please try again.');
            }
        });
    });
    </script>
<?php include __DIR__ . '/../../includes/footer.php'; ?>
