<?php

declare(strict_types=1);

namespace External\ZNZBundle\Synchronizers;

use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use External\ZNZBundle\Exception\ZNZException;
use External\ZNZBundle\Util\ZNZApi;
use External\ZNZBundle\Util\ZNZUtil;
use KupShop\AdminBundle\Util\ActivityLog;
use KupShop\KupShopBundle\Context\ContextManager;
use KupShop\KupShopBundle\Context\CountryContext;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Email\PasswordResetAdminEmail;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\Database\QueryHint;
use KupShop\KupShopBundle\Util\System\TokenGenerator;
use KupShop\SynchronizationBundle\Exception\RabbitRetryMessageException;
use Query\Operator;
use Query\QueryBuilder;
use Symfony\Contracts\Service\Attribute\Required;

class UserSynchronizer extends BaseSynchronizer implements SynchronizerOutInterface
{
    protected static string $type = 'user';
    public static string $typeGroups = 'users_group';

    #[Required]
    public ZNZApi $znzApi;
    #[Required]
    public TokenGenerator $tokenGenerator;
    #[Required]
    public ContextManager $contextManager;
    #[Required]
    public PasswordResetAdminEmail $passwordResetAdminEmail;

    public static function getPriority(): int
    {
        return 99;
    }

    public static function getHandledTables(): array
    {
        return [
            'ZakaznickaSkupina' => 'processUserGroup',
            'Zakaznici' => 'processUser',
            'Adresy' => 'processUserAddress',
            'CenoveUrovneVazby' => 'processUserGroupPriceListRelation',
        ];
    }

    public function useTestConnection(): bool
    {
        return !$this->configuration->useProductionHelios();
    }

    public static function getIdField(): ?string
    {
        return 'IdZakaznik';
    }

    public function processToHelios(): void
    {
        if (isLocalDevelopment()) {
            return;
        }

        $lastSyncTime = $this->getLastSyncTime();

        $orSpecs = ['zu.id_znz IS NULL'];
        if ($lastSyncTime) {
            $orSpecs[] = 'u.date_updated IS NOT NULL AND u.date_updated > :filterDate';
        }

        $qb = sqlQueryBuilder()
            ->select('u.*, zu.id_znz, zu.id_znz_invoice, zu.id_znz_delivery')
            ->from('users', 'u')
            ->leftJoin('u', 'znz_users', 'zu', 'zu.id_user = u.id')
            ->andWhere(
                Operator::andX(
                    $this->getUsersToHeliosSpec(),
                    // podminky pro zapis uzivatele
                    Operator::orX($orSpecs)
                )
            )
            // order by date_updated with newly registered at the beginning
            ->orderBySql('zu.id_znz IS NULL DESC, u.date_updated ASC')
            ->groupBy('u.id');

        if ($lastSyncTime) {
            $qb->setParameter('filterDate', $lastSyncTime->format('Y-m-d H:i:s'));
        }

        // max 250 per one sync run
        $qb->setMaxResults(250);

        $updateLastSyncTime = null;
        foreach ($qb->execute() as $item) {
            $user = new \User();
            $user->loadData($item);

            $userData = $this->getUserData($user, !empty($item['id_znz']) ? (int) $item['id_znz'] : null);

            // save date_updated of last synchronized item
            if (!empty($item['id_znz']) && !empty($item['date_updated'])) {
                $updateLastSyncTime = (new \DateTime($item['date_updated']))->getTimestamp();
            }

            try {
                $znzId = ZNZUtil::withRetryStrategy(fn () => $this->getZNZApi()->updateUser($userData), false);
            } catch (\Exception $e) {
                $this->logger->log($e);
                continue;
            }

            if (empty($item['id_znz'])) {
                $this->znzUtil->createMapping(self::$type, $znzId, (int) $item['id']);
            }

            $addresses = $this->getUserAddresses(
                $user,
                !empty($item['id_znz_invoice']) ? (int) $item['id_znz_invoice'] : null,
                !empty($item['id_znz_delivery']) ? (int) $item['id_znz_delivery'] : null
            );

            $invoiceAddress = $addresses['invoice'];
            $deliveryAddress = $addresses['delivery'];

            // pokud uz je fakturacni adresa v Heliosu zalozena, nebo je vyplnena adresa na e-shopu
            if ($item['id_znz_invoice'] || !empty($invoiceAddress['firstname'])) {
                try {
                    $znzInvoiceId = ZNZUtil::withRetryStrategy(fn () => $this->getZNZApi()->updateUserAddress($invoiceAddress), false);
                } catch (\Exception $e) {
                    $this->logger->log($e);
                }

                if (empty($item['id_znz_invoice']) && isset($znzInvoiceId)) {
                    sqlQueryBuilder()
                        ->update('znz_users')
                        ->directValues(['id_znz_invoice' => $znzInvoiceId])
                        ->where(Operator::equals(['id_user' => $user->id]))
                        ->execute();
                }
            }

            // pokud uz je dorucovaci adresa v Heliosu zalozena, nebo je vyplnena adresa na e-shopu
            if ($item['id_znz_delivery'] || !empty($deliveryAddress['firstname'])) {
                try {
                    $znzDeliveryId = ZNZUtil::withRetryStrategy(fn () => $this->getZNZApi()->updateUserAddress($deliveryAddress), false);
                } catch (\Exception $e) {
                    $this->logger->log($e);
                }

                if (empty($item['id_znz_delivery']) && isset($znzDeliveryId)) {
                    sqlQueryBuilder()
                        ->update('znz_users')
                        ->directValues(['id_znz_delivery' => $znzDeliveryId])
                        ->where(Operator::equals(['id_user' => $user->id]))
                        ->execute();
                }
            }
        }

        if ($updateLastSyncTime) {
            $this->updateLastSyncTime($updateLastSyncTime);
        }
    }

