<?php

namespace KupShop\CatalogBundle\Product;

use KupShop\KupShopBundle\Util\Functional\Mapping;
use KupShop\KupShopBundle\Util\StringUtil;
use Query\Operator;

class ProductFinder
{
    use \DatabaseCommunication;

    protected ?array $listProducers = null;

    public function findProduct($code)
    {
        if ($code == '') {
            return null;
        }

        $SQL = $this->selectSQL('products', ['code' => $code]);

        if (sqlNumRows($SQL) == 0) {
            $vatId = getAdminVat()['id'];

            return sqlGetConnection()->transactional(
                function () use ($code, $vatId) {
                    $this->insertSQL(
                        'products',
                        [
                            'title' => $code,
                            'code' => $code,
                            'vat' => $vatId,
                            'date_added' => date('Y-m-d H:i:s'),
                        ]
                    );

                    return sqlInsertId();
                }
            );
        }

        return sqlFetchAssoc($SQL)['id'];
    }

    public function getProductIdByCode(string $code): ?int
    {
        return $this->getIdByCode($code);
    }

    public function getVariationIdByCode(string $code): ?int
    {
        return $this->getIdByCode($code, 'products_variations');
    }

    protected function getIdByCode(string $code, string $tableName = 'products'): ?int
    {
        $id = sqlQueryBuilder()
            ->select('id')
            ->from($tableName)
            ->where(Operator::equals(['code' => $code]))
            ->execute()->fetchOne();

        if (!$id) {
            return null;
        }

        return (int) $id;
    }

    protected $listVAT;

    public function findVAT($percent)
    {
        if (is_null($this->listVAT)) {
            $this->listVAT = sqlFetchAll(sqlQuery('SELECT id, vat, is_default FROM vats'), ['id' => 'vat']);
        }

        if ($index = array_search($percent, $this->listVAT)) {
            return $index;
        }

        $this->insertSQL('vats', ['descr' => "Daň {$percent}%", 'vat' => $percent]);
        $index = sqlInsertId();

        $this->listVAT[$index] = $percent;

        return $index;
    }

    public function findProducer(string $producer): int
    {
        if ($this->listProducers === null) {
            $this->listProducers = Mapping::mapKeys(
                sqlQueryBuilder()
                    ->select('id, name')
                    ->from('producers')
                    ->execute()->fetchAllAssociative(),
                fn ($k, $v) => [StringUtil::slugify($v['name']), (int) $v['id']]
            );
        }

        $key = StringUtil::slugify($producer);

        if (!($this->listProducers[$key] ?? false)) {
            $this->listProducers[$key] = sqlGetConnection()->transactional(function () use ($producer) {
                sqlQueryBuilder()
                    ->insert('producers')
                    ->directValues(
                        [
                            'name' => $producer,
                        ]
                    )->execute();

                return (int) sqlInsertId();
            });
        }

        return $this->listProducers[$key];
    }
}
