<?php
/**
 * For the full copyright and license information, please view the
 * docs/licenses/LICENSE.txt file that was distributed with this source code.
 */

namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory;

use PrestaShop\PrestaShop\Adapter\Feature\MultistoreFeature;
use PrestaShop\PrestaShop\Core\Context\LanguageContext;
use PrestaShop\PrestaShop\Core\Domain\Cart\CartStatus;
use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection;
use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection;
use PrestaShop\PrestaShop\Core\Grid\Action\Row\AccessibilityChecker\DeleteCartAccessibilityChecker;
use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection;
use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollectionInterface;
use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction;
use PrestaShop\PrestaShop\Core\Grid\Action\Type\LinkGridAction;
use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction;
use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection;
use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn;
use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BadgeColumn;
use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn;
use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\DataColumn;
use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\DateTimeColumn;
use PrestaShop\PrestaShop\Core\Grid\Filter\Filter;
use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection;
use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface;
use PrestaShop\PrestaShop\Core\Multistore\MultistoreContextCheckerInterface;
use PrestaShopBundle\Form\Admin\Type\DateRangeType;
use PrestaShopBundle\Form\Admin\Type\SearchAndResetType;
use PrestaShopBundle\Form\Admin\Type\YesAndNoChoiceType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\Request;

/**
 * Class CartGridDefinitionFactory builds Grid definition for carts listing.
 */
class CartGridDefinitionFactory extends AbstractFilterableGridDefinitionFactory
{
    use DeleteActionTrait;
    use BulkDeleteActionTrait;

    public const GRID_ID = 'cart';

    public function __construct(
        HookDispatcherInterface $hookDispatcher,
        protected readonly MultistoreFeature $multistoreFeature,
        protected readonly LanguageContext $languageContext,
        protected readonly MultistoreContextCheckerInterface $multistoreContextChecker,
        protected readonly DeleteCartAccessibilityChecker $deleteCartAccessibilityChecker,
    ) {
        parent::__construct($hookDispatcher);
    }

    /**
     * {@inheritdoc}
     */
    protected function getId()
    {
        return self::GRID_ID;
    }

    /**
     * {@inheritdoc}
     */
    protected function getName()
    {
        return $this->trans('Carts', [], 'Admin.Global');
    }

    /**
     * {@inheritdoc}
     */
    protected function getColumns()
    {
        $columnCollection = (new ColumnCollection())
            ->add((new BulkActionColumn('bulk'))
                ->setOptions([
                    'bulk_field' => 'id_cart',
                    'disabled_field' => 'unremovable',
                ])
            )
            ->add((new DataColumn('id_cart'))
                ->setName($this->trans('ID', [], 'Admin.Global'))
                ->setOptions([
                    'field' => 'id_cart',
                    'alignment' => 'center',
                ])
            )
            ->add((new DataColumn('id_order'))
                ->setName($this->trans('Order ID', [], 'Admin.Orderscustomers.Feature'))
                ->setOptions([
                    'field' => 'id_order',
                    'alignment' => 'center',
                ])
            )
            ->add((new BadgeColumn('status'))
                ->setName($this->trans('Status', [], 'Admin.Global'))
                ->setOptions([
                    'field' => 'status',
                    'alignment' => 'center',
                    'badge_type' => '',
                    'badge_type_field' => 'status_badge_color',
                ])
            )
            ->add((new DataColumn('customer_name'))
                ->setName($this->trans('Customer', [], 'Admin.Global'))
                ->setOptions([
                    'field' => 'customer_name',
                ])
            )
            ->add((new BadgeColumn('cart_total'))
                ->setName($this->trans('Total', [], 'Admin.Global'))
                ->setOptions([
                    'field' => 'cart_total',
                    'sortable' => false,
                    'alignment' => 'center',
                ])
            )
            ->add((new DataColumn('carrier_name'))
                ->setName($this->trans('Carrier', [], 'Admin.Global'))
                ->setOptions([
                    'field' => 'carrier_name',
                ])
            )
            ->add((new DateTimeColumn('date_add'))
                ->setName($this->trans('Date', [], 'Admin.Global'))
                ->setOptions([
                    'field' => 'date_add',
                    'format' => $this->languageContext->getDateTimeFormat(),
                    'clickable' => true,
                ])
            )
            ->add((new DataColumn('customer_online'))
                ->setName($this->trans('Online', [], 'Admin.Global'))
                ->setOptions([
                    'field' => 'customer_online',
                ])
            )
            ->add((new ActionColumn('actions'))
                ->setName($this->trans('Actions', [], 'Admin.Global'))
                ->setOptions([
                    'actions' => $this->getRowActions(),
                ])
            );

        if ($this->needShopNameColumn()) {
            $columnCollection->addAfter(
                'customer_online',
                (new DataColumn('shop_name'))
                    ->setName($this->trans('Shop', [], 'Admin.Global'))
                    ->setOptions([
                        'field' => 'shop_name',
                    ])
            );
        }

        return $columnCollection;
    }

