<?php
// Inventory has no Composer dependencies. Loading the project-wide autoloader
// here made every inventory consumer (including the POS sale page) fail before
// rendering when optional packages required a newer PHP runtime.
require_once 'Logger.php';
require_once 'Tracking.php';

class Inventory {
    private $conn;
    private $table_name = "items";
    private $barcodeDir;
    private $lastError;
    private $logger;
    private $tracking;

    public function __construct($conn, $logger = null) {
        $this->conn = $conn;
        $this->logger = $logger;
        $this->tracking = new Tracking($conn, $logger);
        $this->barcodeDir = __DIR__ . '/../assets/barcodes/';

        if (!is_dir($this->barcodeDir)) {
            if (!mkdir($this->barcodeDir, 0755, true)) {
                error_log("Failed to create barcode directory: " . $this->barcodeDir);
            }
        }

        error_log("Barcode directory set to: " . $this->barcodeDir);
    }

    private function columnExists($table, $column) {
        $stmt = $this->conn->prepare("SHOW COLUMNS FROM `$table` LIKE :column_name");
        $stmt->execute([':column_name' => $column]);
        return (bool)$stmt->fetch(PDO::FETCH_ASSOC);
    }

    private function productCodeForItemName($itemName) {
        $name = strtoupper(trim((string)$itemName));
        $base = preg_replace('/[^A-Z0-9]+/', '-', $name);
        $base = trim((string)$base, '-');
        if ($base === '') {
            $base = 'ITEM';
        }

        return substr('IMS-' . $base . '-' . substr(sha1($name), 0, 8), 0, 120);
    }

