<?php

namespace Shop\Presentation\Modules\AdminClients;

use ActiveTable\ColumnTable;
use ActiveTable\DataTableEngine;
use Core\Form\Control\MenuItem;
use Core\Form\Control\MenuItemAction;
use Core\Form\ControlBuilder;
use Core\Form\FormBuilder;
use Core\Form\NiftyControlBuilder;
use Core\Form\Simpleform;
use Core\ModuleController;
use Diamond\Helpers\Form;
use DiamondTable\TableFactory;
use Diamond\Application\Notification\NotificationService;
use Shop\Application\Office\OfficeService;
use Shop\Domain\Customer\Contracts\CustomerEntityInterface;
use Shop\Presentation\Config\Main;
use Shop\Domain\CustomerGroup\CustomerGroupCollection;
use Shop\Domain\Manager\ManagerCollection;
use Shop\Infrastructure\Repositories\City\CityRepository;
use Shop\Infrastructure\Repositories\Country\CountryRepository;
use Shop\Infrastructure\Repositories\Customer\CustomerCriteria;
use Shop\Infrastructure\Repositories\Customer\CustomerRepository;
use Shop\Infrastructure\Repositories\CustomerGroup\CustomerGroupCriteria;
use Shop\Infrastructure\Repositories\CustomerGroup\CustomerGroupRepository;
use Shop\Infrastructure\Repositories\Manager\ManagerCriteria;
use Shop\Infrastructure\Repositories\Manager\ManagerRepository;
use Shop\Infrastructure\Repositories\Region\RegionRepository;
use Shop\Infrastructure\Repositories\Stock\StockCriteria;
use Shop\Infrastructure\Repositories\Stock\StockRepository;
use Shop\Application\Bonus\BonusService;


/**
 * Description of AdminClients
 *
 * @author Diamond Code Generator
 */
class AdminClients extends ModuleController
{

    use FormatColumnsTrait;
    use FormTrait;

    public function __construct(
        protected CustomerRepository $customerRepo,
        protected TableFactory $tableFactory,
        protected NiftyControlBuilder $controlBuilder,
        protected CustomerGroupRepository $customerGroupRepository,
        protected StockRepository $stockRepository,
        protected CountryRepository $countryRepository,
        protected RegionRepository $regionRepository,
        protected CityRepository $cityRepository,
        protected ManagerRepository $managerRepository,
        protected Main $mainConfig,
        protected BonusService $bonusUseCase,
        protected OfficeService $officeService,
        protected FormBuilder $formBuilder,
        protected NotificationService $notificationUseCase
    )
    {
    }

    /**
     * @param CustomerGroupCollection $customerGroups
     * @param CustomerGroupCollection $customerGroupsCollection
     * @return CustomerCriteria
     */
    protected function prepareCustomerCriteria(CustomerGroupCollection $customerGroups, CustomerGroupCollection $customerGroupsCollection): CustomerCriteria
    {
        $filterGroupIds = [];
        foreach ($customerGroupsCollection as $group) {

            if (in_array($group->getId(), [
                $this->mainConfig->getDefaultContractorGroup(),
                $this->mainConfig->getDefaultGuestGroup()
            ], true)) {

                $customerGroups->offsetUnset($group);
                continue;
            }
            $filterGroupIds[] = $group->getId();
        }
        return CustomerCriteria::create()->setFilterByGroupIds($filterGroupIds);
    }

    /**
     * @param DataTableEngine $table
     * @throws \ReflectionException
     * @throws \Twig\Error\LoaderError
     * @throws \Twig\Error\RuntimeError
     * @throws \Twig\Error\SyntaxError
     */
    protected function prepareActions(DataTableEngine $table): void
    {
        $managers = $this->managerRepository->findByCriteria(
            ManagerCriteria::create()->setFilterByActiveStock(true)
        );

        $table->addRowActionCommand(
            'move-clients-selected',
            new ChangeManagerCommand($table, $this->buildChangeManagerForm($managers)),
            'Сменить менеджера'
        );

        $table
            ->addRowActionCommand(
                'change-password', new ChangePasswordCommand(
                    $table,
                    $this->buildChangePasswordForm(),
                    $this->notificationUseCase
                ),
                'Сменить пароль'
            );

    }


    /**
     * @return Simpleform
     */
    protected function buildChangePasswordForm(): Simpleform
    {

        $form = $this->formBuilder->buildSimpleValidationForm('change-password');
        $form->setClass('niffy-admin-form panel-body form-horizontal form-padding');
        $form
            ->addField(
                $this->controlBuilder->buildInputPassword('password')->setClass('form-control'), 'Новый пароль'
            )
            ->addField(
                $this->controlBuilder->buildNiftySimpleSwitchery('notify_and_generate', 'Y','N'), 'Создать автоматически', '', 'Создать из случайной комбинации цифр и букв'
            )
            ->addField(
                $this->controlBuilder->buildNiftySimpleSwitchery('notify', 'Y','N'), 'Уведомить', '', 'Отправить уведомление с новым паролем'
            )
            ->addField(
                $this->controlBuilder->buildHidden('ids', input_post('ids'))
            )
            ->addField(
                $this->controlBuilder->buildHidden('actiontype', input_post('actiontype'))
            )
            ->addControl($this->controlBuilder->buildSubmitButton(
                'submit_change_password',
                'Сменить'
            )->setClass('btn btn-success'))
            ->addControl($this->controlBuilder->buildCancel('cancel',
                'Отмена'
            )->setClass('btn btn-dark'));

        return $form;
    }

