<?php

namespace Shop\Modules\AdminShops;

use ActiveTable\ColumnTable;
use ActiveTable\DataTableEngine;
use Core\Form\ControlBuilder;
use Diamond\Helpers\Form;
use Diamond\Repositories\Site\SiteCriteria;
use Diamond\Repositories\Site\SiteRepository;
use DiamondTable\CommandFactory;
use DiamondTable\TableFactory;
use Shop\Application\Office\Exceptions\MainStockNotFoundException;
use Shop\Application\Office\Exceptions\MainStockSomeFoundException;
use Shop\Config\Main;
use Shop\Domain\Stock\Contracts\StockEntityInterface;
use Shop\Models\Shop\Shop;
use Shop\Modules\AdminProviders\ContractorFormTrait;
use Shop\Repositories\City\CityRepository;
use Shop\Repositories\Country\CountryRepository;
use Shop\Repositories\Customer\CustomerRepository;
use Shop\Repositories\Manager\ManagerRepository;
use Shop\Repositories\PriceAccess\PriceAccessCriteria;
use Shop\Repositories\PriceAccess\PriceAccessRepository;
use Shop\Repositories\PriceList\PriceListCriteria;
use Shop\Repositories\PriceList\PriceListRepository;
use Shop\Repositories\Region\RegionRepository;
use Shop\Repositories\Stock\StockCriteria;
use Shop\Repositories\Stock\StockRepository;
use Shop\UseCases\Imaging\Imaging;
use Shop\Application\Office\OfficeService;

/**
 * Description of AdminShops
 * @todo передаелать на деревягу jqgrid
 * @author Diamond Code Generator
 */
class AdminShops extends \Core\ModuleController #implements \Shop\Contracts\ShopCurrentInterface
{
    use ColumnFormatTrait;
    use ContractorFormTrait;

    protected $stockRepository;
    protected $tableFactory;
    protected $managerRepository;
    protected $countryRepository;
    protected $cityRepository;
    protected $regionRepository;
    protected $customerRepository;
    protected $imagingUseCase;
    protected $priceListRepository;
    protected $siteRepository;
    protected $priceAccessRepository;
    protected $officeService;

    /**
     * AdminShops constructor.
     * @param StockRepository $stockRepository
     * @param Main $mainConf
     * @param TableFactory $tableFactory
     * @param ControlBuilder $controlBuilder
     * @param ManagerRepository $managerRepository
     * @param CountryRepository $countryRepository
     * @param CityRepository $cityRepository
     * @param RegionRepository $regionRepository
     * @param CustomerRepository $customerRepository
     * @param Imaging $imagingUseCase
     * @param PriceListRepository $priceListRepository
     * @param SiteRepository $siteRepository
     * @param PriceAccessRepository $priceAccessRepository
     * @param OfficeService $officeService
     */
    public function __construct(StockRepository $stockRepository,
                                Main $mainConf,
                                TableFactory $tableFactory,
                                ControlBuilder $controlBuilder,
                                ManagerRepository $managerRepository,
                                CountryRepository $countryRepository,
                                CityRepository $cityRepository,
                                RegionRepository $regionRepository,
                                CustomerRepository $customerRepository,
                                Imaging $imagingUseCase,
                                PriceListRepository $priceListRepository,
                                SiteRepository $siteRepository,
                                PriceAccessRepository $priceAccessRepository,
                                OfficeService $officeService)
    {
        $this->stockRepository = $stockRepository;
        $this->tableFactory = $tableFactory;
        $this->controlBuilder = $controlBuilder;
        $this->mainConf = $mainConf;

        $this->managerRepository = $managerRepository;
        $this->countryRepository = $countryRepository;
        $this->cityRepository = $cityRepository;
        $this->regionRepository = $regionRepository;
        $this->customerRepository = $customerRepository;
        $this->imagingUseCase = $imagingUseCase;
        $this->priceListRepository = $priceListRepository;
        $this->siteRepository = $siteRepository;
        $this->priceAccessRepository = $priceAccessRepository;
        $this->officeService = $officeService;
    }


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

        if (!is_dir($this->officeService->getStockImageDir())) {
            return Form::buildAnnouncementMessage(
                'Путь к изображениям торговых точек не настроен. ' . anchor('/admin/shop/stocks/settings', 'Настроить'));
        }

