<?php

namespace Shop\Modules\AdminClients;

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


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

    use FormatColumnsTrait;
    use FormTrait;

    protected $customerRepo;
    protected $tableFactory;
    protected $customerGroupRepository;
    protected $stockRepository;
    protected $countryRepository;
    protected $regionRepository;
    protected $cityRepository;
    protected $bonusUseCase;
    protected $officeService;
    protected $formBuilder;
    protected $notificationUseCase;

    public function __construct(
        CustomerRepository $customerRepo,
        TableFactory $tableFactory,
        ControlBuilder $controlBuilder,
        CustomerGroupRepository $customerGroupRepository,
        StockRepository $stockRepository,
        CountryRepository $countryRepository,
        RegionRepository $regionRepository,
        CityRepository $cityRepository,
        ManagerRepository $managerRepository,
        Main $mainConfig,
        BonusService $bonusUseCase,
        OfficeService $officeService,
        FormBuilder $formBuilder,
        NotificationService $notificationUseCase
    )
    {
        $this->tableFactory = $tableFactory;
        $this->customerRepo = $customerRepo;
        $this->controlBuilder = $controlBuilder;
        $this->customerGroupRepository = $customerGroupRepository;
        $this->stockRepository = $stockRepository;
        $this->countryRepository = $countryRepository;
        $this->regionRepository = $regionRepository;
        $this->cityRepository = $cityRepository;
        $this->managerRepository = $managerRepository;
        $this->mainConfig = $mainConfig;
        $this->bonusUseCase = $bonusUseCase;
        $this->officeService = $officeService;
        $this->formBuilder = $formBuilder;
        $this->notificationUseCase = $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
            ->addField(
                $this->controlBuilder->buildInputPassword('password'), 'Новый пароль'
            )
            ->addField(
                $this->controlBuilder->buildCheckbox('notify_and_generate', 'Y'), 'Создать и уведомить', '', 'Создать случайный и отправить уведомление'
            )
            ->addField(
                $this->controlBuilder->buildCheckbox('notify', 'Y'), 'Уведомить', '', 'Отправить уведомление с новым паролем'
            )
            ->addField(
                $this->controlBuilder->buildHidden('ids', input_post('ids'))
            )
            ->addField(
                $this->controlBuilder->buildHidden('actiontype', input_post('actiontype'))
            )
            ->addControl($this->controlBuilder->buildSubmitButton(
                'submit_change_password',
                'Сменить'
            ))
            ->addControl($this->controlBuilder->buildCancel('cancel',
                'Отмена'
            ));

        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
            ->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', 'Применить')
            );

        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()
        );

        $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('stockId', 'Офис/Менеджер'))
                    ->setFormat($this, 'formatOffice')
            )
            ->addColumn(
                (new ColumnTable('access', 'Доступ'))
                    ->setFormat($this, 'formatAccess')
            );


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

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


}