    public function getUserData(\User $user, ?int $znzId = null): array
    {
        $user->fetchAddresses();

        $data = [
            'email' => $user->email,
            'firstname' => $user->invoice['name'],
            'middlename' => '',
            'lastname' => $user->invoice['surname'],
            'group_id' => $this->getUserGroupId($user),
            '_website' => $this->getUserWebsite($user),
            'helios_customer_id' => $znzId,
            'helios_activity_type' => null,
            'helios_legal_form' => 2, // 0=Právnická osoba 1=Fyzická osoba 2=Soukromá osoba 3=Neurčeno
        ];

        return $data;
    }

    protected function processUser(array $item): void
    {
        $userId = $this->znzUtil->getMapping(self::$type, $item['IdZakaznik']);

        if ($item['meta']['delete']) {
            if ($userId) {
                sqlQueryBuilder()
                    ->delete('users')
                    ->where(Operator::equals(['id' => $userId]))
                    ->execute();

                $this->logger->activity(sprintf('Proběhlo smazání uživatele: %s (%s)', $userId, $item['email'] ?? ''), [
                    'item' => $item,
                ]);
            }

            return;
        }

        if (empty($item['email'])) {
            return;
        }

        if (!$userId) {
            $registrationData = [
                'email' => $item['email'],
                'passw' => !empty($item['HashHeslo']) ? $item['HashHeslo'] : '',
                'date_reg' => (new \DateTime())->format('Y-m-d H:i:s'),
            ];

            try {
                $userId = sqlGetConnection()->transactional(function () use ($item, $registrationData) {
                    sqlQueryBuilder()
                        ->insert('users')
                        ->directValues($registrationData)
                        ->execute();

                    $userId = (int) sqlInsertId();

                    $this->znzUtil->createMapping(self::$type, $item['IdZakaznik'], $userId);

                    return $userId;
                });
            } catch (UniqueConstraintViolationException $e) {
                if ($this->tryMergeWithNewsletterUser($userId, $registrationData)) {
                    $this->znzUtil->createMapping(self::$type, $item['IdZakaznik'], $userId);
                } else {
                    throw new ZNZException(
                        sprintf('Unable to create user because of duplicated email: %s:%s', $item['IdZakaznik'], $item['email']),
                        [
                            'user' => $item,
                        ]
                    );
                }
            }

            if ($this->configuration->isB2BShop()) {
                $this->activateUserB2BFeeds($userId);
            }
        }

        $hasEmptyPassword = sqlQueryBuilder()
            ->select('1')
            ->from('users')
            ->where(Operator::equals(['id' => $userId, 'passw' => '']))
            ->execute()->fetchOne();

        $update = [
            'id_language' => $this->getUserLanguageByWebsite($item['IdWebsite']),
            'email' => $item['email'],
        ];

        // pokud se nejedna o B2B shop, tak aktualizuju i figure zakaznika
        if (!$this->configuration->isB2BShop()) {
            $update['figure'] = $item['Aktivni'] ? 'Y' : 'N';
        }

        if ($hasEmptyPassword && !empty($item['HashHeslo'])) {
            $update['passw'] = $item['HashHeslo'];
        }

        try {
            sqlQueryBuilder()
                ->update('users')
                ->directValues($update)
                ->where(Operator::equals(['id' => $userId]))
                ->execute();
        } catch (UniqueConstraintViolationException $e) {
            if (!$this->tryMergeWithNewsletterUser($userId, $update)) {
                throw new ZNZException(
                    sprintf('Unable to update user "%s" because of duplicated email: %s:%s', $userId, $item['IdZakaznik'], $item['email']),
                    [
                        'item' => $item,
                        'userId' => $userId,
                    ]
                );
            }
        }

        $this->updateUserGroup($userId, $item['IdZakaznickaSkupina']);
        $this->updateUserData($userId, $item);

        if ($this->configuration->isB2BShop()) {
            $this->activateB2BUser($userId, $item);
        }
    }

