<?php
class PosController {
    public function index(): void {
        Auth::requireLogin();
        $tenantId = Auth::tenantId();

        // Get active customers for selection
        $customers = db()->prepare("SELECT id, name, phone FROM customers WHERE tenant_id=? AND is_active=1 ORDER BY name ASC");
        $customers->execute([$tenantId]);
        $customers = $customers->fetchAll();

        // Get shop locations (stores and outlets only) for the tenant
        $locations = Location::shopLocations();
        
        $user = Auth::user();
        $defaultLocationId = null;
        
        if (!empty($user['location_id'])) {
            // Filter locations to only the one assigned to the user
            $locations = array_filter($locations, fn($l) => $l['id'] == $user['location_id']);
            $defaultLocationId = $user['location_id'];
        }

        // Load payment methods settings
        $stmt = db()->prepare("SELECT * FROM settings WHERE tenant_id=?");
        $stmt->execute([$tenantId]);
        $settingsRaw = $stmt->fetchAll();
        $settings = [];
        foreach ($settingsRaw as $s) { $settings[$s['setting_key']] = $s['setting_value']; }

        $pageTitle = 'POS Terminal';
        $currencySymbol = $settings['currency_symbol'] ?? 'GH₵';
        $defaultTaxRate = $settings['tax_rate'] ?? 0;
        $taxEnabled = $settings['tax_enabled'] ?? 0;
        $defaultCustomerId = $settings['default_customer_id'] ?? null;
        
        // Only use settings default if user isn't restricted to a location
        if ($defaultLocationId === null) {
            $defaultLocationId = $settings['default_location_id'] ?? null;
        }

        // POS usually has its own clean layout or no sidebar
        ob_start();
        include APP_ROOT . '/views/tenant/pos/index.php';
        $content = ob_get_clean();

        include APP_ROOT . '/views/tenant/layouts/main.php';
    }

    public function searchProducts(): void {
        Auth::requireLogin();
        $tenantId = Auth::tenantId();
        $query = $_GET['q'] ?? '';
        $categoryId = $_GET['category_id'] ?? '';
        $brandId = $_GET['brand_id'] ?? '';
        
        $user = Auth::user();
        $locationId = !empty($user['location_id']) ? (int)$user['location_id'] : ($_GET['location_id'] ?? '');

        $where = "p.tenant_id = ? AND p.is_active = 1";
        $params = [$tenantId];

        if ($query) {
            $where .= " AND (p.name LIKE ? OR p.sku LIKE ? OR p.barcode LIKE ?)";
            $params[] = "%$query%";
            $params[] = "%$query%";
            $params[] = "%$query%";
        }

        if ($categoryId) {
            $where .= " AND p.category_id = ?";
            $params[] = $categoryId;
        }

        if ($brandId) {
            $where .= " AND p.brand_id = ?";
            $params[] = $brandId;
        }

        $limit = $query ? 20 : 50;

        // Use stock table with location filtering for accurate current stock
        // Build stock filter parameters (these come first in the SQL order)
        $stockParams = [$tenantId];
        $stockFilter = "WHERE s.tenant_id = ?";
        if ($locationId && $locationId > 0) {
            $stockFilter .= " AND s.location_id = ?";
            $stockParams[] = $locationId;
        }

        // Merge stock params first, then WHERE params
        $mainParams = array_merge($stockParams, $params);

        $stmt = db()->prepare(
            "SELECT p.*, COALESCE(sq.stock_sum, 0) as stock_qty
             FROM products p
             LEFT JOIN (
                 SELECT s.product_id, SUM(s.quantity) as stock_sum
                 FROM stock s
                 {$stockFilter}
                 GROUP BY s.product_id
             ) sq ON sq.product_id = p.id
             WHERE $where
             LIMIT $limit"
        );
        $stmt->execute($mainParams);
        $products = $stmt->fetchAll();

        header('Content-Type: application/json');
        echo json_encode($products);
    }

