<?php

namespace Velis\Bpm\Workflow\Utils;

use Psr\SimpleCache\InvalidArgumentException;
use Velis\Arrays;
use Velis\Bpm\Email\Alias as EmailAlias;
use Velis\Bpm\Ticket\Ticket;
use Velis\Bpm\Workflow\Subject;
use Velis\Exception;
use Velis\Notification\Recipient;
use Velis\ParameterBag;
use Velis\User\UserProvider;

/**
 * @author Jan Małysiak <jan.malysiak@velistech.com>
 */
class EmailRecipientProvider
{
    /**
     * @var Recipient[]
     */
    private array $recipients = [];

    public function __construct(private readonly UserProvider $userProvider)
    {
    }

    /**
     * @return Recipient[]
     * @throws Exception
     * @throws InvalidArgumentException
     */
    public function getRecipients(ParameterBag $params, Subject $subject): array
    {
        $userIds = Arrays::toArray($params['user_id']);
        foreach ($this->userProvider->getUsers($userIds) as $user) {
            $this->add($user);
        }

        if ($params['responsible'] && $subject instanceof Ticket) {
            $operator = $subject->getOperator();
            if ($operator) {
                $this->add($operator);
            }
        }

        if ($params['reporter'] && $subject instanceof Ticket) {
            $this->add($subject->getReporter());
        }

        if ($params['owner'] && $subject instanceof Ticket) {
            $this->add($subject->getOwner());
        }

        if ($params['observers'] && $subject instanceof Ticket) {
            foreach ($subject->getObservers() as $observer) {
                $this->add($observer);
            }
        }

        /**
         * If $subject is type Guestbook\Entry
         */
        if ($params['guestbook_person'] && $subject->host_email) {
            $this->add(new EmailAlias($subject->host_email));
        }

        return array_values($this->recipients);
    }

    private function add(Recipient $recipient): void
    {
        $hash = md5(get_class($recipient) . $recipient->getEmail());
        $this->recipients[$hash] = $recipient;
    }
}
