<?php

namespace FiloBlu\Flow\Console\Command;

use Exception;
use FiloBlu\Flow\Helper\Data;
use FiloBlu\Flow\Model\Inboundflow;
use FiloBlu\Flow\Model\ResourceModel\Inboundflow\CollectionFactory;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\ObjectManagerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Class ResetCommand
 * @package FiloBlu\Flow\Console\Command
 */
class ResetCommand extends Command
{
    /**
     * @var CollectionFactory
     */
    protected $inboundflowFactory;

    /**
     * @var ObjectManagerInterface
     */
    protected $objectManager;

    /**
     * @var ResourceConnection
     */
    protected $resourceConnection;

    /**
     * @var Data
     */
    private $helperData;

    /**
     * ListCommand constructor.
     * @param CollectionFactory $inboundFlowFactory
     * @param ResourceConnection $resourceConnection
     * @param ObjectManagerInterface $objectManager
     * @param Data $helperData
     * @param string|null $name
     */
    public function __construct(
        CollectionFactory      $inboundFlowFactory,
        ResourceConnection     $resourceConnection,
        ObjectManagerInterface $objectManager,
        Data                   $helperData,
                               $name = null
    )
    {
        parent::__construct($name);
        $this->helperData = $helperData;
        $this->inboundflowFactory = $inboundFlowFactory;
        $this->objectManager = $objectManager;
        $this->resourceConnection = $resourceConnection;
    }

    /**
     *
     */
    protected function configure()
    {
        $this->setName('flow:reset')
            ->addArgument('status', InputArgument::REQUIRED, 'Status to set')
            ->addArgument('flow', InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'Inbound Flow ids')
            ->setDescription('Reset to state');
    }

    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     * @return int|void
     * @throws Exception
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $status = $input->getArgument('status');

        if (!Inboundflow::isValidStatus($status)) {
            $output->writeln("Invalid status '{$status}'");
            foreach (array_keys(Inboundflow::getStatusList()) as $allowed) {
                $output->writeln("    {$allowed}");
            }

            exit(1);
        }

        $items = $this->inboundflowFactory->create()
            ->addFilter('id', $input->getArgument('flow'), 'in')
            ->getItems();

        foreach ($items as $item) {
            $this->resetItemToState($item, $status);
        }

        return 0;
    }

    /**
     * @param Inboundflow $item
     * @param $status
     * @throws Exception
     */
    protected function resetItemToState(Inboundflow $item, $status)
    {
        if ($item->getFlow() == 'TableFlow') {
            return;
        }

        $mainTable = $this->objectManager
            ->create(sprintf('FiloBlu\Flow\Model\%s', $item->getFlow()))
            ->getResource()
            ->getMainTable();

        $connection = $this->resourceConnection->getConnection();
        $where = $connection->quoteInto('meta_file = ?', $item->getId());

        switch ($status) {
            case Inboundflow::STATUS_PARSED:
                $bind = ['meta_processed' => 0];
                if ($item->getFlow() === 'Imagesflow') {
                    $bind['image_status'] = $status;
                    $bind['image_process_time'] = null;
                }

                $connection->update($mainTable, $bind, $where);

                break;
            case Inboundflow::STATUS_RECEIVED:
                if ($item->getFlow() === 'Imagesflow') {
                    $connection->update($mainTable, [
                        'image_status' => $status,
                        'meta_processed' => 0,
                        'image_hide' => 0,
                        'image_type' => null,
                        'image_alt' => null,
                        'image_position' => null,
                        'image_process_time' => null,
                        'log' => null
                    ], $where);
                } else {
                    $connection->delete($mainTable, $where);
                }

                break;
            default:
        }

        $item->setStatus($status);
        $item->setRetry(0);
        $item->setLog('');
        $item->setComment('');
        $item->save();
    }
}