        try{
            $mainStock = $this->officeService->getMainStock();
        }
        catch (MainStockNotFoundException $ex){
            Form::addTableNotice(
                Form::buildAnnouncementMessage(
                    'Не указан головной офис, сайт может работать не корректно!'
                )
            );
        }
        catch (MainStockSomeFoundException $ex){
            Form::addTableNotice(
                Form::buildAnnouncementMessage(
                    'Указано несколько головных офисов, сайт может работать не корректно!'
                )
            );
        }

        $table = $this->tableFactory->buildAdminTable($this->stockRepository,
            StockCriteria::create()->setTreeView(true)->setLimit(1000)
        );


        $table
            ->removeControlAccess(DataTableEngine::CONTROL_ROWS_SELECT)
            ->getCommandFactory()
            ->addCommand(CommandFactory::FORM_SAVE,
                new SaveStockCommand($table, $this->priceAccessRepository)
            );

        $table
            ->addRowActionCommand(
                'disable-stocks-selected',
                new DisableStocksCommand($this->stockRepository),
                'Деактивировать'
            );

        $table
            ->addRowActionCommand(
                'active-stocks-selected',
                new ActiveStocksCommand($this->stockRepository),
                'Активировать'
            );


        
        $table
            ->addColumn(
                (new ColumnTable('id', '№'))
                    ->setWidth(40)
            )
            ->addColumn(
                (new ColumnTable('title', 'Название'))
                    ->setFormat($this, 'formatName')
                    ->setWidth(300)

            )
            ->addColumn(
                (new ColumnTable('type', 'Тип'))
                    ->setFormat($this, 'formatType')
                    ->setWidth(100)

            )
//            ->addColumn(
//                (new ColumnTable('phones', 'Контактные телефоны'))
//                    ->setFormat($this, 'formatContact')
//
//            )
//            ->addColumn(
//                (new ColumnTable('address', 'Адрес расположения'))
//                    ->setFormat($this, 'formatAddress')
//                    ->setWidth(15, true)
//            )
            ->addColumn(
                (new ColumnTable('priceAccess', 'Доступные прайсы'))
                    ->setFormat($this, 'formatPriceAccess')
                    ->setWidth(100)

            )
            ->addColumn(
                (new ColumnTable('managersCount', 'Менеджеры'))
                    ->setFormat($this, 'formatManagersCount')

            )
            ->addColumn(
                (new ColumnTable('contractorId', 'Контрагент'))
                    ->setFormat($this, 'formatContractor')

            )
            ->addColumn(
                (new ColumnTable('active', 'Активна'))
                    ->setFormat($this, 'formatActive')

            )
            ->addColumn(
                (new ColumnTable('images', 'Фото'))
                    ->setFormat($this, 'formatImages')
            )
            ->addColumn(
                (new ColumnTable('geo', 'Гео'))
                    ->setFormat($this, 'formatGeo')
            )
            ->addColumn(
                (new ColumnTable('actions', ''))
                    ->setFormat($this, 'formatActions')
                    ->setWidth(120)
            );

        $stocks = $this->stockRepository->findByCriteria(
            StockCriteria::create()
                ->setSortByTitle('asc')
                ->setFilterByTypes(['dealer', 'main'])
        );

        $imgUpload = $this->controlBuilder
            ->buildImgUpload('image', $this->officeService->getStockImageDir(), true)
            ->setMaxHeight(1000)
            ->setMaxWidth(1000)
            ->setPreviewImage(true)
            ->setPreviewImageSize(100);

        $imgUploadLogo = $this->controlBuilder
            ->buildImgUpload('logo', $this->officeService->getStockImageDir(), true)
            ->setMaxHeight(300)
            ->setMaxWidth(300)
            ->setPreviewImage(true)
            ->setPreviewImageSize(100);

        $prices = $this->priceListRepository->findByCriteria(
            PriceListCriteria::create()
        );
        $accessPricesIds = [];
        if (input_get('id') > 0) {
            $accessCollection = $this->priceAccessRepository->findByCriteria(
                PriceAccessCriteria::create()->setFilterByShopId(input_get('id'))
            );

            foreach ($accessCollection as $access) {
                $accessPricesIds[] = $access->getPriceScheetId();
            }
        }

