<?php
declare(strict_types=1);

namespace Autogedal\EanTools\Controller\Adminhtml\Missing;

use Autogedal\EanTools\Controller\Adminhtml\AbstractFormatTool;
use Autogedal\EanTools\Model\Spreadsheet\Format;
use Autogedal\EanTools\Model\Tool\ExportScheduler;
use Magento\Backend\App\Action\Context;
use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\View\Result\PageFactory;
use Psr\Log\LoggerInterface;
use Throwable;

class Post extends AbstractFormatTool implements HttpPostActionInterface
{
    private const DEFAULT_STATUS = 'all';
    private const STATUSES = ['all', 'enabled', 'disabled'];
    private const PRODUCT_TYPES = ['simple', 'bundle', 'configurable', 'virtual', 'grouped', 'downloadable'];

    public function __construct(
        Context $context,
        PageFactory $resultPageFactory,
        Format $format,
        private readonly ExportScheduler $scheduler,
        private readonly LoggerInterface $logger
    ) {
        parent::__construct($context, $resultPageFactory, $format);
    }

    public function execute(): ResultInterface
    {
        try {
            $runId = $this->scheduler->scheduleMissing([
                'status' => $this->resolveStatus(),
                'types' => $this->resolveTypes(),
            ], $this->resolveFormat());
            $this->messageManager->addSuccessMessage(
                (string)__('The export has been queued and will be processed by cron.')
            );

            return $this->redirectTo('*/result/index', ['run' => $runId]);
        } catch (LocalizedException $e) {
            $this->logger->warning('Autogedal_EanTools missing: ' . $e->getMessage(), ['exception' => $e]);
            $this->messageManager->addErrorMessage($e->getMessage());
        } catch (Throwable $e) {
            $this->logger->error('Autogedal_EanTools missing: ' . $e->getMessage(), ['exception' => $e]);
            $this->messageManager->addErrorMessage((string)__('The list of products without EANs could not be generated.'));
        }

        return $this->redirectTo('*/missing/index');
    }

    private function resolveStatus(): string
    {
        $status = $this->getRequest()->getParam('status');

        return is_string($status) && in_array($status, self::STATUSES, true)
            ? $status
            : self::DEFAULT_STATUS;
    }

    private function resolveTypes(): array
    {
        $types = $this->getRequest()->getParam('types');
        if (!is_array($types)) {
            return [];
        }

        return array_values(array_unique(array_intersect(array_filter($types, 'is_string'), self::PRODUCT_TYPES)));
    }
}