    protected function processUserAddress(array $item): void
    {
        if (!($mapping = $this->znzUtil->getUserMapping($item['IdZakaznik']))) {
            return;
        }

        if ($item['meta']['delete']) {
            return;
        }

        $prefix = '';
        $mappingField = 'id_znz_invoice';
        if (!$item['Fakturacni']) {
            $prefix = 'delivery_';
            $mappingField = 'id_znz_delivery';
        }

        $userName = $this->znzUtil->getUserNameParts($item['Nazev']);

        $update = [
            $prefix.'name' => $userName['name'],
            $prefix.'surname' => $userName['surname'],
            $prefix.'firm' => $item['DruhyNazev'],
            $prefix.'city' => $item['Misto'],
            $prefix.'street' => $item['Ulice'],
            $prefix.'zip' => $item['PSC'],
            $prefix.'country' => $this->znzUtil->getCountryCodeForHelios($item['IdZeme'] ?? Contexts::get(CountryContext::class)->getDefaultId()),
            $prefix.'phone' => $item['Telefon'],
        ];

        if ($item['Fakturacni']) {
            if (!empty($item['DIC'])) {
                $update[$prefix.'dic'] = trim($item['DIC']);
            }

            // fakturacni email
            if (!empty($item['Email'])) {
                $update['copy_email'] = $item['Email'];
            }
        }

        sqlQueryBuilder()
            ->update('users')
            ->directValues($update)
            ->where(Operator::equals(['id' => $mapping['id_user']]))
            ->execute();

        if (empty($mapping['id_znz_invoice'])) {
            sqlQueryBuilder()
                ->update('znz_users')
                ->directValues(
                    [
                        $mappingField => $item['IdAdresa'],
                    ]
                )
                ->where(Operator::equals(['id_user' => $mapping['id_user']]))
                ->execute();
        }
    }

    protected function processUserGroup(array $item): void
    {
        if ($this->isDeleteMessage($item)) {
            if ($userGroupId = $this->znzUtil->getMapping(self::$typeGroups, $item['meta']['unique_id'])) {
                sqlQueryBuilder()
                    ->delete('users_groups')
                    ->where(Operator::equals(['id' => $userGroupId]))
                    ->execute();
            }

            return;
        }

        if (!($userGroupId = $this->znzUtil->getMapping(self::$typeGroups, $item['IdZakaznickaSkupina']))) {
            sqlGetConnection()->transactional(function () use ($item) {
                sqlQueryBuilder()
                    ->insert('users_groups')
                    ->directValues(
                        [
                            'name' => $item['Nazev'],
                        ]
                    )->execute();

                $userGroupId = (int) sqlInsertId();

                $this->znzUtil->createMapping(self::$typeGroups, $item['IdZakaznickaSkupina'], $userGroupId);

                return $userGroupId;
            });
        }

        try {
            sqlQueryBuilder()
                ->update('users_groups')
                ->directValues(
                    [
                        'name' => $item['Nazev'],
                        'descr' => $item['Cislo'],
                    ]
                )
                ->where(Operator::equals(['id' => $userGroupId]))
                ->execute();
        } catch (UniqueConstraintViolationException $e) {
            sqlQueryBuilder()
                ->update('users_groups')
                ->directValues(
                    [
                        'name' => "{$item['Nazev']} (2)",
                        'descr' => $item['Cislo'],
                    ]
                )
                ->where(Operator::equals(['id' => $userGroupId]))
                ->execute();
        }
    }