    /**
     * {@inheritdoc}
     */
    protected function getGridActions()
    {
        return (new GridActionCollection())
            ->add((new LinkGridAction('export'))
                ->setName($this->trans('Export', [], 'Admin.Actions'))
                ->setIcon('cloud_download')
                ->setOptions([
                    'route' => 'admin_carts_export',
                ])
            )
            ->add((new SimpleGridAction('common_refresh_list'))
                ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature'))
                ->setIcon('refresh')
            )
            ->add((new SimpleGridAction('common_show_query'))
                ->setName($this->trans('Show SQL query', [], 'Admin.Actions'))
                ->setIcon('code')
            )
            ->add((new SimpleGridAction('common_export_sql_manager'))
                ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions'))
                ->setIcon('storage')
            );
    }

    /**
     * {@inheritdoc}
     */
    protected function getFilters()
    {
        return (new FilterCollection())
            ->add(
                (new Filter('id_cart', TextType::class))
                    ->setAssociatedColumn('id_cart')
                    ->setTypeOptions([
                        'required' => false,
                    ])
            )
            ->add(
                (new Filter('id_order', TextType::class))
                    ->setAssociatedColumn('id_order')
                    ->setTypeOptions([
                        'required' => false,
                    ])
            )
            ->add(
                (new Filter('status', ChoiceType::class))
                    ->setAssociatedColumn('status')
                    ->setTypeOptions([
                        'placeholder' => $this->translator->trans('All', [], 'Admin.Global'),
                        'choices' => [
                            $this->translator->trans('Ordered', [], 'Admin.Orderscustomers.Feature') => CartStatus::ORDERED,
                            $this->translator->trans('Non ordered', [], 'Admin.Orderscustomers.Feature') => CartStatus::NOT_ORDERED,
                            $this->translator->trans('Abandoned cart', [], 'Admin.Orderscustomers.Feature') => CartStatus::ABANDONED_CART,
                        ],
                        'expanded' => false,
                        'multiple' => false,
                        'required' => false,
                        'choice_translation_domain' => false,
                    ])
            )
            ->add(
                (new Filter('customer_name', TextType::class))
                    ->setAssociatedColumn('customer_name')
                    ->setTypeOptions([
                        'required' => false,
                    ])
            )
            ->add(
                (new Filter('carrier_name', TextType::class))
                    ->setAssociatedColumn('carrier_name')
                    ->setTypeOptions([
                        'required' => false,
                    ])
            )
            ->add(
                (new Filter('date_add', DateRangeType::class))
                    ->setAssociatedColumn('date_add')
                    ->setTypeOptions([
                        'required' => false,
                    ])
            )
            ->add(
                (new Filter('customer_online', YesAndNoChoiceType::class))
                    ->setAssociatedColumn('customer_online')
                    ->setTypeOptions([
                        'required' => false,
                    ])
            )
            ->add(
                (new Filter('actions', SearchAndResetType::class))
                    ->setAssociatedColumn('actions')
                    ->setTypeOptions([
                        'reset_route' => 'admin_common_reset_search_by_filter_id',
                        'reset_route_params' => [
                            'filterId' => self::GRID_ID,
                        ],
                        'redirect_route' => 'admin_carts_index',
                    ])
            );
    }

    /**
     * {@inheritdoc}
     */
    protected function getBulkActions()
    {
        return (new BulkActionCollection())
            ->add(
                $this->buildBulkDeleteAction('admin_carts_bulk_delete')
            );
    }

    /**
     * Add row actions in grid.
     *
     * @return RowActionCollectionInterface
     */
    protected function getRowActions(): RowActionCollectionInterface
    {
        return (new RowActionCollection())
            ->add(
                (new LinkRowAction('view'))
                    ->setName($this->trans('View', [], 'Admin.Actions'))
                    ->setIcon('zoom_in')
                    ->setOptions([
                        'route' => 'admin_carts_view',
                        'route_param_name' => 'cartId',
                        'route_param_field' => 'id_cart',
                        'clickable_row' => true,
                    ])
            )
            ->add(
                $this->buildDeleteAction(
                    'admin_carts_delete',
                    'cartId',
                    'id_cart',
                    Request::METHOD_DELETE,
                    [],
                    [
                        'accessibility_checker' => $this->deleteCartAccessibilityChecker,
                    ]
                )
            );
    }

    /**
     * Function aim to define if we need to add Shop Name column in grid.
     * (Only if we are on Multistore mode and All ou Group context)
     *
     * @return bool
     */
    private function needShopNameColumn(): bool
    {
        return $this->multistoreFeature->isActive() && !$this->multistoreContextChecker->isSingleShopContext();
    }
}