    private function generateBarcodeImage($unique_code, $barcode_type = 'C128B') {
        if (empty($unique_code)) {
            $this->lastError = "Empty unique code provided.";
            return false;
        }

        try {
            error_log("Generating barcode for unique_code: " . $unique_code);
            
           /* $barcode = new \Com\Tecnick\Barcode\Barcode\Barcode();
            $bobj = $barcode->getBarcodeObj(
                $barcode_type, 
                $unique_code, 
                150,
                30,
                'black',
                array(2, 2, 2, 2)
            );

            $barcode_image = $bobj->getPngData();

            if (!$barcode_image) {
                $this->lastError = "Failed to generate barcode PNG for code: '$unique_code'";
                error_log($this->lastError);
                return false;
            }


            */
            $safe_filename = preg_replace('/[^a-zA-Z0-9_-]/', '_', $unique_code);
            $timestamp = time();
            $image_filename = $safe_filename . '_' . $timestamp . '.png';
            $full_path = $this->barcodeDir . $image_filename;

          /*
            if (file_put_contents($full_path, $barcode_image) === false) {
                $this->lastError = "Failed to save barcode image to: " . $full_path;
                error_log($this->lastError);
                return false;
            } */

            $relative_path = 'assets/barcodes/' . $image_filename;
            error_log("Barcode generated successfully: " . $relative_path . " (Full path: " . $full_path . ")");
            
            if (!file_exists($full_path)) {
                $this->lastError = "Barcode file was not created properly: " . $full_path;
                error_log($this->lastError);
                return false;
            }
            
            return $relative_path;

        } catch (Exception $e) {
            $this->lastError = "Exception during barcode generation: " . $e->getMessage();
            error_log("Barcode generation exception: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Builds and runs "SELECT $selectCols FROM items i WHERE $baseWhere [AND search]
     * ORDER BY $orderBy [LIMIT ? OFFSET ?]". $orderBy must be a caller-controlled
     * whitelist string, never raw user input.
     */
    private function fetchPaged(
        string $selectCols,
        string $baseWhere,
        array $baseParams,
        array $searchableCols = [],
        ?string $searchTerm = null,
        string $orderBy = 'i.item_id DESC',
        ?int $limit = null,
        int $offset = 0
    ): array {
        [$where, $params] = $this->applySearch($baseWhere, $baseParams, $searchableCols, $searchTerm);

        $sql = "SELECT $selectCols FROM items i WHERE $where ORDER BY $orderBy";
        if ($limit !== null) {
            $sql .= " LIMIT ? OFFSET ?";
        }

        $stmt = $this->conn->prepare($sql);
        $index = 1;
        foreach ($params as $param) {
            $stmt->bindValue($index++, $param, is_int($param) ? PDO::PARAM_INT : PDO::PARAM_STR);
        }
        if ($limit !== null) {
            $stmt->bindValue($index++, $limit, PDO::PARAM_INT);
            $stmt->bindValue($index++, $offset, PDO::PARAM_INT);
        }
        $stmt->execute();

        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    /** Counts rows matching the same base/search conditions as fetchPaged(), no LIMIT. */
    private function countPaged(
        string $baseWhere,
        array $baseParams,
        array $searchableCols = [],
        ?string $searchTerm = null
    ): int {
        [$where, $params] = $this->applySearch($baseWhere, $baseParams, $searchableCols, $searchTerm);

        $stmt = $this->conn->prepare("SELECT COUNT(*) FROM items i WHERE $where");
        $index = 1;
        foreach ($params as $param) {
            $stmt->bindValue($index++, $param, is_int($param) ? PDO::PARAM_INT : PDO::PARAM_STR);
        }
        $stmt->execute();

        return (int)$stmt->fetchColumn();
    }

    private function applySearch(string $baseWhere, array $baseParams, array $searchableCols, ?string $searchTerm): array {
        if (empty($searchTerm) || empty($searchableCols)) {
            return [$baseWhere, $baseParams];
        }

        $clauses = [];
        foreach ($searchableCols as $col) {
            $clauses[] = "$col LIKE ?";
            $baseParams[] = "%$searchTerm%";
        }

        return [$baseWhere . " AND (" . implode(' OR ', $clauses) . ")", $baseParams];
    }

    public function generateUniqueCodes($preCode, $quantity, array $reservedCodes = []) {
        if (empty($preCode) || !is_numeric($quantity) || $quantity <= 0 || $quantity > 1000) {
            return false;
        }

        $codes = [];
        $prefix = trim($preCode);
        $lastNumber = 0;
        $numberWidth = 5;
        $usedCodes = [];

        // Read every code with this exact prefix and derive the highest numeric
        // suffix. Ordering unique_code as text is unreliable once a sequence
        // grows beyond its original padding width or includes manual codes.
        $stmt = $this->conn->prepare(
            "SELECT unique_code FROM items
             WHERE LEFT(unique_code, CHAR_LENGTH(?)) = ?"
        );
        $stmt->execute([$prefix, $prefix]);
        $existingCodes = $stmt->fetchAll(PDO::FETCH_COLUMN);

        foreach (array_merge($existingCodes, $reservedCodes) as $existingCode) {
            $existingCode = trim((string)$existingCode);
            if ($existingCode === '') {
                continue;
            }

            $usedCodes[strtolower($existingCode)] = true;
            if (strncasecmp($existingCode, $prefix, strlen($prefix)) !== 0) {
                continue;
            }

            $numberPart = substr($existingCode, strlen($prefix));
            if ($numberPart !== '' && ctype_digit($numberPart)) {
                $lastNumber = max($lastNumber, (int)$numberPart);
                $numberWidth = max($numberWidth, strlen($numberPart));
            }
        }

        $currentNumber = $lastNumber + 1;

        for ($i = 0; $i < $quantity; $i++) {
            do {
                $uniqueNumber = str_pad((string)$currentNumber, $numberWidth, '0', STR_PAD_LEFT);
                $fullCode = $prefix . $uniqueNumber;
                $currentNumber++;
            } while (isset($usedCodes[strtolower($fullCode)]));

            $codes[] = $fullCode;
            $usedCodes[strtolower($fullCode)] = true;
        }

        return $codes;
    }

    public function getAllItems() {
        $sql = "SELECT * FROM items";
        $stmt = $this->conn->prepare($sql);
        $stmt->execute();
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public function getItemById($itemId) {
        $sql = "SELECT * FROM items WHERE item_id = :item_id";
        $stmt = $this->conn->prepare($sql);
        $stmt->bindParam(':item_id', $itemId);
        $stmt->execute();
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }

    public function getLastInsertedItems($count) {
        $sql = "SELECT * FROM items ORDER BY item_id DESC LIMIT :count";
        $stmt = $this->conn->prepare($sql);
        $stmt->bindParam(':count', $count, PDO::PARAM_INT);
        $stmt->execute();
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public function recordSale($branchId, $itemId, $quantity, $unitPrice, $soldBy) {
        $totalPrice = $quantity * $unitPrice;
        
        $this->conn->beginTransaction();
        
        try {
            $sql = "INSERT INTO sold_items (branch_id, item_id, unit_price, total_price, sold_by)
                    VALUES (:branch_id, :item_id, :unit_price, :total_price, :sold_by)";
            $stmt = $this->conn->prepare($sql);
            $stmt->bindParam(':branch_id', $branchId);
            $stmt->bindParam(':item_id', $itemId);
            $stmt->bindParam(':unit_price', $unitPrice);
            $stmt->bindParam(':total_price', $totalPrice);
            $stmt->bindParam(':sold_by', $soldBy);
            $stmt->execute();
            
            $this->conn->commit();
            return true;
        } catch (Exception $e) {
            $this->conn->rollBack();
            error_log("Error recording sale: " . $e->getMessage());
            return false;
        }
    }

    public function generateSalesReport($branchId, $startDate, $endDate) {
        $sql = "INSERT INTO sales_reports (branch_id, report_start_date, report_end_date, total_sales, total_items_sold)
                SELECT :branch_id, :start_date, :end_date, SUM(total_price), SUM(quantity)
                FROM sold_items
                WHERE branch_id = :branch_id AND sold_at BETWEEN :start_date AND :end_date";
        $stmt = $this->conn->prepare($sql);
        $stmt->bindParam(':branch_id', $branchId);
        $stmt->bindParam(':start_date', $startDate);
        $stmt->bindParam(':end_date', $endDate);
        return $stmt->execute();
    }

    private function simpleItemsQuery($branchId, string $shelfStatus): array {
        $selectCols = "i.item_id, i.item_name, i.item_details, i.category, i.unique_code as unique_id, i.unit_price,
                       i.current_location_id, i.created_at AS date_entered, i.barcode_image_path";
        $where = "(i.serial_number IS NULL OR i.serial_number = '')
                  AND i.shelf_status = ?
                  AND (i.technical_specs IS NULL OR i.technical_specs = '' OR i.technical_specs = 'No technical specifications provided')
                  AND i.item_id NOT IN (SELECT item_id FROM sold_items WHERE is_verified = 1)";
        $params = [$shelfStatus];

        if ($branchId !== null) {
            $where .= " AND i.current_location_id = ?";
            $params[] = (int)$branchId;
        }

        $searchableCols = ['i.unique_code', 'i.item_name', 'i.item_details'];

        return [$selectCols, $where, $params, $searchableCols];
    }

    public function getSimpleItems($branchId = null, ?string $searchTerm = null, string $orderBy = 'i.item_name ASC', ?int $limit = null, int $offset = 0) {
        [$selectCols, $where, $params, $searchableCols] = $this->simpleItemsQuery($branchId, 'on_shelf');
        return $this->fetchPaged($selectCols, $where, $params, $searchableCols, $searchTerm, $orderBy, $limit, $offset);
    }

    public function countSimpleItems($branchId = null, ?string $searchTerm = null): int {
        [, $where, $params, $searchableCols] = $this->simpleItemsQuery($branchId, 'on_shelf');
        return $this->countPaged($where, $params, $searchableCols, $searchTerm);
    }

    public function getSimpleItemsDamaged($branchId = null, ?string $searchTerm = null, string $orderBy = 'i.item_name ASC', ?int $limit = null, int $offset = 0) {
        [$selectCols, $where, $params, $searchableCols] = $this->simpleItemsQuery($branchId, 'damaged');
        return $this->fetchPaged($selectCols, $where, $params, $searchableCols, $searchTerm, $orderBy, $limit, $offset);
    }

    public function countSimpleItemsDamaged($branchId = null, ?string $searchTerm = null): int {
        [, $where, $params, $searchableCols] = $this->simpleItemsQuery($branchId, 'damaged');
        return $this->countPaged($where, $params, $searchableCols, $searchTerm);
    }

    private function simpleItemsAssetsQuery($branchId): array {
        $selectCols = "i.item_id, i.item_name, i.item_details, i.unique_code as unique_id, i.unit_price,
                         i.warranty_months as warranty, i.serial_number, i.technical_specs,
                         i.condition_status, i.created_at AS date_entered, i.barcode_image_path";
        $where = "i.shelf_status = 'asset' AND i.item_id NOT IN (SELECT item_id FROM sold_items WHERE is_verified = 1)";
        $params = [];

        if ($branchId !== null) {
            $where .= " AND i.current_location_id = ?";
            $params[] = (int)$branchId;
        }

        $searchableCols = ['i.unique_code', 'i.item_name', 'i.item_details', 'i.serial_number', 'i.technical_specs'];

        return [$selectCols, $where, $params, $searchableCols];
    }

    public function getSimpleItemsAssets($branchId = null, ?string $searchTerm = null, string $orderBy = 'i.item_name ASC', ?int $limit = null, int $offset = 0) {
        [$selectCols, $where, $params, $searchableCols] = $this->simpleItemsAssetsQuery($branchId);
        return $this->fetchPaged($selectCols, $where, $params, $searchableCols, $searchTerm, $orderBy, $limit, $offset);
    }

    public function countSimpleItemsAssets($branchId = null, ?string $searchTerm = null): int {
        [, $where, $params, $searchableCols] = $this->simpleItemsAssetsQuery($branchId);
        return $this->countPaged($where, $params, $searchableCols, $searchTerm);
    }


    private function detailedItemsQuery($branchId): array {
        $selectCols = "i.item_id, i.item_name, i.item_details, i.category, i.unique_code as unique_id, i.unit_price,
            i.warranty_months as warranty, i.serial_number, i.technical_specs,
            i.condition_status, i.current_location_id, i.created_at AS date_entered, i.barcode_image_path";
        // is_verified only reflects whether the sale's weekly report has been
        // verified/rejected — it does NOT mean the item is still unsold (a sale
        // stays in sold_items, just un-verified, even if its report is later
        // rejected). Any sold_items row at all means the item is gone from stock.
        $where = "i.shelf_status = 'on_shelf'
          AND NOT EXISTS (SELECT 1 FROM sold_items s WHERE s.item_id = i.item_id)
          AND NOT EXISTS (SELECT 1 FROM missing_items m WHERE m.unique_code = i.unique_code)";
        $params = [];

        if ($branchId !== null) {
            $where .= " AND i.current_location_id = ?";
            $params[] = (int)$branchId;
        }

        $searchableCols = ['i.unique_code', 'i.item_name', 'i.item_details', 'i.category', 'i.serial_number', 'i.technical_specs'];

        return [$selectCols, $where, $params, $searchableCols];
    }

    public function getDetailedItems($branchId = null, ?string $searchTerm = null, string $orderBy = 'i.item_name ASC', ?int $limit = null, int $offset = 0) {
        [$selectCols, $where, $params, $searchableCols] = $this->detailedItemsQuery($branchId);
        return $this->fetchPaged($selectCols, $where, $params, $searchableCols, $searchTerm, $orderBy, $limit, $offset);
    }

    public function countDetailedItems($branchId = null, ?string $searchTerm = null): int {
        [, $where, $params, $searchableCols] = $this->detailedItemsQuery($branchId);
        return $this->countPaged($where, $params, $searchableCols, $searchTerm);
    }

    private function detailedItemGroupExpression(): string {
        return "CONCAT('N:', LOWER(
            REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
                TRIM(i.item_name), ' ', ''
            ), '-', ''), '_', ''), '/', ''), '.', '')
        ))";
    }

    private function detailedGroupSearchHaving(?string $searchTerm, array &$params): string {
        $searchTerm = trim((string)$searchTerm);
        if ($searchTerm === '') {
            return '';
        }
        $columns = ['i.product_code', 'i.unique_code', 'i.item_name', 'i.item_details', 'i.category', 'i.serial_number', 'i.technical_specs'];
        $conditions = [];
        foreach ($columns as $column) {
            $conditions[] = "{$column} LIKE ?";
            $params[] = "%{$searchTerm}%";
        }
        return ' HAVING MAX(CASE WHEN ' . implode(' OR ', $conditions) . ' THEN 1 ELSE 0 END) = 1';
    }

    public function getGroupedDetailedItems($branchId, ?string $searchTerm = null, int $limit = 25, int $offset = 0, int $maxLimit = 100): array {
        [, $where, $params] = $this->detailedItemsQuery($branchId);
        $groupExpression = $this->detailedItemGroupExpression();
        $having = $this->detailedGroupSearchHaving($searchTerm, $params);

        $sql = "SELECT {$groupExpression} AS group_key,
                       MAX(i.product_code) AS product_code,
                       COUNT(DISTINCT NULLIF(i.product_code, '')) AS product_code_count,
                       MAX(i.item_name) AS item_name,
                       GROUP_CONCAT(DISTINCT NULLIF(i.item_details, '') ORDER BY i.item_details SEPARATOR ', ') AS item_details,
                       GROUP_CONCAT(DISTINCT NULLIF(i.category, '') ORDER BY i.category SEPARATOR ', ') AS category,
                       COUNT(*) AS available_quantity,
                       MIN(i.unit_price) AS minimum_price, MAX(i.unit_price) AS maximum_price,
                       MIN(i.created_at) AS date_entered, MAX(i.warranty_months) AS warranty,
                       MAX(i.technical_specs) AS technical_specs,
                       GROUP_CONCAT(DISTINCT NULLIF(i.condition_status, '') ORDER BY i.condition_status SEPARATOR ', ') AS conditions
                FROM items i WHERE {$where}
                GROUP BY {$groupExpression}{$having}
                ORDER BY item_name ASC LIMIT ? OFFSET ?";
        $stmt = $this->conn->prepare($sql);
        $index = 1;
        foreach ($params as $param) {
            $stmt->bindValue($index++, $param, is_int($param) ? PDO::PARAM_INT : PDO::PARAM_STR);
        }
        $stmt->bindValue($index++, max(1, min(max(1, $maxLimit), $limit)), PDO::PARAM_INT);
        $stmt->bindValue($index, max(0, $offset), PDO::PARAM_INT);
        $stmt->execute();
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public function countGroupedDetailedItems($branchId, ?string $searchTerm = null): int {
        [, $where, $params] = $this->detailedItemsQuery($branchId);
        $groupExpression = $this->detailedItemGroupExpression();
        $having = $this->detailedGroupSearchHaving($searchTerm, $params);
        $stmt = $this->conn->prepare(
            "SELECT COUNT(*) FROM (
                SELECT 1 FROM items i WHERE {$where} GROUP BY {$groupExpression}{$having}
            ) grouped_items"
        );
        foreach ($params as $index => $param) {
            $stmt->bindValue($index + 1, $param, is_int($param) ? PDO::PARAM_INT : PDO::PARAM_STR);
        }
        $stmt->execute();
        return (int)$stmt->fetchColumn();
    }

    public function getDetailedItemGroupCodes($branchId, string $groupKey): array {
        [, $where, $params] = $this->detailedItemsQuery($branchId);
        $groupExpression = $this->detailedItemGroupExpression();
        $params[] = $groupKey;
        $stmt = $this->conn->prepare(
            "SELECT i.item_id, i.unique_code, i.item_details, i.serial_number, i.current_location_id,
                    i.item_name, i.product_code, i.unit_price, i.condition_status,
                    i.warranty_months, i.technical_specs, i.created_at AS date_entered,
                    (SELECT b.branch_name FROM branches b WHERE b.branch_id = i.current_location_id LIMIT 1) AS branch_name
             FROM items i
             WHERE {$where} AND {$groupExpression} = ?
             ORDER BY i.unique_code ASC"
        );
        foreach ($params as $index => $param) {
            $stmt->bindValue($index + 1, $param, is_int($param) ? PDO::PARAM_INT : PDO::PARAM_STR);
        }
        $stmt->execute();
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    private function detailedMissingItemsQuery($branchId): array {
        $selectCols = "i.item_id, i.item_name, i.item_details, i.category, i.unique_code AS unique_id, i.unit_price,
            i.warranty_months AS warranty, i.serial_number, i.technical_specs,
            i.condition_status, i.created_at AS date_entered, i.barcode_image_path";
        $where = "i.shelf_status = 'on_shelf'
          AND EXISTS (SELECT 1 FROM missing_items m WHERE m.unique_code = i.unique_code)";
        $params = [];

        if ($branchId !== null) {
            $where .= " AND i.current_location_id = ?";
            $params[] = (int)$branchId;
        }

        $searchableCols = ['i.unique_code', 'i.item_name', 'i.item_details', 'i.category', 'i.serial_number', 'i.technical_specs'];

        return [$selectCols, $where, $params, $searchableCols];
    }

    public function getDetailedMissingItems($branchId = null, ?string $searchTerm = null, string $orderBy = 'i.item_name ASC', ?int $limit = null, int $offset = 0) {
        [$selectCols, $where, $params, $searchableCols] = $this->detailedMissingItemsQuery($branchId);
        return $this->fetchPaged($selectCols, $where, $params, $searchableCols, $searchTerm, $orderBy, $limit, $offset);
    }

    public function countDetailedMissingItems($branchId = null, ?string $searchTerm = null): int {
        [, $where, $params, $searchableCols] = $this->detailedMissingItemsQuery($branchId);
        return $this->countPaged($where, $params, $searchableCols, $searchTerm);
    }

	
    private function unknownItemsQuery(): array {
        $selectCols = "i.item_id, i.item_name, i.item_details, i.category, i.unique_code as unique_id, i.unit_price,
                         i.warranty_months as warranty, i.serial_number, i.technical_specs,
                         i.condition_status, i.created_at AS date_entered, i.barcode_image_path";
        $where = "i.shelf_status = 'on_shelf'
                  AND i.item_id NOT IN (SELECT item_id FROM sold_items WHERE is_verified = 1)
                  AND i.current_location_id IS NULL";
        $searchableCols = ['i.unique_code', 'i.item_name', 'i.item_details', 'i.category', 'i.serial_number', 'i.technical_specs'];

        return [$selectCols, $where, [], $searchableCols];
    }

    public function getUnkwownItems(?string $searchTerm = null, string $orderBy = 'i.item_name ASC', ?int $limit = null, int $offset = 0) {
        [$selectCols, $where, $params, $searchableCols] = $this->unknownItemsQuery();
        return $this->fetchPaged($selectCols, $where, $params, $searchableCols, $searchTerm, $orderBy, $limit, $offset);
    }

    public function countUnkwownItems(?string $searchTerm = null): int {
        [, $where, $params, $searchableCols] = $this->unknownItemsQuery();
        return $this->countPaged($where, $params, $searchableCols, $searchTerm);
    }




    public function searchSimpleItems($branchId, $searchField, $searchTerm) {
        $query = "SELECT i.item_id, i.item_name, i.item_details, i.category, i.unique_code as unique_id, i.unit_price, i.created_at AS date_entered, i.barcode_image_path
                  FROM items i
                  WHERE i.current_location_id = ?
                  AND i.shelf_status = 'on_shelf'
                  AND (i.brand IS NULL OR i.brand = '')
                  AND (i.model IS NULL OR i.model = '')
                  AND (i.serial_number IS NULL OR i.serial_number = '')
                  AND (i.technical_specs IS NULL OR i.technical_specs = '' OR i.technical_specs = 'No technical specifications provided')
                  AND i.item_id NOT IN (SELECT item_id FROM sold_items WHERE is_verified = 1)";

        $searchParam = null;
        if (!empty($searchTerm) && !empty($searchField)) {
            $allowedFields = ['unique_id' => 'i.unique_code', 'item_name' => 'i.item_name', 'unit_price' => 'i.unit_price', 'date_entered' => 'i.created_at'];
            if (array_key_exists($searchField, $allowedFields)) {
                  $query .= " AND " . $allowedFields[$searchField] . " LIKE ?";
                  $searchParam = "%$searchTerm%";
            }
        }

        $stmt = $this->conn->prepare($query);

        if ($searchParam !== null) {
            $stmt->execute([$branchId, $searchParam]);
        } else {
            $stmt->execute([$branchId]);
        }

        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public function searchDetailedItems($branchId, $searchField, $searchTerm) {
        $query = "SELECT i.item_id, i.item_name, i.item_details, i.category, i.unique_code as unique_id, i.unit_price,
                         i.warranty_months as warranty, i.brand, i.model, i.serial_number, i.technical_specs,
                         i.condition_status, i.created_at AS date_entered, i.barcode_image_path
                  FROM items i
                  WHERE i.current_location_id = ?
                  AND i.shelf_status = 'on_shelf'
                  AND i.item_id NOT IN (SELECT item_id FROM sold_items)";

        $searchParam = null;
        if (!empty($searchTerm) && !empty($searchField)) {
            $allowedFields = [
                'unique_id' => 'i.unique_code',
                'item_name' => 'i.item_name',
                'item_details' => 'i.item_details',
                'unit_price' => 'i.unit_price',
                'date_entered' => 'i.created_at',
                'warranty' => 'i.warranty_months',
                'brand' => 'i.brand',
                'model' => 'i.model',
                'serial_number' => 'i.serial_number',
                'technical_specs' => 'i.technical_specs',
                'condition_status' => 'i.condition_status'
            ];
            
            if (array_key_exists($searchField, $allowedFields)) {
                $query .= " AND " . $allowedFields[$searchField] . " LIKE ?";
                $searchParam = "%$searchTerm%";
            }
        }

        $stmt = $this->conn->prepare($query);

        if ($searchParam !== null) {
            $stmt->execute([$branchId, $searchParam]);
        } else {
            $stmt->execute([$branchId]);
        }

        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public function updateItem($item_id, $data, $apply_to_all = false) {
        $this->conn->beginTransaction();
        try {
            $oldData = null;
            if ($this->logger) {
                $oldData = $this->getItemById($item_id);
            }

            $fields = ['item_name', 'unique_code', 'item_details', 'unit_price', 'comment', 'category', 'shelf_status'];
            $set_clause = [];
            $params = [];

            if (isset($data['unique_code']) && !empty($data['unique_code'])) {
                $sql_check = "SELECT COUNT(*) FROM items WHERE unique_code = :unique_code AND item_id != :item_id";
                $stmt_check = $this->conn->prepare($sql_check);
                $stmt_check->bindParam(':unique_code', $data['unique_code']);
                $stmt_check->bindParam(':item_id', $item_id, PDO::PARAM_INT);
                $stmt_check->execute();
                if ($stmt_check->fetchColumn() > 0) {
                    $this->lastError = "The unique code '{$data['unique_code']}' is already in use.";
                    throw new Exception($this->lastError);
                }
            }

            foreach ($fields as $field) {
                if (isset($data[$field])) {
                    $set_clause[] = "$field = :$field";
                    $params[":$field"] = $data[$field] ?: null;
                }
            }
            $set_clause = implode(', ', $set_clause);

            if ($apply_to_all) {
                $sql = "UPDATE items SET $set_clause WHERE item_name = :item_name";
                $params[':item_name'] = $data['item_name'];
            } else {
                $sql = "UPDATE items SET $set_clause WHERE item_id = :item_id";
                $params[':item_id'] = $item_id;
            }

            $stmt = $this->conn->prepare($sql);
            $stmt->execute($params);

            if ($this->logger) {
                error_log("Inventory: About to log UPDATE for item_id: $item_id");
                $result = $this->logger->logInventory('UPDATE', $item_id, $data, $oldData);
                error_log("Inventory: Log result for UPDATE: " . ($result ? 'SUCCESS' : 'FAILED'));
            } else {
                error_log("Inventory: Logger is null, cannot log UPDATE");
            }

            $this->conn->commit();
            return true;
        } catch (Exception $e) {
            $this->conn->rollBack();
            $this->lastError = $e->getMessage();
            error_log("Error updating item: " . $e->getMessage());
            return false;
        }
    }

    
	public function moveToShelf($item_id) {
    try {
        $sql = "DELETE FROM missing_items WHERE item_id = :item_id";
        
        $stmt = $this->conn->prepare($sql);
        $stmt->bindParam(':item_id', $item_id, PDO::PARAM_INT);
        
        if ($stmt->execute()) {
            return true;
        } else {
            return false;
        }

    } catch (PDOException $e) {
        error_log("Error moving item to shelf: " . $e->getMessage());
        return false;
    }
}

   
	
	
	
	public function deleteItem($item_id, $deletion_reason = null) {
        $this->conn->beginTransaction();
        try {
            $itemData = null;
            if ($this->logger) {
                $itemData = $this->getItemById($item_id);
                if ($deletion_reason) {
                    $itemData['deletion_reason'] = $deletion_reason;
                }
            }

            $sql_verifications = "DELETE FROM stock_taking_verifications WHERE item_id = :item_id";
            $stmt_verifications = $this->conn->prepare($sql_verifications);
            $stmt_verifications->bindParam(':item_id', $item_id, PDO::PARAM_INT);
            $stmt_verifications->execute();

            $sql = "DELETE FROM items WHERE item_id = :item_id";
            $stmt = $this->conn->prepare($sql);
            $stmt->bindParam(':item_id', $item_id, PDO::PARAM_INT);
            $result = $stmt->execute();

            if ($result && $this->logger && $itemData) {
                $this->logger->logInventory('DELETE', $item_id, null, $itemData);
            }

            $this->conn->commit();
            return $result;
        } catch (Exception $e) {
            $this->conn->rollBack();
            error_log("Error deleting item: " . $e->getMessage());
            return false;
        }
    }

    public function getLastError(): string {
        return $this->lastError ?? 'Unknown error';
    }

    public function addItemsToWarehouse(array $items, int $createdBy, int $branchId = 7): bool {
        $warehouseBranchId = 7;
        
        error_log("Starting addItemsToWarehouse with " . count($items) . " items for warehouse (branch_id: $warehouseBranchId)");
        
        if (empty($items)) {
            error_log("Error: No items provided to addItemsToWarehouse");
            $this->lastError = "No items provided for import";
            return false;
        }
        
        $this->conn->beginTransaction();
        try {
            $successCount = 0;
            $allowedConditions = ['NEW', 'OPEN_BOX', 'USED'];
            $allowedCategories = ['accessory', 'battery', 'computer', 'furniture','TV','other'];
            
            foreach ($items as $index => $item) {
                error_log("Processing warehouse item " . ($index + 1) . " with unique_code: " . $item['unique_code']);
                
                $requiredKeys = ['unique_code', 'item_name', 'category', 'condition_status', 'unit_price'];
                foreach ($requiredKeys as $key) {
                    if (!isset($item[$key]) || $item[$key] === '' || $item[$key] === null) {
                        throw new Exception("Missing required field '{$key}' for item " . ($index + 1));
                    }
                }
                
                $condition = strtoupper(trim($item['condition_status']));
                if (!in_array($condition, $allowedConditions)) {
                    throw new Exception("Invalid condition_status for item " . ($index + 1) . ": " . $item['condition_status']);
                }
                
                $category = trim($item['category']);
                /*
                if (!in_array($category, $allowedCategories)) {
                    throw new Exception("Invalid category for item " . ($index + 1) . ": " . $item['category']);
                }*/

                if (!is_numeric($item['unit_price']) || $item['unit_price'] < 0) {
                    throw new Exception("Invalid unit_price for item " . ($index + 1) . ": " . $item['unit_price']);
                }
                
                $unique_code = trim($item['unique_code']);
                $barcode_type = 'C128B';
                
                error_log("Generating INDIVIDUAL barcode for unique_code: " . $unique_code);
                $barcode_image_path = $this->generateBarcodeImage($unique_code, $barcode_type);
                
                if ($barcode_image_path === false) {
                    error_log("Barcode generation FAILED for " . $unique_code . ": " . $this->lastError);
                    $barcode_image_path = null;
                    error_log("Continuing without barcode for item: " . $unique_code);
                }
                
                if ($barcode_image_path) {
                    error_log("Barcode generated SUCCESSFULLY for " . $unique_code . ": " . $barcode_image_path);
                }
                
                usleep(100000);
                
                $warehouseFields = [
                    'unique_code' => $unique_code,
                    'item_name' => trim($item['item_name']),
                    'category' => $category,
                    'condition_status' => $condition,
                    'unit_price' => floatval($item['unit_price']),
                    'created_by' => $createdBy,
                    'current_location_id' => $warehouseBranchId,
                    'barcode_type' => $barcode_type,
                    'barcode_data' => $unique_code,
                    'barcode_image_path' => $barcode_image_path,
                ];

                if ($this->columnExists($this->table_name, 'product_code')) {
                    $warehouseFields['product_code'] = isset($item['product_code']) && trim($item['product_code']) !== ''
                        ? trim($item['product_code'])
                        : $this->productCodeForItemName($item['item_name']);
                }
                
                $optionalFields = [
                    'item_details' => isset($item['item_details']) && trim($item['item_details']) !== '' ? trim($item['item_details']) : null,
                    'description' => isset($item['description']) && trim($item['description']) !== '' ? trim($item['description']) : null,
                    'comment' => isset($item['comment']) && trim($item['comment']) !== '' ? trim($item['comment']) : null,
                    'serial_number' => isset($item['serial_number']) && trim($item['serial_number']) !== '' ? trim($item['serial_number']) : null,
                    'brand' => isset($item['brand']) && trim($item['brand']) !== '' ? trim($item['brand']) : null,
                    'model' => isset($item['model']) && trim($item['model']) !== '' ? trim($item['model']) : null,
                    'warranty_months' => isset($item['warranty_months']) && is_numeric($item['warranty_months']) && $item['warranty_months'] >= 0 ? intval($item['warranty_months']) : null,
                    'technical_specs' => isset($item['technical_specs']) && trim($item['technical_specs']) !== '' ? trim($item['technical_specs']) : 'No technical specifications provided',
                ];
                
                foreach ($optionalFields as $key => $value) {
                    if ($value !== null) {
                        $warehouseFields[$key] = $value;
                    }
                }
                
                $columns = implode(', ', array_keys($warehouseFields));
                $placeholders = ':' . implode(', :', array_keys($warehouseFields));
                $sql = "INSERT INTO " . $this->table_name . " ({$columns}) VALUES ({$placeholders})";
                
                $stmt = $this->conn->prepare($sql);
                if (!$stmt) {
                    $errorInfo = $this->conn->errorInfo();
                    throw new Exception("Failed to prepare statement: " . $errorInfo[2]);
                }
                
                $result = $stmt->execute($warehouseFields);
                if (!$result) {
                    $errorInfo = $stmt->errorInfo();
                    error_log("SQL Error for item " . ($index + 1) . ": " . json_encode($errorInfo));
                    throw new Exception("Failed to insert warehouse item " . ($index + 1) . ": " . $errorInfo[2]);
                }
                
                $insertedId = $this->conn->lastInsertId();
                error_log("Successfully inserted item " . ($index + 1) . " with ID: " . $insertedId . " and barcode: " . ($barcode_image_path ?? 'NONE'));

                if ($this->logger) {
                    if ($index === 0 && count($items) > 1) {
                        $bulkData = $warehouseFields;
                        $bulkData['items_count'] = count($items);
                        $this->logger->logInventory('CREATE', $insertedId, $bulkData);
                    } elseif (count($items) === 1) {
                        $this->logger->logInventory('CREATE', $insertedId, $warehouseFields);
                    }
                }

                $this->tracking->logEvent(
                    $insertedId,
                    $unique_code,
                    'added',
                    $warehouseBranchId,
                    null,
                    $createdBy,
                    [
                        'item_name' => trim($item['item_name']),
                        'item_details' => trim((string)($item['item_details'] ?? '')),
                        'condition_status' => $condition,
                        'unit_price' => floatval($item['unit_price']),
                        'source' => 'warehouse_import'
                    ]
                );

                $successCount++;
            }
            
            error_log("Successfully added {$successCount} items to warehouse with individual barcodes");
            $this->conn->commit();
            return true;
            
        } catch (Exception $e) {
            $this->conn->rollBack();
            $this->lastError = $e->getMessage();
            error_log("Error adding items to warehouse: " . $e->getMessage());
            return false;
        }
    }

    private function itemsByCurrentLocationQuery($locationId): array {
        $selectCols = "i.item_id, i.item_name, i.item_details, i.product_code, IFNULL(i.unique_code, 'N/A') as unique_code,
                        IFNULL(i.unit_price, 0) as unit_price,
                       IFNULL(i.condition_status, '') as condition_status,
                        IFNULL(i.serial_number, '') as serial_number,
                       IFNULL(i.warranty_months, 0) as warranty_months, IFNULL(i.technical_specs, '') as technical_specs,
                       i.created_at AS date_entered, i.barcode_image_path";
        $where = "i.current_location_id = ?
                  AND i.shelf_status = 'on_shelf'
                  AND NOT EXISTS (
                      SELECT 1 FROM sold_items sold_current
                      WHERE sold_current.item_id = i.item_id
                  )";
        $params = [(int)$locationId];
        $searchableCols = ['i.product_code', 'i.unique_code', 'i.item_name', 'i.item_details', 'i.serial_number'];

        return [$selectCols, $where, $params, $searchableCols];
    }

    public function getItemsByCurrentLocation($locationId, ?string $searchTerm = null, string $orderBy = 'i.item_name ASC', ?int $limit = null, int $offset = 0) {
        [$selectCols, $where, $params, $searchableCols] = $this->itemsByCurrentLocationQuery($locationId);
        return $this->fetchPaged($selectCols, $where, $params, $searchableCols, $searchTerm, $orderBy, $limit, $offset);
    }

    public function countItemsByCurrentLocation($locationId, ?string $searchTerm = null): int {
        [, $where, $params, $searchableCols] = $this->itemsByCurrentLocationQuery($locationId);
        return $this->countPaged($where, $params, $searchableCols, $searchTerm);
    }

    /** Returns product-level on-shelf quantities for only the products present on the current page. */
    public function availableQuantitiesForItems($locationId, array $items): array {
        $productCodes = [];
        $fallbackNames = [];
        foreach ($items as $item) {
            $code = trim((string)($item['product_code'] ?? ''));
            if ($code !== '') {
                $productCodes[$code] = true;
            } else {
                $name = trim((string)($item['item_name'] ?? ''));
                if ($name !== '') {
                    $fallbackNames[$name] = true;
                }
            }
        }
        if (!$productCodes && !$fallbackNames) {
            return [];
        }

        $filters = [];
        $params = [(int)$locationId];
        if ($productCodes) {
            $filters[] = 'i.product_code IN (' . implode(',', array_fill(0, count($productCodes), '?')) . ')';
            array_push($params, ...array_keys($productCodes));
        }
        if ($fallbackNames) {
            $filters[] = "((i.product_code IS NULL OR i.product_code = '') AND i.item_name IN ("
                . implode(',', array_fill(0, count($fallbackNames), '?')) . '))';
            array_push($params, ...array_keys($fallbackNames));
        }

        $sql = "SELECT COALESCE(NULLIF(i.product_code, ''), i.item_name) AS product_key, COUNT(*) AS available_quantity
                FROM items i
                WHERE i.current_location_id = ?
                  AND i.shelf_status = 'on_shelf'
                  AND NOT EXISTS (SELECT 1 FROM sold_items sold WHERE sold.item_id = i.item_id)
                  AND (" . implode(' OR ', $filters) . ")
                GROUP BY COALESCE(NULLIF(i.product_code, ''), i.item_name)";
        $stmt = $this->conn->prepare($sql);
        foreach ($params as $index => $param) {
            $stmt->bindValue($index + 1, $param, is_int($param) ? PDO::PARAM_INT : PDO::PARAM_STR);
        }
        $stmt->execute();

        $quantities = [];
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
            $quantities[(string)$row['product_key']] = (int)$row['available_quantity'];
        }
        return $quantities;
    }

    public function getItemByUniqueCode($uniqueCode) {
        $sql = "SELECT * FROM items WHERE unique_code = :unique_code";
        $stmt = $this->conn->prepare($sql);
        $stmt->bindParam(':unique_code', $uniqueCode, PDO::PARAM_STR);
        $stmt->execute();
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }

    public function getItemByBarcodeData($barcodeData) {
        try {
            $sql = "SELECT * FROM " . $this->table_name . " WHERE barcode_data = :barcode_data LIMIT 1";
            $stmt = $this->conn->prepare($sql);
            $stmt->bindParam(':barcode_data', $barcodeData, PDO::PARAM_STR);
            $stmt->execute();
            
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if ($result) {
                error_log("Item found by barcode_data: " . $barcodeData . " -> " . $result['unique_code']);
            } else {
                error_log("No item found for barcode_data: " . $barcodeData);
            }
            
            return $result;
        } catch (PDOException $e) {
            error_log("Error getting item by barcode data: " . $e->getMessage());
            return false;
        }
    }

    public function getItemByBarcodeOrCode($searchValue) {
        try {
            $sql = "SELECT * FROM " . $this->table_name . " WHERE barcode_data = :search_value LIMIT 1";
            $stmt = $this->conn->prepare($sql);
            $stmt->bindParam(':search_value', $searchValue, PDO::PARAM_STR);
            $stmt->execute();

            $result = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$result) {
                $sql = "SELECT * FROM " . $this->table_name . " WHERE unique_code = :search_value LIMIT 1";
                $stmt = $this->conn->prepare($sql);
                $stmt->bindParam(':search_value', $searchValue, PDO::PARAM_STR);
                $stmt->execute();
                $result = $stmt->fetch(PDO::FETCH_ASSOC);
            }

            if ($result) {
                error_log("Item found by barcode/code search: " . $searchValue . " -> " . $result['unique_code']);
            } else {
                error_log("No item found for barcode/code: " . $searchValue);
            }

            return $result;
        } catch (PDOException $e) {
            error_log("Error getting item by barcode or code: " . $e->getMessage());
            return false;
        }
    }

    public function getWarehouseStats() {
        try {
            $warehouseBranchId = 7;
            $sql = "SELECT
                        COUNT(*) as total_items,
                        SUM(CASE WHEN condition_status = 'NEW' THEN 1 ELSE 0 END) as new_items,
                        SUM(CASE WHEN condition_status = 'OPEN_BOX' THEN 1 ELSE 0 END) as open_box_item,
                        SUM(CASE WHEN condition_status = 'USED' THEN 1 ELSE 0 END) as used_items,
                        AVG(unit_price) as avg_price,
                        SUM(unit_price) as total_value
                    FROM items
                    WHERE current_location_id = :warehouse_id
                    AND item_id NOT IN (SELECT item_id FROM sold_items WHERE transaction_id LIKE '%_VERIFIED_%')";

            $stmt = $this->conn->prepare($sql);
            $stmt->bindParam(':warehouse_id', $warehouseBranchId, PDO::PARAM_INT);
            $stmt->execute();
            $stats = $stmt->fetch(PDO::FETCH_ASSOC);

            $lowStockSql = "SELECT COUNT(*) as low_stock_count FROM (
                                SELECT item_name, COUNT(*) as item_count
                                FROM items
                                WHERE current_location_id = :warehouse_id
                                AND item_id NOT IN (SELECT item_id FROM sold_items WHERE transaction_id LIKE '%_VERIFIED_%')
                                GROUP BY item_name
                                HAVING item_count < 5
                            ) as low_stock_items";

            $lowStockStmt = $this->conn->prepare($lowStockSql);
            $lowStockStmt->bindParam(':warehouse_id', $warehouseBranchId, PDO::PARAM_INT);
            $lowStockStmt->execute();
            $lowStock = $lowStockStmt->fetch(PDO::FETCH_ASSOC);

            return array_merge($stats, $lowStock);
        } catch (Exception $e) {
            error_log("Error getting warehouse stats: " . $e->getMessage());
            return [
                'total_items' => 0,
                'new_items' => 0,
                'open_box_item' => 0,
                'used_items' => 0,
                'avg_price' => 0,
                'total_value' => 0,
                'low_stock_count' => 0
            ];
        }
    }

    public function getWarehouseItemsByCondition() {
        try {
            $warehouseBranchId = 7;
            $sql = "SELECT condition_status, COUNT(*) as count, SUM(unit_price) as total_value
                    FROM items
                    WHERE current_location_id = :warehouse_id
                    AND item_id NOT IN (SELECT item_id FROM sold_items WHERE transaction_id LIKE '%_VERIFIED_%')
                    GROUP BY condition_status
                    ORDER BY condition_status";

            $stmt = $this->conn->prepare($sql);
            $stmt->bindParam(':warehouse_id', $warehouseBranchId, PDO::PARAM_INT);
            $stmt->execute();
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            error_log("Error getting warehouse items by condition: " . $e->getMessage());
            return [];
        }
    }

    public function getWarehouseValueOverTime($startDate, $endDate) {
        try {
            $warehouseBranchId = 7;
            $sql = "SELECT
                        DATE_FORMAT(created_at, '%Y-%m') as month,
                        COUNT(*) as items_added,
                        SUM(unit_price) as value_added
                    FROM items
                    WHERE current_location_id = :warehouse_id
                    AND created_at BETWEEN :start_date AND :end_date
                    GROUP BY DATE_FORMAT(created_at, '%Y-%m')
                    ORDER BY month";

            $stmt = $this->conn->prepare($sql);
            $stmt->bindParam(':warehouse_id', $warehouseBranchId, PDO::PARAM_INT);
            $stmt->bindParam(':start_date', $startDate);
            $stmt->bindParam(':end_date', $endDate);
            $stmt->execute();
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            error_log("Error getting warehouse value over time: " . $e->getMessage());
            return [];
        }
    }

    public function getAvailableItemsByName($itemName, $branchId) {
        try {
            $sql = "SELECT * FROM items
                    WHERE item_name LIKE :item_name
                    AND current_location_id = :branch_id
                    AND item_id NOT IN (SELECT item_id FROM sold_items WHERE transaction_id NOT LIKE '%_VERIFIED_%')
                    ORDER BY item_id";
            $stmt = $this->conn->prepare($sql);
            $stmt->bindParam(':item_name', $itemName, PDO::PARAM_STR);
            $stmt->bindParam(':branch_id', $branchId, PDO::PARAM_INT);
            $stmt->execute();
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            error_log("Error getting available items by name: " . $e->getMessage());
            return [];
        }
    }
	
	
	
	
	 public function getAllCategories() {
        $query = "SELECT * FROM category";
        $stmt = $this->conn->prepare($query);
        $stmt->execute();
        return $stmt;
    }
	
	 public function updatePrice($percentage) {
        $query = "SELECT * FROM items";
        $stmt = $this->conn->prepare($query);
        $stmt->execute();
        return $stmt;
    }

	 public function previewPriceChange($percentage) {
        $query = "SELECT item_id, item_name, item_details, unique_code, unit_price
                  FROM items
                  ORDER BY item_name ASC, unique_code ASC";
        $stmt = $this->conn->prepare($query);
        $stmt->execute();

        $items = [];
        while ($item = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $oldPrice = (float)($item['unit_price'] ?? 0);
            $newPrice = round($oldPrice + ($oldPrice * $percentage), 2);
            $items[] = [
                'item_id' => $item['item_id'],
                'item_name' => $item['item_name'],
                'unique_code' => $item['unique_code'],
                'old_price' => $oldPrice,
                'new_price' => $newPrice,
                'difference' => $newPrice - $oldPrice
            ];
        }

        return $items;
    }

	 public function applyPriceChange($percentage) {
        $items = $this->previewPriceChange($percentage);
        if (empty($items)) {
            return 0;
        }

        $this->conn->beginTransaction();
        try {
            $query = "UPDATE items SET unit_price = :new_price WHERE item_id = :item_id";
            $stmt = $this->conn->prepare($query);
            $updated = 0;

            foreach ($items as $item) {
                $stmt->bindValue(':new_price', $item['new_price']);
                $stmt->bindValue(':item_id', $item['item_id'], PDO::PARAM_INT);
                $stmt->execute();
                $updated += $stmt->rowCount();
            }

            $this->conn->commit();
            return $updated;
        } catch (Exception $e) {
            if ($this->conn->inTransaction()) {
                $this->conn->rollBack();
            }
            throw $e;
        }
    }
	
	 public function updateNew($item_id, $new_price) {
        $query = "UPDATE items SET unit_price = :new_price WHERE item_id = :item_id";
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':new_price', $new_price);
        $stmt->bindParam(':item_id', $item_id, PDO::PARAM_INT);
        $stmt->execute();
        return $stmt;
    }
	
	
	
	
	

}
?>
