<?php

namespace Shop\Modules\AdminShopManagers;

use ActiveTable\ColumnTable;
use Core\Form\ControlBuilder;
use Core\Form\FormBuilder;
use Core\Form\Simpleform;
use Core\Helpers\Text;
use Diamond\Helpers\Form;
use Diamond\Repositories\User\UserCriteria;
use Diamond\Repositories\User\UserRepository;
use Diamond\Repositories\UserGroup\UserGroupCriteria;
use Diamond\Repositories\UserGroup\UserGroupRepository;
use DiamondTable\CommandFactory;
use DiamondTable\TableFactory;
use Shop\Config\Main;
use Shop\Domain\Manager\Contracts\ManagerEntityInterface;
use Shop\Modules\AdminShops\MoveCustomersCommand;
use Shop\Repositories\Customer\CustomerCriteria;
use Shop\Repositories\Customer\CustomerRepository;
use Shop\Repositories\Manager\ManagerCriteria;
use Shop\Repositories\Manager\ManagerRepository;
use Shop\Repositories\Stock\StockCriteria;
use Shop\Repositories\Stock\StockRepository;

/**
 * Description of AdminShopManagers
 *
 * @author Diamond Code Generator
 */
class AdminShopManagers extends \Core\ModuleController
{

    protected $customerRepository;
    protected $managerRepository;
    protected $tableFactory;
    protected $controlBuilder;
    protected $stockRepository;
    protected $userRepository;
    protected $userGroupRepository;
    protected $mainConf;
    protected $formBuilder;

    public function __construct(ManagerRepository   $managerRepository, TableFactory $tableFactory,
                                ControlBuilder      $controlBuilder,
                                StockRepository     $stockRepository,
                                UserRepository      $userRepository,
                                UserGroupRepository $userGroupRepository,
                                CustomerRepository  $customerRepository,
                                Main                $mainConf,
                                FormBuilder         $formBuilder
    )
    {
        $this->managerRepository = $managerRepository;
        $this->tableFactory = $tableFactory;
        $this->stockRepository = $stockRepository;
        $this->controlBuilder = $controlBuilder;
        $this->userRepository = $userRepository;
        $this->userGroupRepository = $userGroupRepository;
        $this->customerRepository = $customerRepository;
        $this->formBuilder = $formBuilder;
        $this->mainConf = $mainConf;
    }


    /**
     * @return string
     * @throws \ReflectionException
     * @throws \Repo\Concrete\Exceptions\Collection
     * @throws \Twig\Error\LoaderError
     * @throws \Twig\Error\RuntimeError
     * @throws \Twig\Error\SyntaxError
     */
    public function process(): string
    {

        $managersAr = $this->managerRepository->findByCriteria(
            ManagerCriteria::create()->setSortByName('ASC')
        );

        $table = $this->tableFactory->buildAdminTable($this->managerRepository, ManagerCriteria::create());
        $table->setDefaultSortColumn('id', 'DESC');
        $table
            ->addRowActionCommand(
                'move-customers-selected',
                new MoveCustomersCommand($table, $this->buildMoveCustomersForm(Form::prepareDropdown($managersAr, 'манеджер', 'getDropdownListWithShop')),
                    $this->customerRepository),
                'Перенос клиентов'
            );

        $stocks = $this->stockRepository->findByCriteria(
            StockCriteria::create()->setSortByTitle('ASC')
        );

        $userGroups = $this->userGroupRepository->findByCriteria(
            UserGroupCriteria::create()
        );

        $table->setCommand(CommandFactory::FORM_SAVE, new SaveManagerCommand($table, $this->userRepository));
        $table->setCommand(CommandFactory::ROWS_DELETE, new DeleteManagerCommand($table, $this->userRepository, $this->logger));
        $currentUserGroupId = null;
        if (input_get('id') > 0) {
            $manager = $this->managerRepository->findById(input_get('id'));
            if ($manager) {
                $users = $this->userRepository->findByCriteria(
                    UserCriteria::create()->setFilterByEmail($manager->getEmail())
                );
                $user = $users->current();
                if ($user) {
                    $currentUserGroupId = $users->current()->getGroupId();
                }

            }
        }

        $table
            ->addColumn(
                (new ColumnTable('id', '№'))
                    ->setWidth(40)
            )
            ->addColumn(
                (new ColumnTable('name', 'ФИО'))->setWidth(160)
            )
            ->addColumn(
                (new ColumnTable('email', 'Электронная почта'))->setWidth(160)
            )
            ->addColumn(
                (new ColumnTable('phone', 'Телефон'))->setWidth(160)
            )
            ->addColumn(
                (new ColumnTable('comment', 'Комментарий'))
                    ->setFormat($this, 'formatComment')
            )
            ->addColumn(
                (new ColumnTable('stockId', 'Торг.точка'))
                    ->setFormat($this, 'formatShop')
            )
            ->addColumn(
                (new ColumnTable('user', 'Доступ в админ.часть'))
                    ->setFormat($this, 'formatAccess')
            )
            ->addColumn(
                (new ColumnTable('customer', 'Клиентов'))
                    ->setFormat($this, 'formatCountCustomers')
                    ->setWidth(40)
            )
            ->addColumn(
                (new ColumnTable('actions', ''))
                    ->setFormat($this->tableFactory, 'formatActions')
                    ->setWidth(120)
            );

        $table
            ->addField(
                $this->controlBuilder->buildFormHeader('Основная информация о менеджере', 'main')
            )
            ->addField(
                $this->controlBuilder->buildInput('name'), true
            )
            ->addField(
                $this->controlBuilder->buildInput('email'), true, null, null, ['email']
            )
            ->addField(
                $this->controlBuilder->buildPhoneInput('phone', $this->mainConf->getMobileMask())
            )
            ->addField(
                $this->controlBuilder->buildTextArea('comment')
            )
            ->addField(
                $this->controlBuilder->buildDropdownUniform('shopId', Form::prepareDropdown($stocks)), true,
                'Торговая точка'
            )
            ->addField(
                $this->controlBuilder->buildDropdownUniform('userGroupId',
                    Form::prepareDropdownWithDef($userGroups, '', 'права доступа')
                )->setValue($currentUserGroupId), false,
                'Доступ в систему', 'персональный доступ к системе'
            );

        $table
            ->addFilter(
                $this->controlBuilder->buildInput('search_by_name')
            )
            ->addFilter(
                $this->controlBuilder->buildInput('search_by_email')
            )
            ->addFilter(
                $this->controlBuilder->buildDropdownUniform('filter_by_stockId', Form::prepareDropdown($stocks))
            );

        return $table->render();
    }

