<?php

namespace Diamond\Modules\AdminContents;

use ActiveTable\ColumnTable;
use ActiveTable\DataTableEngine;
use Core\AdminModuleController;
use Core\Form\Control\MenuItem;
use Core\Form\NiftyControlBuilder;
use Core\Helpers\Text;
use Diamond\Domain\Content\Contracts\ContentEntityInterface;
use Diamond\Domain\ContentCategory\ContentCategoryCollection;
use Diamond\Helpers\Date;
use Diamond\Helpers\Form;
use Diamond\Helpers\Formatter;
use Diamond\Infrastructure\Models\ContentTagRel\Base\ContentTagRelQuery;
use Diamond\Repositories\Content;
use Diamond\Repositories\ContentCategory;
use Diamond\Repositories\ContentTag\ContentTagCriteria;
use Diamond\Repositories\ContentTag\ContentTagRepository;
use DiamondTable\CommandFactory;
use DiamondTable\TableFactory;
use Repo\EntityInterface;


/**
 * Description of AdminContents
 *
 * @author Admin
 */
class AdminContents extends AdminModuleController
{


    public function __construct(private Content\ContentRepository                 $repo,
                                private ContentCategory\ContentCategoryRepository $categoryRepo,
                                private TableFactory                              $tableFactory,
                                private ContentTagRepository                      $contentTagRepository,
                                protected NiftyControlBuilder                            $controlBuilder)
    {
    }


    public function process(): string
    {
        $table = $this->tableFactory->buildAdminTable($this->repo, Content\ContentCriteria::create());
        
        $table
            ->getCommandFactory()
            ->addCommand(CommandFactory::FORM_SAVE,
                new SaveContentCommand($table)
            );

        $categories = $this->categoryRepo->findByCriteria(ContentCategory\ContentCategoryCriteria::create());

        $tags = $this->contentTagRepository->findByCriteria(
            ContentTagCriteria::create()
        );

        $table
            ->setDefaultSortColumn('id','desc')
            ->addColumn(
                (new ColumnTable('id', '№'))->setWidth(40)
            )
            ->addColumn(
                (new ColumnTable('datecreate', 'Дата создания'))
                    ->setFormat($this, 'formatDateCreate')
            )
            ->addColumn(
                (new ColumnTable('datecreate', 'Дата изменения'))
                    ->setFormat($this, 'formatDateUpdate')
            )
            ->addColumn(
                (new ColumnTable('date', 'Дата публикации'))
                    ->setFormat($this, 'formatDate')
            )
            ->addColumn(
                (new ColumnTable('title', 'Заголовок'))
            )
            ->addColumn(
                (new ColumnTable('preview', 'Краткий текст'))
                    ->setFormat($this, 'formatPreview')
            )
            ->addColumn(
                (new ColumnTable('body', 'Полный текст'))
                    ->setFormat($this, 'formatBody')
            )
            ->addColumn(
                (new ColumnTable('categoryId', 'Раздел'))
                    ->setFormat($this, 'formatCategory')
            )
            ->addColumn(
                (new ColumnTable('tags', 'Теги'))
                    ->setFormat($this, 'formatTags')
            )
            ->addColumn(
                (new ColumnTable('active', 'Опубл.'))
                    ->setFormat($this, 'formatActive')
            )
            ->addColumn(
                (new ColumnTable('actions', ''))
                    ->setFormat($this, 'formatActions')
                    ->setWidth(120)
            );

        $tagsIds = [];
        if (input_get('id') > 0) {
            /**
             * @var \Diamond\Infrastructure\Models\Content\Content $content
             */
            $contents = ContentTagRelQuery::create()->findByContentId(input_get('id'));
            $tagsIds = $contents->getColumnValues('ContentTagId');
        }

        $table
            ->addField(
                $this->controlBuilder->buildInput('title'), true
            )
            ->addField(
                $this->controlBuilder->buildDatePicker('date')->setValue(\date('d.m.Y'))->setFn($this,'formatDate'), true
            )
            ->addField(
                $this
                    ->controlBuilder
                    ->buildNiftyMultiSelect('tags', Form::prepareDropdown($tags))->setValue($tagsIds), false, 'Теги'
            )
            ->addField(
                $this->controlBuilder->buildDropdownUniform('categoryId', Form::prepareDropdown($categories)), true
            )
            ->addField(
                $this
                    ->controlBuilder
                    ->buildDropdownYNUniform('active')->setValue('N'), true
            )
            ->addField(
                $this
                    ->controlBuilder
                    ->buildTextEditor('preview')
                    ->setMini(true)
                    ->setHeight(300)
                    ->setWidthPercent(100)
            )
            ->addField(
                $this
                    ->controlBuilder
                    ->buildTextEditor('body')
                    ->setMini(true)
                    ->setWidthPercent(100), true
            );

        $this->makeFilter($table, $categories);

        return $table->render();
    }


    protected function makeFilter(DataTableEngine $table, ContentCategoryCollection $categories): void
    {
        $table
            ->addFilter(
                $this
                    ->controlBuilder
                    ->buildInput('search_by_title')
            )
            ->addFilter(
                $this
                    ->controlBuilder
                    ->buildDropdownUniform('filter_by_categoryId', Form::prepareDropdown($categories))
            )
            ->addFilter(
                $this
                    ->controlBuilder
                    ->buildDropdownYNUniform('filter_by_active', [null => 'любой'])
            )
            ->addFilter(
                $this
                    ->controlBuilder
                    ->buildDatePicker('filter_by_datecreate')->setFormat('dd.mm.yy')
            );

    }


    public function formatTags(ContentEntityInterface $content): string
    {
        $tags = $content->getContentTagRels()->getColumnValues('ContentTagId') ?? [];
        $html = [];
        foreach ($tags as $tag) {
            $tagModel = $this->contentTagRepository->findById($tag);
            $html [] = '<span class="label label-default">' . $tagModel->getName() . '</span>';
        }
        return Text::toggleList($html);
    }


    public function formatCategory(ContentEntityInterface $content): string
    {
        return $content->getContentCategory()->getTitle();
    }


    public function formatBody(ContentEntityInterface $content): string
    {
        return Formatter::formatLongText($content->getBody());
    }


    public function formatPreview(ContentEntityInterface $content): string
    {
        return Formatter::formatLongText($content->getPreview());
    }


    public function formatActive(ContentEntityInterface $content): string
    {
        $data = [
            'class' => self::class,
            'id' => $content->getId(),
            'fn' => 'changeActive'
        ];
        return $this->controlBuilder->buildNiftySwitchery($data, $content->getActive() === 'Y')->render();
    }

    public function changeActive(int $id, bool $checked): void
    {
        $item = $this->repo->findById($id);
        $item->setActive($checked === true ? 'Y' : 'N');
        $this->repo->save($item);
    }

    public function formatDateCreate(ContentEntityInterface $content): string
    {
        return $content->getDatecreate("d.m.Y");
    }

    public function formatDateUpdate(ContentEntityInterface $content): string
    {
        return (string)$content->getDateUpdate("d.m.Y");
    }

    public function formatDate(ContentEntityInterface $content): string
    {
        return $content->getDate("d.m.Y");
    }

    public function formatActions(EntityInterface $entity, ?array $items = []): string
    {
        return parent::formatActions($entity, [
            new MenuItem(adaptive_url([
                'fn' => 'add',
                'id' => $entity->getId()
            ]), 'Скопировать','fa fa-copy')
        ]);
    }


}
