<?php declare(strict_types=1);

namespace Diamond\Modules\AdminPages;

use ActiveTable\ColumnTable;
use Core\AdminModuleController;
use Core\Form\Control\MenuItem;
use Core\Form\Control\MenuItemDelete;
use Core\Form\Control\MenuItemEdit;
use Core\Form\NiftyControlBuilder;
use Diamond\Domain\Page\Contracts\PageEntityInterface;
use Diamond\Helpers\Form;
use Diamond\Helpers\Formatter;
use Diamond\Repositories\Page\PageCriteria;
use Diamond\Repositories\Page\PageRepository;
use Diamond\Repositories\Template;
use Diamond\Config\Main;
use DiamondTable\TableFactory;
use Repo\EntityInterface;


class AdminPages extends AdminModuleController
{


    public function __construct(private Main                        $mainConfig,
                                private Template\TemplateRepository $templateRepo,
                                private PageRepository              $pageRepo,
                                private TableFactory                $tableFactory,
                                private NiftyControlBuilder              $controlBuilder)
    {}


    public function process(): string
    {

        $table = $this->tableFactory->buildAdminTable($this->pageRepo, PageCriteria::create(), 'Создать страницу');

        $this->templates = $this->templateRepo->findByCriteria(Template\TemplateCriteria::create());

        if (!$this->templates->count()) {
            return Form::buildAnnouncementMessage('Редактирование страниц невозможно, необходимо создать шаблоны сайта');
        }

        $table
            ->setDefaultSortColumn('id','DESC')
            ->addColumn(
                (new ColumnTable('id', '№'))->setWidth(40)
            )
            ->addColumn(
                (new ColumnTable('code', 'Идентификатор'))
            )
            ->addColumn(
                (new ColumnTable('title', 'Заголовок страницы'))
            )
            ->addColumn(
                (new ColumnTable('url', 'Адрес страницы'))
                    ->setFormat($this, 'formatUrl')
            )
            ->addColumn(
                (new ColumnTable('script', 'Twig страница'))
            )
            ->addColumn(
                (new ColumnTable('template', 'Шаблон'))
                    ->setFormat($this, 'formatTemplate')
            )
            ->addColumn(
                (new ColumnTable('content', 'Содержимое страницы'))
                    ->setFormat($this, 'formatContent')
            )
            ->addColumn(
                (new ColumnTable('active', 'Актив.'))
                    ->setFormat($this, 'formatActive')
            )
            ->addColumn(
                (new ColumnTable('system', 'Систем.'))
                    ->setFormat($this, 'formatSystem')
            )
            ->addColumn(
                (new ColumnTable('actions', ''))
                    ->setFormat($this, 'formatActions')
                    ->setWidth(120)
            )
            ->addFilter(
                $this->controlBuilder->buildInput('search_by_code')
            )
            ->addFilter(
                $this->controlBuilder->buildInput('search_by_title')
            )
            ->addFilter(
                $this->controlBuilder->buildInput('search_by_url')
            )
            ->addFilter(
                $this->controlBuilder->buildInput('search_by_script')
            )
            ->addFilter(
                $this->controlBuilder->buildDropdownYNUniform('filter_by_active', [
                    null => 'любой'
                ])
            )
            ->addFilter(
                $this->controlBuilder->buildDropdownYNUniform('filter_by_system', [
                    null => 'любой'
                ])
            )
            ->addFilter(
                $this->controlBuilder->buildDropdownUniform('filter_by_template', Form::prepareDropdown($this->templates))
            );


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

        $table
            ->addField(
                $this->controlBuilder->buildInput('title'), false, null, 'будет использоваться в title'
            )
            ->addField(
                $this->controlBuilder->buildInput('code'), false, null, 'техническое имя'
            )
            ->addField(
                $this->controlBuilder->buildInput('url'), false, null,
                $this->mainConfig->getUrl_suffix() ?
                    'Суффикс ' . $this->mainConfig->getUrl_suffix() . ' будет атоматически добавлен' : 'начинается с /'
            )
            ->addField(
                $this->controlBuilder->buildInput('script'), false, null, 'twig шаблон из папки pages'
            )
            ->addField(
                $this->controlBuilder->buildDropdownUniform('template', array_merge([
                    null => 'без шаблона'
                ], $this->templates->getDropdownList()))
            )
            ->addField(
                $this->controlBuilder
                    ->buildTextEditor('content')
                    ->setMini(true)
                    ->setHeight(300)
                    ->setWidthPercent(100)

            )
            ->addField(
                $this->controlBuilder->buildNiftySimpleSwitchery('active','Y','N'), true
            )
            ->addField(
                $this->controlBuilder->buildNiftySimpleSwitchery('system','Y','N'), true
            )
            ->addField(
                $this->controlBuilder->buildInputSmall('seoRule'), false, 'ЧПУ правило', 'Например /page/.*'
            )
            ->addField(
                $this->controlBuilder->buildFormHeader(
                    'Мета теги', 'meta'
                )
            )
            ->addField(
                $this->controlBuilder->buildInput('mtTitle'), false, 'Заголовок'
            )
            ->addField(
                $this->controlBuilder->buildTextArea('mtDescription', 2), false, 'Описание'
            )
            ->addField(
                $this->controlBuilder->buildTextArea('mtKeywords', 2), false, 'Ключевые слова', 'через запятую'
            );

        return $table->render();
    }


    public function formatTemplate(PageEntityInterface $page): string
    {
        $ar = $this->templates->getDropdownList();
        return $ar[$page->getTemplate()] ?? $page->getTemplate();
    }


    public function formatActions(EntityInterface $page, ?array $items = []): string
    {
        $items = [
            new MenuItemEdit($page->getId())
        ];

        $items [] =
            new MenuItem(adaptive_url([
                'fn' => 'add',
                'id' => $page->getId()
            ]), 'Скопировать','fa fa-copy');

        if ($page->getSystem() === 'N') {
            $items [] = new MenuItemDelete($page->getId());
        }

        return $this->controlBuilder->buildActionMenu($items)->render();
    }

    public function formatUrl(PageEntityInterface $page): string
    {
        return !$page->getUrl() ? '' : anchor($page->getUrl(), $page->getUrl(), [
            'target' => '_blank',
            'title' => 'Открыть страницу в отдельной вкладке'
        ]);
    }

    public function formatContent(PageEntityInterface $page): string
    {
        return Formatter::formatLongText((string)$page->getContent());
    }


    public function formatSystem(PageEntityInterface $page): string
    {
        $data = [
            'class' => self::class,
            'id' => $page->getId(),
            'fn' => 'changeSystem'
        ];
        return $this->controlBuilder->buildNiftySwitchery($data, $page->getSystem() === 'Y')->render();
    }

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

    public function changeActive(int $id, bool $checked): void
    {
        $page = $this->pageRepo->findById($id);

        $page->setActive($checked === true ? 'Y' : 'N');
        $this->pageRepo->save($page);
    }


    public function changeSystem(int $id, bool $checked): void
    {
        $page = $this->pageRepo->findById($id);

        $page->setSystem($checked === true ? 'Y' : 'N');
        $this->pageRepo->save($page);
    }

}
