<?php

namespace Shop\Presentation\Modules\AdminCategories;

use ActiveTable\ColumnTable;
use ActiveTable\DataTableEngine;
use Core\Concrete\RequestAwareTrait;
use Core\Contracts\RequestAwareInterface;
use Core\Form\ControlBuilder;
use Core\Helpers\Text;
use Core\ModuleController;
use Core\Template\Template;
use Diamond\Helpers\Form;
use DiamondTable\TableFactory;
use Shop\Domain\Catalog\Contracts\CatalogEntityInterface;
use Shop\Domain\ProductCategory\Contracts\ProductCategoryEntityInterface;
use Shop\Infrastructure\Models\Category\Category;
use Shop\Infrastructure\Models\Category\CategoryQuery;
use Shop\Infrastructure\Repositories\Catalog\CatalogCriteria;
use Shop\Infrastructure\Repositories\Catalog\CatalogRepository;
use Shop\Infrastructure\Repositories\Product\ProductCriteria;
use Shop\Infrastructure\Repositories\Product\ProductRepository;
use Shop\Infrastructure\Repositories\ProductCategory\ProductCategoryCriteria;
use Shop\Infrastructure\Repositories\ProductCategory\ProductCategoryRepository;

/**
 * Description of AdminCategories
 *
 * @author Dmitriy
 */
class AdminCategories extends ModuleController implements RequestAwareInterface
{

    public int|null $parentId = null;

    use RequestAwareTrait;

    public function __construct(protected ProductCategoryRepository $productCategoryRepository,
                                protected ProductRepository $productRepository,
                                protected CatalogRepository $catalogRepository,
                                protected TableFactory $tableFactory,
                                protected Template $template,
                                protected ControlBuilder $controlBuilder)
    {

    }



    public function process(): string
    {

        $this->template->addStyleLink('/_diamond/diamond-cms/assets/nifty/plugins/fooTable/css/footable.core.css');
        $this->template->addScript($this->render('javascript'));

        $list = $this->productCategoryRepository->findByCriteria(
            ProductCategoryCriteria::create()
        );
        $listCatalog = $this->catalogRepository->findByCriteria(
            CatalogCriteria::create()
        );

        $catalogAr = Form::prepareDropdown($listCatalog);
        $listAr = Form::prepareDropdownWithDef($list, 'NULL', 'без родительского', 'getDropdownListWithParent');

        if (input_get('id') > 0) {
            unset($listAr[input_get('id')]);
        }

        $criteria =  ProductCategoryCriteria::create();

        if(!input_get('id') && !input_post('actiontype')){
            if($this->parentId){
                $criteria->setFilterByParentIds([$this->parentId]);
            }
            else{
                $criteria->setFilterByParentIdIsNull(true);
            }
        }

        $table = $this->tableFactory->buildAdminTable($this->productCategoryRepository,
           $criteria
                //->setAsTreeView(true)
                );

        $table
            ->removeControlAccess(DataTableEngine::CONTROL_ROWS_SELECT)
            ->setClass('nifty-table dataTable  table table-striped footable breakpoint toggle-circle');


        $this->prepareColumns($table);
//            ->addRowActionCommand(
//                'change-catalog',
//                new ChangeCatalogCommand($table, $this->buildMoveBrandForm($catalogAr)),
//                'Сменить каталог'
//            );

        $table
            ->addField(
                $this->controlBuilder
                    ->buildInput('title'), true
            )
            ->addField(
                $this->controlBuilder
                    ->buildInput('alias'), true, 'Псевдоним на латинице', 'для использования в ЧПУ'
            )

            ->addField(
                $this->controlBuilder
                    ->buildDropdownUniform('catalogId', $catalogAr)
                    ->setValue($this->request->query->get('catalog_id') ?? 'NULL')
                , true, 'Каталог'
            )
            ->addField(
                $this->controlBuilder
                    ->buildTextEditor('desc')
                    ->setHeight(200)
                    ->setCompact(true)
            );

        $table
            ->addFilter(
                $this->controlBuilder->buildInput('search_by_title')
            );


//        $this->buildForm($table, $catalogAr);

        return $table->render();
    }

    /**
     * @param ProductCategoryEntityInterface $categoryEntity
     * @return string
     * @throws \Propel\Runtime\Exception\PropelException
     */
    public function formatParent(ProductCategoryEntityInterface $categoryEntity): string
    {
        if (!$categoryEntity->getParentCategory()) {
            return '';
        }
        return $categoryEntity->getParentCategory()->getTitle();
    }

