<?php

namespace FiloBlu\ActiveCampaign\Console\Command;

use FiloBlu\ActiveCampaign\Api\Data\JobsInterface;
use FiloBlu\ActiveCampaign\Cron\JobManager as JobManagerCron;
use FiloBlu\ActiveCampaign\Model\Config\Source\DirectionType;
use FiloBlu\ActiveCampaign\Model\Config\Source\EntityType;
use FiloBlu\ActiveCampaign\Model\Config\Source\JobStatus;
use FiloBlu\ActiveCampaign\Model\Config\Source\Type;
use FiloBlu\ActiveCampaign\Model\JobManager as JobManagerModel;
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 JobPrepare
 * @package FiloBlu\ActiveCampaign\Console\Command
 */
class JobPrepare extends Command
{

    /**
     * @var JobManagerCron
     */
    protected $jobManager;


    /**
     * JobManager constructor.
     * @param JobManagerCron $jobManager
     * @param string|null $name
     */
    public function __construct(
        JobManagerCron $jobManager,
        string $name = null
    ) {
        parent::__construct($name);
        $this->jobManager = $jobManager;
    }

    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     * @return int|void
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $options = $this->createOptionArguments($input, $output);

        if ($options === false) {
            return;
        }

        list($status, $message) = $this->jobManager->executeJob($options);

        $output->writeln("<$status>$message</$status>");
        return 0;
    }

    /**
     * @param $input
     * @param $output
     * @return array|bool
     */
    protected function createOptionArguments($input, $output)
    {
        $options = [];
        $type = $input->getArgument(JobsInterface::TYPE);
        $direction = $input->getArgument(JobsInterface::DIRECTION);
        $entity = $input->getArgument(JobsInterface::ENTITY);
        $exportType = $input->getArgument(JobManagerCron::EXPORT_TYPE);
        $consoleError = JobManagerModel::CONSOLE_ERROR;

        $options[JobManagerCron::OPERATION] = JobManagerCron::OPERATION_PREPARE;

        if (!in_array($type, Type::TYPE_AVAILABLE)) {
            $allowed_type = implode(',', Type::TYPE_AVAILABLE);
            $output->writeln("<{$consoleError}>The type '{$type}' is not available. Please choose between [{$allowed_type}]</{$consoleError}>");
            return false;
        }
        if (!in_array($direction, DirectionType::DIRECTION_AVAILABLE)) {
            $allowed_direction = implode(',', DirectionType::DIRECTION_AVAILABLE);
            $output->writeln("<{$consoleError}>The direction '{$direction}' is not available. Please choose between [{$allowed_direction}]</{$consoleError}>");
            return false;
        }
        if (!in_array($entity, EntityType::ENTITY_AVAILABLE)) {
            $allowed_entity = implode(',', EntityType::ENTITY_AVAILABLE);
            $output->writeln("<{$consoleError}>The entity '{$entity}' is not available. Please choose between [{$allowed_entity}]</{$consoleError}>");
            return false;
        }
        if (!in_array($exportType, JobsInterface::EXPORT_TYPE_AVAILABLE)) {
            $allowed_export_type = implode(',', JobsInterface::EXPORT_TYPE_AVAILABLE);
            $output->writeln("<{$consoleError}>The entity '{$entity}' is not available. Please choose between [{$allowed_export_type}]</{$consoleError}>");
            return false;
        }

        $options[JobsInterface::TYPE] = $type;
        $options[JobsInterface::DIRECTION] = $direction;
        $options[JobsInterface::ENTITY] = $entity;
        $options[JobManagerCron::EXPORT_TYPE] = $exportType;
        $options[JobsInterface::STATUS] = JobStatus::JOB_STATUS_BULK_WAITING;

        return $options;
    }

    /**
     * @inheritDoc
     */
    protected function configure()
    {
        $this->setName('activecampaign:job:prepare');
        $this->setDescription('ActiveCampaign job manager');
        $this->setDefinition([
            new InputArgument(JobsInterface::ENTITY, InputArgument::REQUIRED, "entity"),
            new InputArgument(JobManagerCron::EXPORT_TYPE, InputArgument::OPTIONAL, "export_type", JobsInterface::INCREMENTAL),
            new InputArgument(JobsInterface::TYPE, InputArgument::OPTIONAL, "type", Type::TYPE_REST),
            new InputArgument(JobsInterface::DIRECTION, InputArgument::OPTIONAL, "direction", DirectionType::DIRECTION_EXPORT)
        ]);
    }
}