    public function store(): void {
        Auth::requireLogin();
        Security::checkCsrf();
        $tenantId = Auth::tenantId();

        $data = json_decode(file_get_contents('php://input'), true);
        if (!$data) {
            echo json_encode(['success' => false, 'message' => 'Invalid data']);
            return;
        }
        
        // Enforce location restriction
        $user = Auth::user();
        if (!empty($user['location_id'])) {
            $data['location_id'] = (int)$user['location_id'];
        }

        try {
            db()->beginTransaction();

            $saleNo = 'SALE-' . strtoupper(substr(uniqid(), -8));
            $type = $data['type'] ?? 'pos';
            $status = $data['status'] ?? 'completed';
            $paymentMethod = $data['payment_method'] ?? 'cash';
            $paymentStatus = $data['payment_status'] ?? 'paid';

            // 1. Create Sale Record
            $amountTendered = isset($data['amount_paid']) ? (float)$data['amount_paid'] : (float)($data['payable'] ?? $data['total']);
            $changeDue = (float)($data['change_due'] ?? 0);
            $amountPaid = max(0, $amountTendered - $changeDue);
            $amountPaid = min($amountPaid, (float)$data['total']);
            
            // Calculate subtotal (total before tax and shipping)
            $subtotal = (float)$data['total'] - ((float)($data['tax'] ?? 0) + (float)($data['shipping'] ?? 0) - (float)($data['discount'] ?? 0));

            $stmt = db()->prepare(
                "INSERT INTO sales (tenant_id, user_id, customer_id, location_id, sale_no, type, subtotal, total, tax_amount, shipping_amount, discount_amount, amount_paid, change_due, payment_method, payment_status, status)
                 VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
            );
            $stmt->execute([
                $tenantId,
                Auth::userId(),
                $data['customer_id'] ?: null,
                $data['location_id'],
                $saleNo,
                $type,
                $subtotal,
                $data['total'],
                $data['tax'] ?? 0,
                $data['shipping'] ?? 0,
                $data['discount'] ?? 0,
                $amountPaid,
                $changeDue,
                $paymentMethod,
                $paymentStatus,
                $status
            ]);
            $saleId = db()->lastInsertId();

            // 2. Add Sale Items
            foreach ($data['items'] as $item) {
                $stmt = db()->prepare(
                    "INSERT INTO sale_items (tenant_id, sale_id, product_id, quantity, unit_price, total)
                     VALUES (?,?,?,?,?,?)"
                );
                $stmt->execute([
                    $tenantId,
                    $saleId,
                    $item['id'],
                    $item['qty'],
                    $item['price'],
                    $item['qty'] * $item['price']
                ]);

                // Only deduct stock for completed sales (not drafts, quotations, or suspended)
                if ($status === 'completed') {
                    ensureStockAvailable($item['id'], $data['location_id'], -$item['qty'], null, $tenantId);
                    adjustStock($item['id'], $data['location_id'], -$item['qty'], null, $tenantId);
                    logMovement($item['id'], $data['location_id'], 'sale', -$item['qty'], $saleNo, '', null, $tenantId);
                }
            }

            // 3. Add payment records for split payments
            if (!empty($data['payments']) && is_array($data['payments'])) {
                foreach ($data['payments'] as $payment) {
                    $stmt = db()->prepare(
                        "INSERT INTO payments (tenant_id, type, reference_id, amount, method, note, user_id)
                         VALUES (?,?,?,?,?,?,?)"
                    );
                    $stmt->execute([
                        $tenantId,
                        'sale',
                        $saleId,
                        $payment['amount'],
                        $payment['method'],
                        $payment['note'] ?? '',
                        Auth::userId()
                    ]);
                }
            }

            db()->commit();
            header('Content-Type: application/json');
            echo json_encode(['success' => true, 'sale_id' => $saleId, 'sale_no' => $saleNo]);

        } catch (Exception $e) {
            db()->rollBack();
            header('Content-Type: application/json');
            echo json_encode(['success' => false, 'message' => $e->getMessage()]);
        }
    }

