<?php
/**
 * 2007-2023 PrestaShop
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@prestashop.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
 * versions in the future. If you wish to customize PrestaShop for your
 * needs please refer to http://www.prestashop.com for more information.
 *
 *  @author    PrestaShop SA <contact@prestashop.com>
 *  @copyright 2007-2023 PrestaShop SA
 *  @license   http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 *  International Registered Trademark & Property of PrestaShop SA
 */

namespace PrestaShop\Module\AgileMultisellerPro\Provider;

use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchProviderInterface;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchResult;
use PrestaShop\PrestaShop\Core\Product\Search\SortOrderFactory;
use Symfony\Component\Translation\TranslatorInterface;

if (!defined('_PS_VERSION_')) {
    exit;
}

class SellerProductSearchProvider implements ProductSearchProviderInterface
{
    private $translator;
    private $id_seller;
    private $extraConditions;
    private $sortOrderFactory;

    public function __construct(TranslatorInterface $translator, $id_seller, $extraConditions)
    {
        $this->translator = $translator;
        $this->id_seller = $id_seller;
        $this->extraConditions = $extraConditions;
        $this->sortOrderFactory = new SortOrderFactory($this->translator);
    }

    private function getProductsOrCount(ProductSearchContext $context, ProductSearchQuery $query, $type = 'products')
    {
        return self::getProductsBySeller(
            $this->id_seller,
            \Context::getContext(),
            $type !== 'products',
            $query->getPage(),
            $query->getResultsPerPage(),
            $query->getSortOrder()->toLegacyOrderBy(),
            $query->getSortOrder()->toLegacyOrderWay(),
            $this->extraConditions
        );
    }

    public function runQuery(ProductSearchContext $context, ProductSearchQuery $query)
    {
        $products = $this->getProductsOrCount($context, $query, 'products');
        $count = $this->getProductsOrCount($context, $query, 'count');

        $result = new ProductSearchResult();
        $result
            ->setProducts($products)
            ->setTotalProductsCount($count)
        ;

        $result->setAvailableSortOrders(
            $this->sortOrderFactory->getDefaultSortOrders()
        );

        return $result;
    }

    private static function getProductsBySeller($id_seller, \Context $context, $nb_only = false, $p = 1, $n = 10, $orderby = '', $orderway = '', $extraConditions = '')
    {
        $select = 'SELECT p.*, pl.name,pl.link_rewrite, cl.name `name_category`, i.`id_image`, 0 AS price_final, sav.`quantity` as sav_quantity, sip.approved ';
        $from = '
                FROM `' . _DB_PREFIX_ . 'product` p
                INNER JOIN ' . _DB_PREFIX_ . 'product_shop product_shop ON (product_shop.id_product = p.id_product AND product_shop.id_shop = ' . \Configuration::get('PS_SHOP_DEFAULT') . ')
                LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON (pl.id_lang=' . $context->language->id . ' AND p.`id_product` = pl.`id_product` ' . \Shop::addSqlRestrictionOnLang('pl') . ')
            LEFT JOIN `' . _DB_PREFIX_ . 'image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1)
            LEFT JOIN `' . _DB_PREFIX_ . 'stock_available` sav ON (sav.`id_product` = p.`id_product` AND sav.`id_product_attribute` = 0
                AND sav.`id_shop` = ' . (int) $context->shop->id . ')
            LEFT JOIN `' . _DB_PREFIX_ . 'category_lang` cl ON (p.id_category_default=cl.id_category AND cl.id_lang=' . (int) $context->language->id . ' AND cl.`id_shop` = ' . (int) $context->shop->id . ')
            LEFT JOIN `' . _DB_PREFIX_ . 'sellerinfo_product` sip ON p.id_product = sip.id_product            
        ';
        $where = ' WHERE IFNULL(sip.id_sellerinfo, 0) = ' . (int) $id_seller . ' AND product_shop.active = 1';

        if ($extraConditions != '') {
            $where = $where . $extraConditions;
        }

        if ($nb_only) {
            return \Db::getInstance()->getValue('SELECT COUNT(*) ' . $from . $where);
        }

        $p = $p < 1 ? 1 : $p;
        $n = $n < 1 ? 12 : $n;
        $orderby = empty($orderby) ? 'p.date_add' : $orderby;
        $orderway = !in_array(\Tools::strtolower($orderway), ['asc', 'desc']) ? 'asc' : $orderway;

        $sort = ' ORDER BY ' . $orderby . ' ' . $orderway;

        $limit = ' LIMIT ' . (((int) $p - 1) * (int) $n) . ',' . (int) $n;
        $sql = $select . $from . $where . $sort . $limit;

        return \Db::getInstance()->executeS($sql);
    }
}
