<?php
session_start();
include_once('../includes/config.php');

// Ensure PDO connection available
if (!isset($dbh) || !$dbh) {
    header('Content-Type: application/json');
    echo json_encode(['success' => false, 'message' => 'Database connection (PDO) not available']);
    exit();
}

// Quick sanity check: required POS tables
$requiredTables = ['tblpossales','tblpossaleitems','tblpospayments'];
$missing = [];
try {
    foreach ($requiredTables as $t) {
        $stmt = $dbh->query("SHOW TABLES LIKE '" . $t . "'");
        if ($stmt->rowCount() === 0) { $missing[] = $t; }
    }
} catch (Exception $e) {
    // ignore
}
if ($missing) {
    echo json_encode([
        'success' => false,
        'message' => 'Required POS tables missing',
        'error' => 'Missing: ' . implode(', ', $missing) . '. Run api/install-pos-tables.php or execute create_pos_tables.sql'
    ]);
    exit();
}

// Check if user is logged in
if (!isset($_SESSION['uid'])) {
    http_response_code(401);
    echo json_encode(['success' => false, 'message' => 'Unauthorized']);
    exit();
}

// Force JSON output and suppress default HTML notices
header('Content-Type: application/json');
ini_set('display_errors', 0);
error_reporting(E_ALL);

