<?php

namespace App\Command;

use App\Entity\Content;
use App\Service\Campaign\TeamMemberService;
use App\Service\CampaignService;
use App\Service\Content\StatusService;
use App\Service\Content\TypeService;
use App\Service\ContentService;
use Cake\Chronos\Date;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Webmozart\Assert\Assert;

class CrmMakeContentCommand extends Command
{
    protected static $defaultName = 'crm:make:content';
    private $contentService;
    private $campaignService;
    private $contentStatusService;
    /**
     * @var TypeService
     */
    private $contentTypeService;
    /**
     * @var TeamMemberService
     */
    private $teamMemberService;

    public function __construct(ContentService $contentService, CampaignService $campaignService, StatusService $contentStatusService, TypeService $contentTypeService, TeamMemberService $teamMemberService, $name = null)
    {
        parent::__construct($name);
        $this->contentService = $contentService;
        $this->campaignService = $campaignService;
        $this->contentStatusService = $contentStatusService;
        $this->contentTypeService = $contentTypeService;
        $this->teamMemberService = $teamMemberService;
    }

    protected function configure()
    {
        $this
            ->setDescription('Add a Content')
            ->addArgument('campaign', InputArgument::REQUIRED, 'Campaign which content will be assigned to')
            ->addArgument('type', InputArgument::REQUIRED, 'Type of a content')
            ->addArgument('status', InputArgument::OPTIONAL, 'Status of a content')
            ->addOption('option1', null, InputOption::VALUE_NONE, 'Option description');
    }

    protected function execute(InputInterface $input, OutputInterface $output): ?int
    {
        $io = new SymfonyStyle($input, $output);

        $io->note(sprintf('You passed arguments: %s, %s', $input->getArgument('campaign'), $input->getArgument('type')));

        try {
            Assert::integerish($input->getArgument('type'));
            $campaign = $this->campaignService->getCampaign($input->getArgument('campaign'));
            $type = $this->contentTypeService->get($input->getArgument('type'));
            $status = $this->contentStatusService->getFirstByWorkflow($type->getWorkflow());
            Assert::notNull($status);
        } catch (\Exception $e) {
            $io->error($e->getMessage());

            return 1;
        }

        if ($campaign->hasAssignedContentWriter()) {
            $user = $campaign->getContentWriter();
        } elseif ($campaign->hasRandomContentAssignment()) {
            $team = $this->teamMemberService->getByCampaign($campaign->getId());
            $writers = array_filter($team, function ($member) {
                return $member->getRole()->filter(function ($role) { return 'Content Writer' === $role->getTitle(); })
                        ->count() > 0;
            });
            if (count($writers) > 0) {
                $user = $writers[array_rand($writers)]->getUser();
            }
        }

        $content = (new Content())
            ->setTitle('Content #'.($campaign->getContents()->count() + 1))
            ->setType($type)
            ->setCampaign($campaign)
            ->setStatus($status)
            ->setDueDate((new Date(time()))->modify('+2 weeks'));

        if ($user) {
            $content->setUser($user);
        }
        $this->contentService->saveContent($content);

        $output->write('Content created');
    }
}
