<?php

namespace KupShop\PohodaBundle\Utils\Importers;

use KupShop\KupShopBundle\Email\NewsletterSubscribeEmail;
use KupShop\KupShopBundle\Email\PasswordResetAdminEmail;
use KupShop\KupShopBundle\Util\StringUtil;
use KupShop\PohodaBundle\Utils\PohodaBase;
use KupShop\UserBundle\Util\UserImporter;
use Query\Operator;

class UsersImporter extends UserImporter
{
    use PohodaBase;

    protected $request_template = 'requests/usersIn.tpl';
    protected $xslt = 'usersIn.xsl';
    protected $mainIdentifier = 'pohoda_id';

    protected $insertUser = true;

    /**
     * @var PasswordResetAdminEmail
     */
    protected $passwordResetAdminEmail;

    /**
     * @var NewsletterSubscribeEmail
     */
    protected $newsletterSubscribeEmail;

    /**
     * @throws \KupShop\PohodaBundle\Exceptions\PohodaException
     */
    public function processData($XMLStringResponse = null)
    {
        if ($this->pohodaConnector->getCurrentKey() != $this->pohodaConnector->getDefaultKey()) {
            return;
        }

        $this->pohodaConnector->prepareSyncTime();
        if (!$XMLStringResponse) {
            $XMLStringResponse = $this->getData();
        }

        $resultXML = $this->transformHelper->baseTransform($XMLStringResponse, $this->transformHelper->loadXslt($this->xslt));
        $this->importUsers($resultXML);

        $this->pohodaConnector->setLastSyncTime('usersIn');
    }

    /**
     * @return bool|false|string|string[]|null
     *
     * @throws \KupShop\PohodaBundle\Exceptions\PohodaException
     * @throws \SmartyException
     */
    public function getData()
    {
        $request = $this->pohodaConnector->getRequestContent($this->request_template, ['full' => $this->isFullSync()]);

        $request = $this->replace($request);

        return $this->pohodaConnector->sendRequest($request);
    }

    /**
     * @required
     */
    public function setPasswordResetAdminEmail(PasswordResetAdminEmail $passwordResetAdminEmail): void
    {
        $this->passwordResetAdminEmail = $passwordResetAdminEmail;
    }

    /**
     * @required
     */
    public function setNewsletterSubscribeEmail(NewsletterSubscribeEmail $newsletterSubscribeEmail): void
    {
        $this->newsletterSubscribeEmail = $newsletterSubscribeEmail;
    }

    protected function addAdditionalFields(&$userArray, \SimpleXMLElement $user)
    {
        $userArray['pohoda_id'] = strval($user->ID);
        if (!empty(strval($user->DELIVERY->ID))) {
            $userArray['pohoda_id_address'] = strval($user->DELIVERY->ID);
        }
    }

    protected function beforeInsertUserAction($userRow)
    {
        $userArray['date_reg'] = $userRow['date_reg'] ?: (new \DateTime())->format('Y-m-d H:i:s');
    }

    protected function insertUserAction($userId)
    {
        $user = \User::createFromId($userId);

        if (findModule(\Modules::POHODA, \Modules::SUB_USERS_SEND_REG_EMAIL) && $user['email']) {
            $this->passwordResetAdminEmail->setUser($user);
            $message = $this->passwordResetAdminEmail->getEmail();
            $message['to'] = $user['email'];
            $this->passwordResetAdminEmail->sendEmail($message);

            $this->newsletterSubscribeEmail->setEmail($user['email']);
            $message = $this->newsletterSubscribeEmail->getEmail();
            $message['to'] = $user['email'];
            $this->newsletterSubscribeEmail->sendEmail($message);
        }
    }

    /**
     * @param bool $recourse
     */
    protected function processUser(array $localUser, array $existingUsers, $recourse = true): void
    {
        if (array_key_exists(trim(StringUtil::normalize($localUser['email'])), $existingUsers)) {
            try {
                sqlQueryBuilder()
                            ->update('users')
                            ->directValues($localUser)
                            ->andWhere(Operator::equals(['email' => $localUser['email']]))
                            ->execute();
            } catch (\Exception $exception) {
                switch (intval($exception->getPrevious()->errorInfo[1])) {
                    case 1062:
                        sqlQueryBuilder()
                            ->delete('users')
                            ->andWhere(Operator::equals(['email' => $localUser['email']]))
                            ->execute();

                        if ($recourse) {
                            $this->processUser($localUser, $existingUsers, false);
                        }
                        break;
                }
            }
        } elseif (array_key_exists($this->mainIdentifier, $localUser) && in_array($localUser[$this->mainIdentifier], $existingUsers)) {
            try {
                sqlQueryBuilder()
                            ->update('users')
                            ->directValues($localUser)
                            ->andWhere(Operator::equals([$this->mainIdentifier => $localUser[$this->mainIdentifier]]))
                            ->execute();
            } catch (\Exception $exception) {
                switch (intval($exception->getPrevious()->errorInfo[1])) {
                    case 1062:
                        sqlQueryBuilder()
                            ->delete('users')
                            ->andWhere(Operator::equals([$this->mainIdentifier => $localUser[$this->mainIdentifier]]))
                            ->execute();

                        if ($recourse) {
                            $this->processUser($localUser, $existingUsers, false);
                        }
                        break;
                }
            }
        } elseif ($this->insertUser) {
            sqlQueryBuilder()
                        ->insert('users')
                        ->directValues($localUser)
                        ->execute();
            $userId = sqlInsertId();
            $this->insertUserAction($userId);
        }
    }

    public function importUser($user)
    {
        $this->addResponseLog('Users Import', $user);

        return parent::importUser($user);
    }
}