try {
    // Get JSON input
    $input = json_decode(file_get_contents('php://input'), true);
    
    if (!$input) {
        throw new Exception('Invalid JSON input');
    }
    
    // Validate required fields
    if (!isset($input['customer_id']) || !isset($input['cart_items']) || empty($input['cart_items'])) {
        throw new Exception('Customer ID and cart items are required');
    }
    
    $customerId = (int)$input['customer_id'];
    $paymentMethod = isset($input['payment_method']) ? $input['payment_method'] : 'Cash';
    $amountReceived = isset($input['amount_received']) ? (float)$input['amount_received'] : 0;
    $referenceNumber = isset($input['reference_number']) ? $input['reference_number'] : '';
    $notes = isset($input['notes']) ? $input['notes'] : '';
    $discountAmount = isset($input['discount_amount']) ? (float)$input['discount_amount'] : 0;
    $cartItems = $input['cart_items'];
    $userId = $_SESSION['uid'];
    $userName = $_SESSION['name'] ?? 'Unknown';
    $pendingOrderId = isset($input['pending_order_id']) ? (int)$input['pending_order_id'] : null;
    
    // Start transaction
    $dbh->beginTransaction();
    
    try {
        $saleDate = date('Y-m-d');
        $saleTime = date('H:i:s');
        $saleNumber = 'POS-' . date('Ymd') . '-' . str_pad(rand(1, 9999), 4, '0', STR_PAD_LEFT);
        
        // Calculate totals
        $subTotal = 0;
        $totalAmount = 0;
        
        // Validate cart items and calculate totals
        foreach ($cartItems as $item) {
            $productId = (int)$item['product_id'];
            $quantityInBags = (float)$item['quantity'];
            $ratePerKg = (float)$item['rate'];
            $bagKg = (float)$item['bag_kg'];
            
            if ($quantityInBags <= 0 || $ratePerKg <= 0 || $bagKg <= 0) {
                throw new Exception('Invalid quantity, rate, or bag weight for product ID: ' . $productId);
            }
            
            // Check current stock (in bags)
            $stockQuery = "SELECT StockInBags, RiceBagName, BagKg FROM tblricebags WHERE ID = ? AND IsActive = 1";
            $stmt = $dbh->prepare($stockQuery);
            $stmt->execute([$productId]);
            $product = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if (!$product) {
                throw new Exception('Product not found or inactive: ' . $productId);
            }
            
            if ($product['StockInBags'] < $quantityInBags) {
                throw new Exception('Insufficient stock for ' . $product['RiceBagName'] . '. Available: ' . $product['StockInBags'] . ' bags');
            }
            
            // Calculate line total (bags * rate per kg * kg per bag)
            $lineTotal = $quantityInBags * $ratePerKg * $bagKg;
            $subTotal += $lineTotal;
        }
        
        // Apply discount
        $totalAmount = $subTotal - $discountAmount;
        $balanceAmount = $totalAmount - $amountReceived;
        $changeAmount = $amountReceived > $totalAmount ? $amountReceived - $totalAmount : 0;
        
        // Determine payment status
        $paymentStatus = 'Paid';
        if ($amountReceived < $totalAmount) {
            $paymentStatus = $amountReceived > 0 ? 'Partial' : 'Pending';
        }
        
        // Create main POS sale record
        $saleQuery = "
            INSERT INTO tblpossales 
            (SaleNumber, SaleDate, SaleTime, CustomerID, SubTotal, DiscountAmount, TotalAmount, 
             PaidAmount, ChangeAmount, BalanceAmount, PaymentMethod, PaymentStatus, SaleStatus, 
             Notes, ReferenceNumber, CashierID, CashierName, CreatedAt) 
            VALUES 
            (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'Completed', ?, ?, ?, ?, NOW())
        ";
        
        $stmt = $dbh->prepare($saleQuery);
        $result = $stmt->execute([
            $saleNumber, $saleDate, $saleTime, $customerId, $subTotal, $discountAmount, 
            $totalAmount, $amountReceived, $changeAmount, $balanceAmount, $paymentMethod, 
            $paymentStatus, $notes, $referenceNumber, $userId, $userName
        ]);
        
        if (!$result) {
            throw new Exception('Failed to create POS sale record');
        }
        
        $saleId = $dbh->lastInsertId();
        
        // Create sale items and update stock
        foreach ($cartItems as $item) {
            $productId = (int)$item['product_id'];
            $quantityInBags = (float)$item['quantity'];
            $ratePerKg = (float)$item['rate'];
            $bagKg = (float)$item['bag_kg'];
            $lineTotal = $quantityInBags * $ratePerKg * $bagKg;
            
            // Get product details
            $productQuery = "SELECT RiceBagName, Brand, CurrentStock, StockInBags FROM tblricebags WHERE ID = ?";
            $stmt = $dbh->prepare($productQuery);
            $stmt->execute([$productId]);
            $product = $stmt->fetch(PDO::FETCH_ASSOC);
            
            // Create sale item record (store quantity in bags but calculate per kg for compatibility)
            $itemQuery = "
                INSERT INTO tblpossaleitems 
                (SaleID, ProductID, ProductName, ProductCode, Quantity, UnitPrice, LineTotal) 
                VALUES 
                (?, ?, ?, ?, ?, ?, ?)
            ";
            
            $stmt = $dbh->prepare($itemQuery);
            $stmt->execute([
                $saleId, $productId, $product['RiceBagName'] . ' (' . $quantityInBags . ' bags)', 
                $product['Brand'], $quantityInBags, $ratePerKg * $bagKg, $lineTotal
            ]);
            
            // Update product stock (reduce both bag count and kg)
            $newStockInBags = $product['StockInBags'] - $quantityInBags;
            $quantityInKg = $quantityInBags * $bagKg;
            $newStockInKg = $product['CurrentStock'] - $quantityInKg;
            
            $updateStockQuery = "UPDATE tblricebags SET CurrentStock = ?, StockInBags = ? WHERE ID = ?";
            $stmt = $dbh->prepare($updateStockQuery);
            $stmt->execute([$newStockInKg, $newStockInBags, $productId]);
            
            // Create stock adjustment record
            $refNumber = $saleNumber;
            $adjustmentQuery = "
                INSERT INTO tblstockadjustments 
                (RiceBagID, AdjustmentType, Quantity, PreviousStock, NewStock, Reason, 
                 ReferenceNumber, AdjustmentDate, Status, CreatedBy, CreatedDate) 
                VALUES 
                (?, 'Remove', ?, ?, ?, 'POS Sale (Bags)', ?, ?, 'Approved', ?, NOW())
            ";
            
            $stmt = $dbh->prepare($adjustmentQuery);
            $stmt->execute([
                $productId, $quantityInBags, $product['StockInBags'], $newStockInBags, 
                $refNumber, $saleDate, $userId
            ]);
        }
        
        // Create payment record if amount received
        if ($amountReceived > 0) {
            $paymentQuery = "
                INSERT INTO tblpospayments 
                (SaleID, PaymentMethod, Amount, ReferenceNumber, PaymentDate, Status, Notes, CreatedBy) 
                VALUES 
                (?, ?, ?, ?, NOW(), 'Completed', ?, ?)
            ";
            
            $stmt = $dbh->prepare($paymentQuery);
            $stmt->execute([
                $saleId, $paymentMethod, $amountReceived, $referenceNumber, 
                'Payment for ' . $saleNumber, $userId
            ]);
        }
        
        // Create customer payment record (for backward compatibility)
        $customerPaymentQuery = "
            INSERT INTO tblcustomerpayments 
            (CustomerID, TransactionType, Amount, PaymentMethod, ReferenceNumber, 
             TransactionDate, Description, Status, CreatedBy, CreatedDate) 
            VALUES 
            (?, 'Debit', ?, ?, ?, ?, ?, 'Completed', ?, NOW())
        ";
        
        $stmt = $dbh->prepare($customerPaymentQuery);
        $stmt->execute([
            $customerId, $totalAmount, $paymentMethod, $saleNumber, 
            $saleDate, 'POS Sale - ' . $saleNumber . ($notes ? ' - ' . $notes : ''), $userId
        ]);
        
        // If partial or full payment received, create credit entry
        if ($amountReceived > 0) {
            $paymentReceivedQuery = "
                INSERT INTO tblcustomerpayments 
                (CustomerID, TransactionType, Amount, PaymentMethod, ReferenceNumber, 
                 TransactionDate, Description, Status, CreatedBy, CreatedDate) 
                VALUES 
                (?, 'Credit', ?, ?, ?, ?, ?, 'Completed', ?, NOW())
            ";
            
            $stmt = $dbh->prepare($paymentReceivedQuery);
            $stmt->execute([
                $customerId, $amountReceived, $paymentMethod, $saleNumber, 
                $saleDate, 'Payment Received - ' . $saleNumber, $userId
            ]);
        }
        
        // Mark pending order as delivered if this is a delivery
        if ($pendingOrderId) {
            $updateOrderQuery = "
                UPDATE tblpendingorders 
                SET OrderStatus = 'Delivered', DeliveryDate = CURDATE(), DeliveryTime = CURTIME()
                WHERE ID = ?
            ";
            $stmt = $dbh->prepare($updateOrderQuery);
            $stmt->execute([$pendingOrderId]);
        }
        
        // Commit transaction
        $dbh->commit();
        
        // Return success response
        echo json_encode([
            'success' => true,
            'message' => 'Sale completed successfully',
            'data' => [
                'sale_id' => $saleId,
                'sale_number' => $saleNumber,
                'total_amount' => $totalAmount,
                'paid_amount' => $amountReceived,
                'balance_amount' => $balanceAmount,
                'change_amount' => $changeAmount,
                'payment_status' => $paymentStatus,
                'print_receipt_url' => 'api/print-receipt.php?sale_id=' . $saleId
            ]
        ]);
        
    } catch (Exception $e) {
        $dbh->rollBack();
        throw $e;
    }
    
} catch (PDOException $e) {
    if (isset($dbh) && $dbh->inTransaction()) {
        $dbh->rollBack();
    }
    echo json_encode([
        'success' => false,
        'message' => 'Database error: ' . $e->getMessage(),
        'error' => $e->getCode()
    ]);
} catch (Exception $e) {
    if (isset($dbh) && $dbh->inTransaction()) {
        $dbh->rollBack();
    }
    echo json_encode([
        'success' => false,
        'message' => $e->getMessage(),
        'error' => 'GENERAL'
    ]);
}
?>