        $table
            ->addField(
                $this->controlBuilder->buildFormHeader('Основная информация о торговой точке', 'mainData')
            )
            ->addField(
                $this->controlBuilder->buildInput('title'), true
            )
            ->addField(
                $this->controlBuilder
                    ->buildDropdownUniform('type',
                        [
                            'stock' => Shop::MSG_SHOP_STOCK,
                            'main' => Shop::MSG_SHOP_MAIN,
                            'dealer' => Shop::MSG_SHOP_DEALER
                        ]
                    ), true,
                'Тип торговой точки'
            )
            ->addField(
                $this->controlBuilder->buildDropdownUniform('parentId',
                    Form::prepareDropdown($stocks)),
                false,
                'Принадлежность', 'как правило к головному офису'
            )
            ->addField(
                $this->controlBuilder->buildTextArea('directorContact'), false, 'Контакты директора/компании', 'будет использоваться в документах'
            )
            ->addField(
                $this->controlBuilder->buildTextArea('phones'), false, 'Контактные телефоны', 'будет использоваться в документах'
            )
            ->addField(
                $this->controlBuilder->buildTextArea('emails'), false, 'Электронные адреса для писем', 'будет использоваться в документах'
            );

        $this->tableFactory->prepareAdminTableForDomain($table);

        $this->makeContractorForm($table, $this->stockRepository);


        $table
            ->addField(
                $this->controlBuilder->buildInputSmall('postCode'), false, 'Почтовый индекс'
            )
            ->addField(
                $this->controlBuilder->buildInput('street'), false, 'Улица'
            )
            ->addField(
                $this->controlBuilder->buildInputSmall('house'), false, 'Дом'
            )
            ->addField(
                $this->controlBuilder->buildInputSmall('room'), false, 'Квартира/Офис'
            )
            ->addField(
                $this->controlBuilder->buildInputSmall('mapLng'), false, 'Координата по долготе', 'Для карт google,yandex'
            )
            ->addField(
                $this->controlBuilder->buildInputSmall('mapLat'), false, 'Координата по широте', 'Для карт google,yandex'
            )
            ->addField(
                $this->controlBuilder->buildFormHeader('Изображения и описание', 'images')
            )
            ->addField(
                $imgUploadLogo, false, 'Логотип офиса', 'будет использоваться в документах'

            )
            ->addField(
                $imgUpload, false, 'Фото офиса', 'для страницы контактов'

            )
            ->addField(
                $this
                    ->controlBuilder
                    ->buildTextEditor('desc')
                    ->setHeight(200)
                    ->setCompact(true),
                false,
                'Прочее','Режим работы, описание и тд'
            )
            ->addField(
                $this->controlBuilder
                    ->buildAutoDropdownMulti('accessPrices', Form::prepareDropdown($prices))
                    ->setValue($accessPricesIds)
                , false,
                'Доступные прайс-листы'
            )
            ->addField(
                $this->controlBuilder->buildDropdownUniform('active', [
                    'Y' => 'Да',
                    'N' => 'Нет']), true, 'Активна'
            );

        $domains = $this->siteRepository->findByCriteria(SiteCriteria::create()->setSortByHost('ASC'));

        $table
            ->addFilter(
                $this->controlBuilder->buildDropdownUniform(
                    'filter_by_siteid', Form::prepareDropdown($domains))
            )
            ->addFilter(
                $this->controlBuilder->buildInput(
                    'search_by_title'
                )
            )
            ->addFilter(
                $this->controlBuilder->buildDropdownYNUniform('filter_by_active', [
                    null => '-все-'
                ])
            );

        $file = $imgUpload->UploadImage();
        /**
         * @todo убрать костыль
         */
        if ($file) {
            Form::addTableNotice(Form::buildSuccessMessage(sprintf('Изображение офиса %s успешно сохранено', $file)));
        } elseif ($imgUpload->deleteImage()) {
            Form::addTableNotice(Form::buildSuccessMessage('Изображение офиса успешно удалено'));
        }

        //---------------------------------------------------
        $file = $imgUploadLogo->UploadImage();
        if ($file) {
            Form::addTableNotice(Form::buildSuccessMessage(sprintf('Логотип %s успешно сохранен', $file)));
        } elseif ($imgUploadLogo->deleteImage()) {
            Form::addTableNotice(Form::buildSuccessMessage('Логотип успешно удален'));
        }

        return $table->render();
    }


    public function formatActions(StockEntityInterface $stock): string
    {
        $id = $stock->getId();

        return $this->controlBuilder->buildActionMenuAdmin([
            anchor(
                '/admin/shop/stocks/managers',
                Form::buildSpriteIcon('man', 'Добавить менеджера', 'white'),[],
                [
                    'fn' => 'add',
                    'shopId' => $id
                ]),

        ], $id)->render();
    }


}