    /**
     * @param ProductCategoryEntityInterface $categoryEntity
     * @return string
     */
    public function formatDesc(ProductCategoryEntityInterface $categoryEntity): string
    {
        if (!$text = $categoryEntity->getDesc()) {
            return '';
        }
        $txt = Text::clearText($text,30);
        return $txt!==''?$txt.'...':'';
    }


    protected function prepareColumns(DataTableEngine $table): void
    {
        $table
            ->addColumn(
                (new ColumnTable('title', 'Наименование'))
                    ->setFormat($this, 'formatTitle')
            )
            ->addColumn(
                (new ColumnTable('parent', 'Родитель'))
                    ->setFormat($this, 'formatParent')
            )
            ->addColumn(
                (new ColumnTable('alias', 'Псевдоним'))
            )
            ->addColumn(
                (new ColumnTable('products', 'Товаров'))
                    ->setFormat($this, 'formatProducts')
                    ->setWidth(10, true)
            )
            ->addColumn(
                (new ColumnTable('image', 'Изображение'))
            )
            ->addColumn(
                (new ColumnTable('desc', 'Описание'))
                    ->setFormat($this, 'formatDesc')
            )
            ->addColumn(
                (new ColumnTable('catalog', 'Каталог'))
                    ->setFormat($this, 'formatCatalog')
            )
            ->addColumn(
                (new ColumnTable('actions', ''))
                    ->setFormat($this, 'formatActions')
                    ->setWidth(140)
            );
    }

    /**
     * @param ProductCategoryEntityInterface $categoryEntity
     * @return string
     */
    public function formatProducts(ProductCategoryEntityInterface $categoryEntity): string
    {
        $count = $this->productRepository->count(
            ProductCriteria::create()->setFilterByCategoryId($categoryEntity->getId())
        );

        return (string)$count;
    }

    /**
     * @param ProductCategoryEntityInterface $categoryEntity
     * @return string
     */
    public function formatActions(ProductCategoryEntityInterface $categoryEntity): string
    {
        $id = $categoryEntity->getId();

        return $this->controlBuilder->buildActionMenuAdmin([
            anchor(
                adaptive_url([
                    'fn' => 'add',
                    'parent_id' => $id
                ]),
                Form::buildIconText('pencil_white', 'Добавить подраздел')),

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

    /**
     * @param ProductCategoryEntityInterface|Category $categoryEntity
     * @return string
     */
    public function formatTitle(ProductCategoryEntityInterface $categoryEntity): string
    {

        $title = $categoryEntity->getTitle();

        $step = 16;

        $margin = $categoryEntity->getParentId() ? $step : 0;

        $class = '';

        if ($categoryEntity->getParentCategory()) {
            $class .= 'parent-' . $categoryEntity->getParentCategory()->getId();

            if ($categoryEntity->getParentCategory()->getParentCategory()) {
                $class .= ' parent-' . $categoryEntity->getParentCategory()->getParentId();
                $margin += $step;
            }

        }

        if ($categoryEntity->getVirtualColumn('child_exist') > 0) {
            $toggle = '<span class="footable-toggle ' . $class . '" style="position: absolute;margin-left:' . $margin . 'px" data-id="' . $categoryEntity->getId() . '"></span>';
        } else {
            $toggle = '<span class="' . $class . '" style="width: ' . ($step + $margin) . 'px;display: inline-block;position: absolute;"></span>';
        }

        $title = (nbs($categoryEntity->getParentsLevel()*7) .
            ($categoryEntity->getCountChildrens() > 0 ? '<i class="fa fa-folder"></i> ':'') .
            $title);

        return
            $toggle . $this->formatNamePart($title, $step, $margin);
    }

    private function formatNamePart(string $name, int $step, int $margin): string
    {
        $style = 'position: relative; margin-left: ' . ($step + $margin) . 'px';
        return '<div style="' . $style . '">' . $name . '</div>';
    }

    /**
     * @param ProductCategoryEntityInterface $product
     * @return string
     */
    public function formatCatalog(ProductCategoryEntityInterface $category): string
    {
        return is_object($category->getCatalog()) ? $category->getCatalog()->getName() : '';
    }

}