    public function formatCountCustomers(ManagerEntityInterface $managerEntity): string
    {
        $count = $this->customerRepository->count(CustomerCriteria::create()->setFilterByManagerId($managerEntity->getId()));

        return $count;
    }

    /**
     * @param ManagerEntityInterface $managerEntity
     * @return string
     * @throws \Repo\Concrete\Exceptions\Collection
     */
    public function formatAccess(ManagerEntityInterface $managerEntity): string
    {
        $users = $this->userRepository->findByCriteria(
            UserCriteria::create()->setFilterByEmail($managerEntity->getEmail())
        );

        if ($users->count() === 0) {
            return '-';
        } elseif ($users->count() > 1) {
            return Form::buildIcon('info', 'Обнаружено несколько пользователей привязанных к данному менеджеру');
        }
        $user = $users->current();

        $access = $user->getPassword() > '' ? '' : Form::buildIcon('info', 'Пароль не задан');

        return anchor('/admin/diamond/system/users?filter_by_id=' . $user->getId(),
            sprintf(
                '%s (%s) %s',
                $user->getName(),
                $user->getUserGroup()->getName(),
                $access
            )
            , [
                'target' => '_blank'
            ]);
    }

    /**
     * @param ManagerEntityInterface $managerEntity
     * @return string
     */
    public function formatComment(ManagerEntityInterface $managerEntity): string
    {
        return Text::clearText($managerEntity->getComment() ?? '', 120);
    }

    /**
     * @param ManagerEntityInterface $managerEntity
     * @return string
     */
    public function formatShop(ManagerEntityInterface $managerEntity): string
    {

        return $managerEntity->getShop()->getTitleWithType();
    }


    public function actionCreateUserAfterUpdate(array $data, \Core\Form\RepoForm $form)
    {
        try {
            if (!empty($data["userGroupId"])) {

                $user = $this->userService->creatOrUpdateUser($data["name"], $data["email"], $data["userGroupId"]);

                $form->addCustomMessage(
                    "Пользователь системы успешно создан",
                    \Core\Form\RepoForm::MESSAGE_SUCCESS
                );
            }

        } catch (\Diamond\Exceptions\UserException $ex) {

            $form->addCustomMessage(
                "Не удалось создать пользователя системы, ошибка: " . $ex->getMessage(),
                \Core\Form\RepoForm::MESSAGE_ERROR
            );
        }

        return true;
    }

    /**
     *
     * @param array $data
     * @param \Core\Form\RepoForm $form
     * @return boolean
     */
    public function actionManagerValidate(array $data, \Core\Form\RepoForm $form)
    {

        //редактирование записи, сразу выход
        if ($form->getEntity()->getId() > 0) {
            return $data;
        }

        $manager = \Shop\Models\Manager\ManagerQuery::create()
            ->findOneByEmail($data["email"]);

        if (!$manager) {
            return $data;
        }

        $form->addCustomMessage(sprintf(
            "Менеджер с указанным email `%s` уже существует, укажите другой email", $data["email"]
        ), \Core\Form\RepoForm::MESSAGE_ERROR);

        return false;
    }

    public function buildMoveCustomersForm(array $managersAr): Simpleform
    {
        $form = $this->formBuilder->buildSimpleValidationForm('move-customers');

        $ids = Form::getIdsFromRequest();

        foreach ($ids as $id) {
            unset($managersAr[(int)$id]);
        }

        $form
            ->addField(
                $this->controlBuilder->buildAutoDropdown('manager_id', $managersAr),
                'Новый менеджер для клиентов',
                ['required']
            )
            ->addField(
                $this->controlBuilder->buildHidden('ids', $ids)
            )
            ->addField(
                $this->controlBuilder->buildHidden('actiontype', input_post('actiontype'))
            )
            ->addControl(
                $this->controlBuilder->buildSubmitButton('submit_change_manager', 'Сменить менеджера')
            )
            ->addControl($this->controlBuilder->buildCancel('cancel',
                'Отмена'
            ));

        return $form;
    }

}               