<?php

namespace QueryTest;

use Query\Filter;
use Query\Product;
use Query\QueryBuilder;

class ProductTest extends \DatabaseTestCase
{
    /** @var QueryBuilder */
    private $qb;

    public function setUp(): void
    {
        parent::setUp();

        $this->qb = sqlQueryBuilder();
    }

    public function testIsVisible()
    {
        $this->removeModule(\Modules::TRANSLATIONS, null);

        $isVisible = Product::isVisible();
        $expression = $isVisible($this->qb);

        $this->assertRegExp('/p.figure = :visible\d+/', $expression);
        preg_match('/p.figure = :(visible\d+)/', $expression, $matches);
        $this->assertSame('Y', $this->qb->getParameter($matches[1]));
    }

    public function testIsVisibleTranslations()
    {
        $this->switchLanguage();

        $isVisible = Product::isVisible();
        $expression = $isVisible($this->qb);

        $join = $this->qb->getQueryPart('join');

        $this->assertEquals([
            'joinType' => 'left',
            'joinTable' => 'products_translations',
            'joinAlias' => 'p_sk',
            'joinCondition' => 'p_sk.id_product = p.id AND p_sk.id_language = :translation_language_sk',
        ], $join['p'][0]);

        $this->assertRegExp('/COALESCE\(p_sk.figure, p.figure\) = :visible\d+/', $expression);
    }

    public function testInSection()
    {
        $result = $this->qb->select('*')->from('products', 'p')->where(Product::inSection(3))->execute()->fetchAll();

        $this->assertCount(3, $result);
    }

    /**
     * @param int $expectedCount
     *
     * @dataProvider productsInSections
     */
    public function testInSections(array $sectionIds, $expectedCount)
    {
        $count = $this->qb->select('*')->from('products', 'p')->where(Product::inSections($sectionIds))->execute()->rowCount();
        $this->assertSame($expectedCount, $count);
    }

    public function productsInSections()
    {
        return [
            [[3], 3],
            [[2, 3], 5],
        ];
    }

    /**
     * @dataProvider dataSet_testInStore
     *
     * @param bool $useVariations
     * @param int  $expectedCount
     */
    public function testInStore($useVariations, $expectedCount)
    {
        $count = $this->qb->select('*')->from('products', 'p')->where(Product::inStore($useVariations))->execute()->rowCount();

        $this->assertSame($expectedCount, $count);
    }

    public function dataSet_testInStore()
    {
        $dataSet = [];
        $dataSet['no variations'] = [false, 7];
        if (findModule('products_variations')) {
            $dataSet['variations'] = [true, 13];
        }

        return $dataSet;
    }

    /**
     * @todo add yml data to products_of_suppliers and refactor this test
     *
     * @dataProvider dataSet_testInStore
     */
    public function testInStoreSupplier($useVariations, $expectedCount)
    {
        $count = $this->qb->select('*')->from('products', 'p')
            ->andWhere(Filter::byInStore(\Filter::IN_STORE_SUPPLIER, $useVariations))
            ->execute()->rowCount();
        $this->assertSame($expectedCount, $count);
    }
}
