<?php
/**
 * Copyright © 2015 FiloBlu . All rights reserved.
 */

namespace FiloBlu\Flow\Helper;

use Exception;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\App\ResourceConnection;

/**
 * Class Stock
 * @package FiloBlu\Flow\Helper
 */
class Stock extends AbstractHelper
{
    /**
     * @var ResourceConnection
     */
    protected $connection;

    /**
     * @var \FiloBlu\Flow\Block\Product
     */
    private $productData;

    /**
     * Stock constructor.
     * @param Context $context
     * @param ResourceConnection $connection
     * @param \FiloBlu\Flow\Block\Product $productFactory
     */
    public function __construct(Context                     $context,
                                ResourceConnection          $connection,
                                \FiloBlu\Flow\Block\Product $productFactory)
    {
        parent::__construct($context);
        $this->connection = $connection;
        $this->productData = $productFactory;
    }

    /**
     * Adjust $qty_to_update taking into account sold products that are in configured status.
     *
     * @param $product_id integer
     * @param $qty_to_update integer
     * @return int|string
     * @throws Exception
     */
    public function getRealQty($product_id, $qty_to_update)
    {

        if (!$product_id) {
            throw new Exception('product_id error in getRealQty');
        }

        if ((int)$qty_to_update === 0) {
            return 0;
        }

        $reservedQty = $this->getReservedQty($product_id);

        if (!$reservedQty) {
            return $qty_to_update;
        }

        $qty_refreshed = $qty_to_update - $reservedQty;

        if ($qty_refreshed < 0) {
            return $this->notifyBreakdownsStockLoading($product_id, $reservedQty, $qty_to_update, $qty_refreshed);
        }

        return ($qty_refreshed > 0) ? $qty_refreshed : 0;
    }

    /**
     * FOS-720
     *
     * @param $productId integer
     * @return int
     */
    public function getReservedQty($productId)
    {

        $orderStatuses = $this->scopeConfig->getValue('filoblu_flow/flow_stock_option/flow_reserved_order_statuses');

        if (!$orderStatuses) {
            return 0;
        }

        $readConnection = $this->connection->getConnection(ResourceConnection::DEFAULT_CONNECTION);

        $orderStatuses = implode("','", explode(',', $orderStatuses));

        $query = $readConnection->select()
            ->from(['soi' => 'sales_order_item'], ['SUM(soi.qty_ordered) as qty'])
            ->join(['cpe' => 'catalog_product_entity'], 'cpe.entity_id = soi.product_id', [])
            ->join(['so' => 'sales_order'], 'soi.order_id = so.entity_id', [])
            ->where("status IN ('$orderStatuses') AND soi.product_id = $productId")
            ->group('soi.product_id');

        $results = $readConnection->fetchOne($query);

        if (!$results) {
            return 0;
        }

        return intval($results);
    }

    /**
     * FIX for issue FOS-737
     *
     * @param $product_id integer
     * @param $reservedQty integer
     * @param $qty_to_update integer
     * @param $qty_refreshed integer
     * @return string
     */
    private function notifyBreakdownsStockLoading($product_id, $reservedQty, $qty_to_update, $qty_refreshed)
    {

        $product = $this->productData->getProductLoader($product_id);
        return 'Product SKU ' . $product->getSku() . ' - Quantity to update ' . $qty_to_update . ' - Quantity reserved ' . $reservedQty . ' - Excess amount ' . abs($qty_refreshed);
    }

    /**
     * @param $product_id
     * @return string
     */
    public function getReservedQtyOrderList($product_id)
    {

        $orderList = [];

        $readConnection = $this->connection->getConnection(ResourceConnection::DEFAULT_CONNECTION);

        $orderStatuses = $this->scopeConfig->getValue('filoblu_flow/flow_stock_option/flow_reserved_order_statuses');

        if (!$orderStatuses) {
            return '';
        }

        $orderStatuses = implode("','", explode(',', $orderStatuses));

        $query = $readConnection->select()
            ->from(['soi' => 'sales_order_item'], ['soi.product_id', 'soi.sku', 'soi.order_id', 'soi.qty_ordered'])
            ->join(['cpe' => 'catalog_product_entity'], 'cpe.entity_id = soi.product_id', [])
            ->join(['so' => 'sales_order'], 'soi.order_id = so.entity_id', ['so.increment_id'])
            ->where("status IN ('$orderStatuses') AND soi.product_id = $product_id");
        $results = $readConnection->fetchAll($query);

        if (count($results) > 0) {

            foreach ($results as $result) {
                $orderList[] = $result['increment_id'];
            }

        } else {
            return '';
        }

        return implode(',', array_unique($orderList));
    }

}