    public function processUserGroupPriceListRelation(array $item): void
    {
        // pokud se nejedna o B2B rezim a poradi je vetsi jak 1, tak to ignoruju
        if (!$this->configuration->isB2BMode() && ($item['Poradi'] ?? null) > 1) {
            return;
        }

        if (!($userGroupId = $this->znzUtil->getMapping(self::$typeGroups, $item['IdZakaznickaSkupina']))) {
            throw new RabbitRetryMessageException('User group not found');
        }

        if (!($priceListId = $this->znzUtil->getMapping(PriceListSynchronizer::getType(), $item['CenovaUroven']))) {
            throw new RabbitRetryMessageException('Price list not found');
        }

        $update = ['id_pricelist' => $priceListId];

        if ($this->configuration->isB2BShop()) {
            $data = $this->getUserGroupData($userGroupId);
            $data['znz']['stores'][$item['Poradi'] ?? 0] = null;
            if (!empty($item['IdSklad'])) {
                if ($storeId = $this->znzUtil->getMapping('store', $item['IdSklad'])) {
                    $data['znz']['stores'][$item['Poradi'] ?? 0] = $storeId;
                }
            }
            $update['data'] = json_encode($data);
        }

        sqlQueryBuilder()
            ->update('users_groups')
            ->directValues($update)
            ->where(Operator::equals(['id' => $userGroupId]))
            ->execute();
    }

    public function getUserAddresses(\User $user, ?int $znzInvoiceId = null, ?int $znzDeliveryId = null): array
    {
        // nacitam z masteru, protoze se stalo, ze se uzivatel registrovat v 14:40:58 a v 14:41:00 se spustila sync, ktera
        // ho zacala odesilat, ale fetchAddresses sel na slave, kde ten uzivatel jeste chybel a timpadem se udaje nenacetly
        QueryHint::withRouteToMaster(fn () => $user->fetchAddresses());

        return [
            'invoice' => $this->getUserAddress($user, $znzInvoiceId),
            'delivery' => $this->getUserAddress($user, $znzDeliveryId, 'delivery'),
        ];
    }

    private function getUserGroupId(\User $user): int
    {
        $groupIds = $this->configuration->getSettings()['user']['groupId'] ?? [];

        $groupId = $groupIds[$user->id_language] ?? null;
        if (empty($groupId)) {
            $groupId = reset($groupIds);
            if (!empty($groupId)) {
                return (int) $groupId;
            }

            return 80;
        }

        return (int) $groupId;
    }

    private function getUserAddress(\User $user, ?int $znzId, string $type = 'invoice'): array
    {
        return [
            'helios_addr_id' => $znzId,
            'firstname' => $user->{$type}['name'],
            'middlename' => '',
            'lastname' => $user->{$type}['surname'],
            'company' => $user->{$type}['firm'],
            'street' => $user->{$type}['street'],
            'city' => $user->{$type}['city'],
            'postcode' => $user->{$type}['zip'],
            'telephone' => $user->{$type}['phone'],
            'vat_id' => $user->invoice['dic'],
            'helios_company_registration_number' => $user->invoice['ico'],
            'region_id' => '',
            'country_id' => $this->getUserCountry($user, $type),
            '_email' => $user->invoice['email'],
            '_website' => $this->getUserWebsite($user),
            '_address_default_billing_' => $type === 'invoice' ? 1 : 0,
            '_address_default_shipping_' => $type === 'delivery' ? 1 : 0,
        ];
    }

    private function getUserWebsite(\User $user): string
    {
        return $this->znzUtil->getCurrentWebsite(
            $this->getUserLanguage($user)
        );
    }

    private function getUserLanguage(\User $user): string
    {
        $language = $user->id_language ?: Contexts::get(LanguageContext::class)->getDefaultId();
        if (empty($user->id_language) && !empty($user->invoice['country'])) {
            $language = match ($user->invoice['country']) {
                'CZ' => 'cs',
                'SK' => 'sk',
                'IT' => 'it',
                'FR' => 'fr',
                'DE' => 'de',
                default => Contexts::get(LanguageContext::class)->getDefaultId(),
            };
        }

        return $language;
    }

