<?php

namespace Shop\Presentation\Modules\AdminClientCarts;

use ActiveTable\ColumnTable;
use ActiveTable\DataTableEngine;
use Core\AdminModuleController;
use Core\Form\Control\Menu;
use Core\Form\Control\MenuItemDelete;
use Core\Form\Control\MenuItemEdit;
use Core\Form\ControlBuilder;
use Core\Helpers\Date;
use Core\ModuleController;
use Diamond\Helpers\Form;
use Diamond\Infrastructure\Models\Session\Session;
use DiamondTable\CommandFactory;
use DiamondTable\Commands\TableRowSave;
use DiamondTable\Commands\TableRowSuccessTest;
use DiamondTable\TableFactory;
use Repo\EntityInterface;
use Shop\Application\Shopping\ShoppingService;
use Shop\Domain\CustomerBasket\Contracts\CustomerCartRepositoryInterface;
use Shop\Presentation\Helpers\Text;
use Shop\Infrastructure\Repositories\Customer\CustomerRepository;
use Shop\Infrastructure\Repositories\CustomerCart\CustomerCartCriteria;
use Shop\Infrastructure\Repositories\CustomerCart\CustomerCartRepository;
use Shop\Infrastructure\Repositories\OrderItem\OrderItemCriteria;
use Shop\Infrastructure\Repositories\OrderItem\OrderItemRepository;

/**
 * Description of AdminBaskets
 *
 * @author Diamond Code Generator
 */
class AdminClientCarts extends AdminModuleController
{

    private array $extractedData = [];

    public function __construct(protected TableFactory           $tableFactory,
                                protected CustomerCartRepository $customerCartRepository,
                                protected CustomerRepository     $customerRepository,
                                protected ShoppingService        $shoppingService,
                                protected ControlBuilder         $controlBuilder)
    {
    }


    /**
     * @return string
     * @throws \ActiveTable\Exceptions\ActiveTableException
     * @throws \ReflectionException
     */
    public function process(): string
    {
        $table = $this->tableFactory->buildAdminTable($this->customerCartRepository, CustomerCartCriteria::create());

        $table
            ->removeControlAccess(DataTableEngine::CONTROL_ACCESS_DELETE)
            ->removeControlAccess(DataTableEngine::CONTROL_ACCESS_ADD)
            ->removeControlAccess(DataTableEngine::CONTROL_ROWS_SELECT)
            ->setDefaultSortColumn('time', 'DESC')
            ->addColumn(
                new ColumnTable('id', '№')
            )
            ->addColumn(
                (new ColumnTable('time', 'Дата/Время'))
                    ->setFormat($this, 'formatTime')
            )
            ->addColumn(
                (new ColumnTable('time', 'Срок жизни'))
                    ->setFormat($this, 'formatTimeLast')
            )
            ->addColumn(
                (new ColumnTable('client', 'Клиент'))
                    ->setFormat($this, 'formatCustomer')
            )
            ->addColumn(
                (new ColumnTable('data', 'Содержимое'))
                    ->setFormat($this, 'formatItems')
            )
            ->addColumn(
                (new ColumnTable('sum', 'Сумма заказа, ' . $this->shoppingService->getDefaultCurrency()))
                    ->setFormat($this, 'formatSum')
            );

        $table
            ->addField(
                $this->controlBuilder->buildInput('article'), true
            );

        return $table->render();
    }


    public function formatMenuActions(EntityInterface $entity): string
    {
        return (new Menu([
            new MenuItemEdit($entity->getId()),
            new MenuItemDelete($entity->getId())
        ]))->render();
    }

    public function formatTime(EntityInterface $entity): string
    {
        return (new \DateTime())->setTimestamp($entity->getTime())->format(Date::formatDisplay());
    }

    public function formatTimeLast(EntityInterface $entity): string
    {
        $date = (new \DateTime())->setTimestamp($entity->getTime() + $entity->getLifeTime());
        $res = $date->format(Date::formatDisplay());
        if ($date < new \DateTime()) {
            return '<i class="text-danger">' . $res . '</i>';
        }
        return $res;
    }

    public function formatSum(EntityInterface $entity): string
    {
        $data = $this->extractData($entity);

        return $data['basket']['summ'] ?? 0;
    }

    /**
     * @param EntityInterface|Session $entity
     * @return string
     */
    public function formatItems(EntityInterface $entity): string
    {
        $data = $this->extractData($entity);

        $list = [];

        if (isset($data['basket']) && isset($data['basket']['items'])) {
            foreach ($data['basket']['items'] as $item) {

                $list[] = $item['article'] . ' ' . $item['price'] . ' x ' . $item['amount'];

            }
        }

        return Text::toggleList($list);
    }

    private function extractData(EntityInterface $entity): array
    {
        if (isset($this->extractedData[$entity->getId()])) {
            $res = $this->extractedData[$entity->getId()];
        } else {
            $res = stream_get_contents($entity->getData());
            $this->extractedData[$entity->getId()] = $res;
        }

        $data = unserialize(str_replace('_sf2_attributes|', '', $res));

        return is_array($data) ? $data : [];
    }

    public function formatCustomer(EntityInterface $entity): string
    {
        $data = $this->extractData($entity);

        if (isset($data['customer_id'])) {

            $customer = $this->customerRepository->findById($data['customer_id']);

            if ($customer) {
                $name = sprintf("%s / %s / %s",
                    $customer->getName(),
                    $customer->getCustomerGroup()->getName(),
                    $customer->getManager()->getShop()->getTitle()
                );
                return anchor('/admin/shop/customers/customers', $name, [], [
                    'fn' => 'edit',
                    'id' => $customer->getId()
                ]);
            }
        }

        return 'гость';

    }
}               