<?php

namespace Diamond\Modules\AdminBookItems;


use ActiveTable\ColumnTable;
use Core\Concrete\RequestAwareTrait;
use Core\Contracts\RequestAwareInterface;
use Core\Form\Control\Switchery;
use Core\Form\NiftyControlBuilder;
use Core\Helpers\Date;
use Core\ModuleController;
use Diamond\Application\GuestBook\GuestBookService;
use Diamond\Domain\GuestBookItem\Contracts\GuestBookItemEntityInterface;
use Diamond\Helpers\Form;
use Core\Helpers\Text;
use Diamond\Infrastructure\Models\GuestBookItem\GuestBookItem;
use Diamond\Repositories\GuestBook\GuestBookCriteria;
use Diamond\Repositories\GuestBookItem\GuestBookItemCriteria;
use DiamondTable\TableFactory;

/**
 * Description of AdminBookIems
 *
 * @author Diamond Code Generator
 */
class AdminBookItems extends ModuleController implements RequestAwareInterface
{

    use RequestAwareTrait;

    public function __construct(private GuestBookService $guestBookService,
                                private TableFactory $tableFactory,
                                private NiftyControlBuilder $controlBuilder)
    {}


    public function process(): string
    {

        $books = $this->guestBookService->getBookRepository()->findByCriteria(GuestBookCriteria::create());

        $table = $this->tableFactory->buildAdminTable($this->guestBookService->getGuestBookItemRepository(), GuestBookItemCriteria::create());

        $table
            ->setDefaultSortColumn('id','DESC')
            ->addColumn(
                (new ColumnTable('id', '№'))->setWidth(40)
            )
            ->addColumn(
                (new ColumnTable('date', 'Дата/Время'))->setFormat($this, 'formatDate')
            )
            ->addColumn(
                (new ColumnTable('ip', 'Ip адрес'))
            )
            ->addColumn(
                (new ColumnTable('username', 'Имя пользователя'))
            )
            ->addColumn(
                (new ColumnTable('useremail', 'Email пользователя'))
            )
            ->addColumn(
                (new ColumnTable('text', 'Отзыв'))->setFormat($this, 'formatDesc')
            )
            ->addColumn(
                (new ColumnTable('published', 'Опубликованно'))->setFormat($this, 'formatPublished')
            )
            ->addColumn(
                (new ColumnTable('bookId', 'Книга'))->setFormat($this, 'formatBook')
            )
            ->addColumn(
                (new ColumnTable('rank', 'Оценка'))
            )
            ->addColumn(
                (new ColumnTable('objectId', 'Объект отзыва'))
            )
            ->addColumn(
                (new ColumnTable('actions', ''))
                    ->setFormat($this->tableFactory, 'formatActions')
                    ->setWidth(120)
            );

        if ($this->request->query->get('id') > 0) {
            $table
                ->addField(
                    $this->controlBuilder->buildTextLabel('date')
                        ->setFn($this, 'formatDate')
                )
                ->addField(
                    $this->controlBuilder->buildTextLabel('ip')
                )
                ->addField(
                    $this->controlBuilder->buildTextLabel('objectId')->setFn($this, 'formatObject')
                );
        } else {
            $table->addField(
                $this->controlBuilder->buildHidden('ip')->setValue($this->request->getClientIp())
            );
        }

        $table
            ->addField(
                $this->controlBuilder->buildInput('username'), true
            )
            ->addField(
                $this->controlBuilder->buildInput('useremail')
            )

            ->addField(
                $this->controlBuilder->buildDropdownRankUniform('rank', 1, 5)
            )
            ->addField(
                $this->controlBuilder->buildDropdownUniform('bookId', Form::prepareDropdown($books))
            )
            ->addField(
                $this->controlBuilder->buildTextArea('text', 18), true, 'Содержимое отзыва'
            )
            ->addField(
                $this->controlBuilder->buildNiftySimpleSwitchery('published','Y','N')
            );

        $table
            ->addFilter(
                $this->controlBuilder->buildDatePicker('filter_by_date')//buildDatePicker  ->setFormat('dd.mm.yy')
            )
            ->addFilter(
                $this->controlBuilder->buildInput('search_by_username')
            )
            ->addFilter(
                $this->controlBuilder->buildInput('search_by_useremail')
            )
            ->addFilter(
                $this->controlBuilder->buildDropdownUniform('filter_by_bookId', Form::prepareDropdown($books))
            )
            ->addFilter(
                $this->controlBuilder->buildDropdownRankUniform('filter_by_rank', 1, 5, [null => 'любой'])
            )
            ->addFilter(
                $this->controlBuilder->buildDropdownYNUniform('filter_by_published', [null => 'любой'])
            );

        return $table->render();
    }

    public function formatDesc(GuestBookItemEntityInterface $item): string
    {
        return (string)Text::clearText($item->getText());
    }


    public function formatPublished(GuestBookItemEntityInterface $item): string
    {
        $data = [
            'class' => self::class,
            'id' => $item->getId(),
            'fn' => 'changePublished'
        ];
        return (new Switchery($data, $item->getPublished() === 'Y'))->render();
    }

    public function changePublished(int $id, bool $checked): void
    {
        $item = $this->guestBookItemRepository->findById($id);
        $item->setPublished($checked === true ? "Y" : 'N');
        $this->guestBookItemRepository->save($item);
    }


    public function formatDate(GuestBookItemEntityInterface $item): string
    {
        return '<nobr>' . $item->getDate(Date::formatDisplay()) . '</nobr>';
    }


    public function formatBook(GuestBookItemEntityInterface $item)
    {
        return '<nobr>' . $item->getGuestBook()->getTitle() . '</nobr>';
    }


    public function formatObject(GuestBookItemEntityInterface $item)
    {
        return $item->getObjectId() > "" ? anchor(sprintf(admin_path('/shop/products') . "?id=%s", $item->getObjectId()),
            sprintf("Товар #%s", $item->getObjectId()),
            [
                "target" => "_blank"
            ]
        ) : "Сайт";
    }

}