    private function getUserCountry(\User $user, string $type): string
    {
        $country = $user->{$type}['country'];

        if (empty($country)) {
            $country = match ($this->getUserLanguage($user)) {
                'cs' => 'CZ',
                'sk' => 'SK',
                'it' => 'IT',
                'fr' => 'FR',
                'de' => 'DE',
                default => Contexts::get(CountryContext::class)->getDefaultId(),
            };
        }

        return $this->znzUtil->getCountryCodeForHelios($country);
    }

    private function getUserLanguageByWebsite(string $website): string
    {
        $websites = $this->configuration->getSupportedWebsites();

        $language = reset($websites)['language'] ?? Contexts::get(LanguageContext::class)->getDefaultId();
        if ($websites[$website] ?? false) {
            $language = $websites[$website]['language'] ?? $language;
        }

        if (is_array($language)) {
            $language = reset($language);
        }

        return $language;
    }

    private function updateUserData(int $userId, array $item): void
    {
        $turnoverData = [];
        if (!empty($item['SlevoveMeze'])) {
            $turnoverData = [
                'slevaProcentem' => $item['slevaProcentem'],
                'MenaObratu' => $item['MenaObratu'],
                'Obrat' => $item['Obrat'],
                'SledovatObratDnu' => $item['SledovatObratDnu'],
                'SlevoveMeze' => json_decode($item['SlevoveMeze'] ?: '', true) ?: [],
            ];
        }

        $data = [
            'feeds' => [
                'ObrazkyPovoleny' => $item['ObrazkyPovoleny'] ?? false,
                'PopiskyPovoleny' => $item['PopiskyPovoleny'] ?? false,
            ],
            'turnoverData' => $turnoverData,
        ];

        $user = new \User();
        $user->id = $userId;
        $user->setCustomData('znz', $data);
    }

    private function updateUserGroup(int $userId, $znzUserGroupId): void
    {
        $znzGroups = array_map(fn ($x) => $x['id_users_group'], sqlQueryBuilder()
            ->select('id_users_group')
            ->from('znz_users_groups')
            ->execute()->fetchAllAssociative());

        if (!empty($znzGroups)) {
            sqlQueryBuilder()
                ->delete('users_groups_relations')
                ->andWhere(Operator::equals(['id_user' => $userId]))
                ->andWhere(Operator::inIntArray($znzGroups, 'id_group'))
                ->execute();
        }

        $userGroupId = $this->znzUtil->getMapping(self::$typeGroups, $znzUserGroupId);

        // pokud mam ZNZ Group ID, ale nepodarilo se najit skupinu na shopu, tak zaloguju chybu do activity logu
        if (!empty($znzUserGroupId) && !$userGroupId) {
            $this->logger->activity(
                sprintf('Uživatele "%s" se nepodařilo zařadit do skupiny "%s", protože skupina neexistuje!', $userId, $znzUserGroupId),
                [
                    'userId' => $userId,
                    'znzGroupId' => $znzUserGroupId,
                ]
            );
        }

        if ($userGroupId) {
            $this->setUserGroup($userId, $userGroupId);
        }
    }

    private function setUserGroup(int $userId, int $userGroupId): void
    {
        try {
            sqlQueryBuilder()
                ->insert('users_groups_relations')
                ->directValues(
                    [
                        'id_user' => $userId,
                        'id_group' => $userGroupId,
                    ]
                )->execute();
        } catch (UniqueConstraintViolationException) {
        }
    }

