<?php

/**
 * Product Helper Class
 * 
 * This class contains helper methods for product-related operations.
 */
class ProductHelper
{

    /**
     * Add leading zeros to a number to make it a specific length
     * 
     * @param int $num The number to pad
     * @param int $length The desired length of the output string
     * @return string The padded number as a string
     */
    public static function addPreDigitsToNum($num, $length = 7)
    {
        $length = R::getCell('select parcodeDigits from programsetting where id = 1');
        if (!isset($length) || empty($length)) {
            $length = 5;
        }
        return str_pad($num, $length, '0', STR_PAD_LEFT);
    }

    /**
     * Check if a barcode already exists in the database
     * 
     * @param string $barcode The barcode to check
     * @return int 1 if barcode exists, 0 otherwise
     */
    public static function checkBarcode($barcode, $productId = 0)
    {
        $flag = 1;
        $programsetting = (object) R::getRow('select usedParcode,parcodeDigits from programsetting where id = 1');
        if ($programsetting->usedParcode == 0) {

            if (!isset($programsetting->parcodeDigits) || empty($programsetting->parcodeDigits)) {
                $programsetting->parcodeDigits = 5;
            }
        }
        // Check in availableparcode table
        $availableParcode = R::findOne('availableparcode', 'value = ?', [$barcode]);
        if ($availableParcode) {
            //if value in the table it is not repeated
            $flag = 2;
            return $flag;
        }

        // Check in product table
        $product = R::findOne('product', 'parcode = ? and productId != ?', [$barcode, $productId]);
        $flag2;
        if ($product) {
            $flag2 = 1;
        } else {
            $flag2 = 2;
        }

        $flagToreturn = 1;
        if ($flag == 2 || $flag2 == 2) {
            $flagToreturn = 2;
        }


        return $flagToreturn;
    }

    /**
     * Remove a barcode from the availableparcode table if it exists
     * 
     * @param string $barcodeToRemove The barcode to remove
     * @param string $barcodeToAdd (Optional) A new barcode to add
     * @return bool True on success, false on failure
     */
    public static function removeParcodeFromTable($barcodeToRemove, $barcodeToAdd = '')
    {
        $parcodeDigits = R::getCell('select parcodeDigits from programsetting where id = 1');
        if (!isset($parcodeDigits) || empty($parcodeDigits)) {
            $parcodeDigits = 5;
        }
        $biggestParcode = '';
        for ($i = 1; $i <= (int) $parcodeDigits; $i++) {
            $biggestParcode .= '9';
        }
        $biggestParcode = (int) $biggestParcode;

        if ($barcodeToRemove <= $biggestParcode) {
            R::exec("DELETE FROM availableparcode WHERE value = ?", [$barcodeToRemove]);

            // If a new barcode is provided, add it
            if (!empty($barcodeToAdd)) {
                $parcode = R::dispense('availableparcode');
                $parcode->value = $barcodeToAdd;
                R::store($parcode);
            }
        }
    }

    /**
     * Generate a unique barcode
     * 
     * @param int $length The desired length of the barcode
     * @return string A unique barcode
     */
    public static function generateParcode($length = 7)
    {
        //getAvailableParcodeValue
        $parcode = R::getCell('SELECT value 
        FROM availableparcode
        WHERE id >= FLOOR(RAND() * (SELECT MAX(id) FROM availableparcode))
        LIMIT 1');

        if (self::checkBarcode($parcode) != 2) {
            // If exists, generate a new unique one
            $parcode = self::generateParcode();
        }
        
        return $parcode;
    }

    /**
     * Generate a barcode for a product ID
     * 
     * @param int $productId The product ID
     * @return string The generated barcode
     */
    public static function generateBarcodeForProduct($productId)
    {
        $barcode = self::addPreDigitsToNum($productId);

        // Check if barcode already exists
        if (self::checkBarcode($barcode) === 1) {
            // If exists, generate a new unique one
            $barcode = self::generateParcode();
        }

        return $barcode;
    }
}

// Usage example:
// Include the helper
// require_once '_helper/ProductHelper.php';
// $barcode = ProductHelper::generateParcode();
// $exists = ProductHelper::checkBarcode('1234567');
// ProductHelper::removeParcodeFromTable('1234567');