    /**
     * @param ManagerCollection $managers
     * @return Simpleform
     * @throws \ReflectionException
     * @throws \Twig\Error\LoaderError
     * @throws \Twig\Error\RuntimeError
     * @throws \Twig\Error\SyntaxError
     */
    protected function buildChangeManagerForm(ManagerCollection $managers): Simpleform
    {
        $form = $this->formBuilder->buildSimpleValidationForm('move-manager');
        $form->setClass('panel-body form-horizontal form-padding');
        $form
            ->addField(
                $this->controlBuilder->buildAutoDropdown('new_manager', $managers->getDropdownListWithShop()),
                'Новый менеджер',
                ['required']
            )
            ->addField(
                $this->controlBuilder->buildHidden('ids', input_post('ids'))
            )
            ->addField(
                $this->controlBuilder->buildHidden('actiontype', input_post('actiontype'))
            )
            ->addControl(
                $this->controlBuilder->buildSubmitButton('submit_change_manager', 'Применить')->setClass('btn btn-success')
            );

        return $form;
    }

    /**
     * @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
    {

        $customerGroupsCollection = $this->customerGroupRepository->findByCriteria(
            CustomerGroupCriteria::create()
        );


        $customerGroups = clone $customerGroupsCollection;

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

        $criteria = $this->prepareCustomerCriteria($customerGroups, $customerGroupsCollection);

        $table
            = $this->tableFactory->buildAdminTable(
            $this->customerRepo,
            $criteria
        )
            ->setDefaultSortColumn('id', 'DESC');

        $this->prepareActions($table);


        $this->prepareColumns($table);

        $table
            ->addFilter(
                $this
                    ->controlBuilder
                    ->buildDropdownUniform('filter_by_groupId', Form::prepareDropdown($customerGroups, 'группу'))
            )
            ->addFilter(
                $this
                    ->controlBuilder
                    ->buildDropdownUniform('filter_by_stockId', Form::prepareDropdown($stocks, 'торг.точку'))
            )
            ->addFilter(
                $this
                    ->controlBuilder
                    ->buildInput('search_by_email')
            )
            ->addFilter(
                $this
                    ->controlBuilder
                    ->buildInput('search_by_name')
            );


        $this->makeForm($table, $customerGroups);


        return $table->render();
    }


    /**
     * @param DataTableEngine $table
     */
    protected function prepareColumns(DataTableEngine $table): void
    {
        $table
            ->addColumn(
                (new ColumnTable('id', '№'))
                    ->setSorted(true)
                    ->setWidth(40)
            )
            ->addColumn(
                (new ColumnTable('name', 'ФИО'))->setWidth(15, true)
            )
            ->addColumn(
                (new ColumnTable('orders', 'Заказов'))
                    ->setFormat($this, 'formatOrders')
            )
            ->addColumn(
                (new ColumnTable('email', 'E-mail/Логин'))
                    ->setSorted(true)
            )
            ->addColumn(
                (new ColumnTable('phone', 'Телефон'))->setWidth(10, true)
            )
            ->addColumn(
                (new ColumnTable('registred', 'Зарегистрирован'))
                    ->setFormat($this, 'formatcDate')
            )
//            ->addColumn(
//                (new ColumnTable("notifyType", "Уведомления"))
//                    ->setFormat($this,'formatSmsNotify')
//                    ->setWidth(10,true)
//            )
            ->addColumn(
                (new ColumnTable('groupId', 'Группа'))
                    ->setFormat($this, 'formatGroup')
            )
            ->addColumn(
                (new ColumnTable('address', 'Город'))
                    ->setFormat($this, 'formatAddress')
            )
            ->addColumn(
                (new ColumnTable('managerId', 'Менеджер'))
                    ->setFormat($this, 'formatManager')
            )
            ->addColumn(
                (new ColumnTable('stockId', 'Офис'))
                    ->setFormat($this, 'formatOffice')
            )
            ->addColumn(
                (new ColumnTable('access', 'Доступ'))
                    ->setFormat($this, 'formatAccess')
            )
            ->addColumn(
                (new ColumnTable('access', 'Заблокирован'))
                    ->setClass('text-center')
                    ->setFormat($this, 'formatDelete')
            )
        ;


        if ($this->mainConfig->getOrderScoreSumm() > 0) {
            $table
                ->addColumn(
                    (new ColumnTable('score', 'Баллы'))
                        ->setFormat($this, 'formatScore')
                );
        }

        $table
            ->addColumn(
                (new ColumnTable('actions', ''))
                    ->setWidth(120)
                    ->setFormat($this, 'formatActions')
            );
    }


    public function formatActions(CustomerEntityInterface $customer, array $items = []): string
    {

        if(empty($items)){
            if ($customer->getPassword() !== null) {
                $title = 'Изменить пароль';
            } else {
                $title = 'Установить пароль';
            }

            $key = md5(strtolower($customer->getEmail()) .  getenv('ENCRYPTION_KEY') . $customer->getPassword());
            $items = [
                new MenuItemAction($customer->getId(),'change-password',$title,$title. '?','fa fa-key'),
                new MenuItem('/?k=' . $key,'Авторизоваться','fa fa-lock'),
            ];
        }

        //change-password
        return $this->controlBuilder->buildActionMenuAdmin($items, $customer->getId())->render();
    }

}