    private function tryMergeWithNewsletterUser(?int &$userId, array $data): bool
    {
        $duplicatedUser = sqlQueryBuilder()
            ->select('id, figure, get_news, date_subscribe, date_unsubscribe')
            ->from('users')
            ->where(Operator::equals(['email' => $data['email']]))
            ->execute()->fetchAssociative();

        if ($duplicatedUser['id'] === $userId) {
            return false;
        }

        $isNewsletterUser = false;
        // je to newsletter user
        if ($duplicatedUser['figure'] === 'N' && $duplicatedUser['get_news'] === 'Y') {
            $isNewsletterUser = true;
        }

        if (!$isNewsletterUser) {
            return false;
        }

        $data['get_news'] = $duplicatedUser['get_news'];
        $data['date_subscribe'] = $duplicatedUser['date_subscribe'];
        $data['date_unsubscribe'] = $duplicatedUser['date_unsubscribe'];

        $deleteDuplicatedUser = true;
        if ($userId === null && $duplicatedUser['id']) {
            $userId = $duplicatedUser['id'];
            $deleteDuplicatedUser = false;
        }

        sqlGetConnection()->transactional(function () use ($duplicatedUser, $userId, $deleteDuplicatedUser, $data) {
            if ($deleteDuplicatedUser) {
                sqlQueryBuilder()
                    ->delete('users')
                    ->where(Operator::equals(['id' => $duplicatedUser['id']]))
                    ->execute();
            }

            sqlQueryBuilder()
                ->update('users')
                ->directValues($data)
                ->where(Operator::equals(['id' => $userId]))
                ->execute();
        });

        return true;
    }

    private function getUserGroupData(int $userGroupId): array
    {
        $data = sqlQueryBuilder()
            ->select('data')
            ->from('users_groups')
            ->where(Operator::equals(['id' => $userGroupId]))
            ->execute()->fetchOne();

        return json_decode($data ?: '', true) ?? [];
    }

    private function activateB2BUser(int $userId, array $item): void
    {
        // activate inactive user if they need to be assigned to a group
        if (!$this->isUserActive($userId) && !empty($item['IdZakaznickaSkupina'])) {
            sqlQueryBuilder()
                ->update('users')
                ->directValues(['figure' => 'Y'])
                ->where(Operator::equals(['id' => $userId]))
                ->execute();

            $this->sendPasswordEmail($userId);

            $this->logger->activity(
                message: "Provedena aktivace B2B účtu `{$item['email']}` a odeslán mail pro nastavení hesla",
                data: ['userId' => $userId],
                severity: ActivityLog::SEVERITY_NOTICE
            );
        }

        // activate B2B feeds
        $this->activateUserB2BFeeds($userId);
        // assign user to B2B group
        $this->setUserGroup($userId, $this->configuration->getB2BGroup());
    }

    private function sendPasswordEmail(int $userId): void
    {
        if (!($user = \User::createFromId($userId))) {
            return;
        }

        $emailService = clone $this->passwordResetAdminEmail;

        $this->contextManager->activateContexts(
            [LanguageContext::class => $user->id_language ?: Contexts::get(LanguageContext::class)->getDefaultId()],
            function () use ($emailService, $user) {
                $message = $emailService->getEmail();
                $message['to'] = $user->email;

                $emailService->sendEmail($message);
            }
        );
    }

    private function activateUserB2BFeeds(int $userId): void
    {
        if (!findModule(\Modules::XML_FEEDS_B2B)) {
            return;
        }

        // prvotni aktivace feedu pro B2B uzivatele (vygenerovat token pokud jeste neexistuje)
        sqlQueryBuilder()
            ->update('users')
            ->directValues(['feed_token' => $this->tokenGenerator->generate(15)])
            ->andWhere(Operator::equals(['id' => $userId]))
            ->andWhere('feed_token IS NULL')
            ->execute();
    }

    private function isUserActive(int $userId): bool
    {
        return sqlQueryBuilder()
            ->select('figure')
            ->from('users')
            ->where(Operator::equals(['id' => $userId]))
            ->sendToMaster()
            ->execute()->fetchOne() === 'Y';
    }

    private function getUsersToHeliosSpec(): callable
    {
        if ($this->configuration->isB2BShop()) {
            // v pripade B2B uzivatele neresime viditelnost uzivatele
            // protoze chceme zapsat i neaktivniho uzivatele, kterej vytvoril pozadavek na registraci
            return function (QueryBuilder $qb) {
                $qb->leftJoin('u', 'users_groups_relations', 'ugr', 'ugr.id_user = u.id');

                return Operator::inIntArray(
                    array_filter([$this->configuration->getB2BGroup(), $this->configuration->getB2BRegistrationGroup()]),
                    'ugr.id_group'
                );
            };
        }

        // v pripade B2C zapisujeme pouze viditelne uzivatele
        return Operator::equals(['u.figure' => 'Y']);
    }
}
