<?php

namespace Signteer\Core\Action\Signup;

use Signteer\Core\Action\ActionResult;
use Signteer\Core\Action\Volunteer\CreateVolunteer;
use Signteer\Core\Event\EventBus;
use Signteer\Core\Event\Signup\SignupCreated;
use Signteer\Core\Criteria\TaskCriteria;
use Signteer\Core\Criteria\SignupCriteria;
use Signteer\Core\Criteria\VolunteerCriteria;
use Signteer\Core\Finder\TaskFinder;
use Signteer\Core\Finder\SignupFinder;
use Signteer\Core\Finder\VolunteerFinder;
use Signteer\Core\Writer\SignupWriter;

final class CreateSignup
{
    public $writer = SignupWriter::class;
    public $taskFinder = TaskFinder::class;
    public $signupFinder = SignupFinder::class;
    public $volunteerFinder = VolunteerFinder::class;
    public $createVolunteer = CreateVolunteer::class;
    public $eventBus = EventBus::class;

    public function __invoke(int $taskId, string $title, string $email, string $phone): ActionResult
    {
        $ret = new ActionResult();

        $title = trim($title);
        if (!strlen($title)) {
            return $ret->addError('__Title is required.__');
        }

        $task = $this->taskFinder->get($taskId);
        if (!$task) {
            return $ret->addError('__Invalid task.__');
        }

        $totalSpots = $task->getSpots();

        $c = (new SignupCriteria())->whereTaskId('=', $taskId);
        $countExistingSignups = $this->signupFinder->count($c);

        if ($countExistingSignups >= $totalSpots) {
            return $ret->addError('__No spots available for new sign-ups.__');
        }

        $ret_ = ($this->createVolunteer)($title, $email, $phone);
        if (!$ret_->isOk()) {
            return $ret_;
        }

        $volunteerId = $ret_->getReturn();
        $this->writer->create($taskId, $volunteerId);

        return $ret;
    }
}