    public function suspend(): void {
        Auth::requireLogin();
        Security::checkCsrf();
        $tenantId = Auth::tenantId();

        $data = json_decode(file_get_contents('php://input'), true);
        if (!$data) {
            echo json_encode(['success' => false, 'message' => 'Invalid data']);
            return;
        }

        // Enforce location restriction
        $user = Auth::user();
        if (!empty($user['location_id'])) {
            $data['location_id'] = (int)$user['location_id'];
        }

        try {
            db()->beginTransaction();

            $saleNo = 'SUSP-' . strtoupper(substr(uniqid(), -8));

            $stmt = db()->prepare(
                "INSERT INTO sales (tenant_id, user_id, customer_id, location_id, sale_no, type, total, tax_amount, shipping_amount, discount_amount, amount_paid, payment_method, payment_status, status, suspended_at)
                 VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())"
            );
            $stmt->execute([
                $tenantId,
                Auth::userId(),
                $data['customer_id'] ?: null,
                $data['location_id'],
                $saleNo,
                'pos',
                $data['total'],
                $data['tax'] ?? 0,
                $data['shipping'] ?? 0,
                $data['discount'] ?? 0,
                0,
                'cash',
                'credit',
                'suspended'
            ]);
            $saleId = db()->lastInsertId();

            foreach ($data['items'] as $item) {
                $stmt = db()->prepare(
                    "INSERT INTO sale_items (tenant_id, sale_id, product_id, quantity, unit_price, total)
                     VALUES (?,?,?,?,?,?)"
                );
                $stmt->execute([
                    $tenantId,
                    $saleId,
                    $item['id'],
                    $item['qty'],
                    $item['price'],
                    $item['qty'] * $item['price']
                ]);
            }

            db()->commit();
            header('Content-Type: application/json');
            echo json_encode(['success' => true, 'sale_id' => $saleId, 'sale_no' => $saleNo]);

        } catch (Exception $e) {
            db()->rollBack();
            header('Content-Type: application/json');
            echo json_encode(['success' => false, 'message' => $e->getMessage()]);
        }
    }

    public function resume(string $id): void {
        Auth::requireLogin();
        $tenantId = Auth::tenantId();

        $stmt = db()->prepare(
            "SELECT s.*, si.product_id, si.quantity, si.unit_price, p.name as product_name, p.sku as product_sku
             FROM sales s
             LEFT JOIN sale_items si ON s.id = si.sale_id
             LEFT JOIN products p ON si.product_id = p.id
             WHERE s.id = ? AND s.tenant_id = ? AND s.status = 'suspended'"
        );
        $stmt->execute([$id, $tenantId]);
        $sale = $stmt->fetchAll();

        if (!$sale) {
            header('Content-Type: application/json');
            echo json_encode(['success' => false, 'message' => 'Suspended order not found']);
            return;
        }

        $items = [];
        foreach ($sale as $row) {
            if ($row['product_id']) {
                $items[] = [
                    'id' => $row['product_id'],
                    'qty' => $row['quantity'],
                    'price' => $row['unit_price'],
                    'name' => $row['product_name'],
                    'sku' => $row['product_sku']
                ];
            }
        }

        header('Content-Type: application/json');
        echo json_encode([
            'success' => true,
            'customer_id' => $sale[0]['customer_id'],
            'location_id' => $sale[0]['location_id'],
            'total' => $sale[0]['total'],
            'tax' => $sale[0]['tax_amount'],
            'shipping' => $sale[0]['shipping_amount'] ?? 0,
            'discount' => $sale[0]['discount_amount'],
            'items' => $items
        ]);
    }

    public function recentTransactions(): void {
        Auth::requireLogin();
        $tenantId = Auth::tenantId();

        $stmt = db()->prepare(
            "SELECT id, sale_no, total, payment_method, payment_status, status, created_at
             FROM sales
             WHERE tenant_id = ? AND status != 'suspended'
             ORDER BY created_at DESC LIMIT 10"
        );
        $stmt->execute([$tenantId]);
        $transactions = $stmt->fetchAll();

        header('Content-Type: application/json');
        echo json_encode($transactions);
    }

    public function suspendedOrders(): void {
        Auth::requireLogin();
        $tenantId = Auth::tenantId();

        $stmt = db()->prepare(
            "SELECT id, sale_no, total, customer_id, suspended_at
             FROM sales
             WHERE tenant_id = ? AND status = 'suspended'
             ORDER BY suspended_at DESC"
        );
        $stmt->execute([$tenantId]);
        $orders = $stmt->fetchAll();

        header('Content-Type: application/json');
        echo json_encode($orders);
    }

    public function categories(): void {
        Auth::requireLogin();
        $tenantId = Auth::tenantId();

        $stmt = db()->prepare("SELECT id, name FROM categories WHERE tenant_id = ? ORDER BY name ASC");
        $stmt->execute([$tenantId]);
        $categories = $stmt->fetchAll();

        header('Content-Type: application/json');
        echo json_encode($categories);
    }
}
