<?php

namespace KupShop\OrderingBundle\Util\Attachment;

use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\OrderingBundle\Attachment\AttachmentInterface;
use KupShop\OrderingBundle\Exception\UnknownAttachmentTypeException;
use Symfony\Component\DependencyInjection\ContainerInterface;

class AttachmentLocator
{
    private $handlers;
    private $container;

    private $attachments = [];
    private $serviceIDs = [];

    public function __construct(iterable $handlers, ContainerInterface $container)
    {
        $this->handlers = $handlers;
        $this->container = $container;
    }

    public function getAttachments(object|string $group): array
    {
        if (empty($this->attachments)) {
            $typesByPriority = [];
            $attachments = [];
            foreach ($this->handlers as $handler) {
                if ($handler::isAllowed()) {
                    $typesByPriority[$handler::getGroup()][$handler::getType()] = $handler::getPriority();
                    $attachments[$handler::getGroup()][$handler::getType()] = $handler::getName();
                }
            }
            foreach ($typesByPriority as $groupValue => $groupByPriority) {
                arsort($groupByPriority);
                foreach ($groupByPriority as $type => $priority) {
                    $this->attachments[$groupValue][$type] = $attachments[$groupValue][$type];
                }
            }
        }
        if ($group == 'ALL') {
            return $this->attachments;
        }

        return $this->attachments[$group->value];
    }

    /**
     * @return AttachmentInterface
     *
     * @throws UnknownAttachmentTypeException
     */
    public function getServiceByType(string $type, \Order $order)
    {
        if (empty($this->serviceIDs)) {
            foreach ($this->handlers as $handler) {
                $this->serviceIDs[$handler::getType()] = get_class($handler);
            }
        }

        if (!isset($this->serviceIDs[$type])) {
            throw new UnknownAttachmentTypeException($type);
        }

        // TODO predelat na stejny zpusob jako jsou emaily

        /** @var AttachmentInterface $service */
        $service = ServiceContainer::getService($this->serviceIDs[$type]);
        $service->setOrder($order);

        return $service;
    }
}
