<?php


namespace Shop\Modules\AdminShopManagers;


use ActiveTable\Contracts\CommandInterface;
use ActiveTable\DataTableEngine;
use Diamond\Repositories\User\UserCriteria;
use Diamond\Repositories\User\UserRepository;
use Propel\Runtime\Exception\PropelException;
use Psr\Log\LoggerInterface;
use Shop\Helpers\Form;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Twig\Error\RuntimeError;

class DeleteManagerCommand implements CommandInterface
{
    protected $tableEngine;
    protected $userRepository;
    protected $logger;

    public function __construct(DataTableEngine $tableEngine, UserRepository $userRepository, LoggerInterface $logger)
    {
        $this->tableEngine = $tableEngine;
        $this->userRepository = $userRepository;
        $this->logger = $logger;
    }

    public function process(): void
    {
        $engine = $this->tableEngine;
        $ids = \Diamond\Helpers\Form::getIdsFromRequest();
        
        if (!$ids) {
            Form::addTableNotice(
                Form::buildErrorMessage('Не выбранны записи для удаления')
            );
        } else {

            $success = $error = [];

            foreach ($ids as $id) {
                try {
                    if (!$entity = $engine->getRepo()->findById($id)) {
                        throw new \RuntimeException('entity not found by id ' . $id);
                    }

                    $users = $this->userRepository->findByCriteria(
                      UserCriteria::create()->setFilterByEmail($entity->getEmail())
                    );

                    $user = $users->current();

                    if($user) {
                        $this->userRepository->delete($user);
                    }

                    $engine->getRepo()->delete($entity);

                    $success [] = $id;
                } catch (\RuntimeException | RuntimeError |  PropelException $ex) {
                    $error [] = $id;

                    if(is_a($ex,PropelException::class)){
                        while($ex = $ex->getPrevious()){
                            if(preg_match('~constraint\sfails\s.*?\(.*?\.(.*?)\,~is',$ex->getMessage(),$match)){
                                $error_caption[$id] = 'Имеется относящийся к удаляемой записи `'.$id.'` документ в таблице ' . $match[1];
                                break;
                            }
                        }
                    }
                    $this->logger->error($ex->getMessage());
                }
            }

            if (count($success)) {

                $text = count($ids) === 1 ?
                    sprintf(
                        'Выбранная запись № %s успешно удалена!',
                        implode(',', $success)
                    ) :
                    sprintf(
                        'Выбранные записи № %s успешно удалены!',
                        implode(',', $success)
                    );

                Form::addTableNotice(
                    Form::buildSuccessMessage($text)
                );
            }

            if (count($error)) {

                $text = count($ids) === 1 ?
                    sprintf(
                        'Запись № %s не получилось удалить',
                        implode(',', $error)
                    ) :
                    sprintf(
                        'Следующие записи № %s не получилось удалить',
                        implode(',', $error)
                    );

                if(count($error_caption)){
                    $text .= '. '. implode(',', $error_caption);
                }

                Form::addTableNotice(
                    Form::buildErrorMessage($text)
                );
            }
        }
        RedirectResponse::create(adaptive_url([], ['fn', 'id']))->send();
    }

}