<?php

namespace Autogedal\Retur\Model;

use Autogedal\Retur\Api\Data\ReturInterface;
use Autogedal\Retur\Api\ReturRepositoryInterface;
use Autogedal\Retur\Model\ReturFactory;
use Autogedal\Retur\Model\ResourceModel\Retur as ReturResource;
use Autogedal\Retur\Model\ResourceModel\Retur\CollectionFactory;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Exception\CouldNotDeleteException;

class ReturRepository implements ReturRepositoryInterface
{
    /**
     * @var returFactory
     */
    private $returFactory;

    /**
     * @var ReturResource
     */
    private $returResource;

    /**
     * @var CollectionFactory
     */
    private $collectionFactory;

    /**
     * Model data storage
     *
     * @var array
     */
    private $returs;

    public function __construct(
        ReturFactory $returFactory,
        ReturResource $returResource,
        CollectionFactory $collectionFactory
    ) {
        $this->returFactory = $returFactory;
        $this->returResource = $returResource;
        $this->collectionFactory = $collectionFactory;
    }

    /**
     * @inheritdoc
     */
    public function save(ReturInterface $retur)
    {
        try {
            if ($retur->getEntityId()) {
                $retur = $this->getById($retur->getEntityId())->addData($retur->getData());
            }
            $this->returResource->save($retur);
            unset($this->returs[$retur->getEntityId()]);
        } catch (\Exception $e) {
            if ($retur->getEntityId()) {
                throw new CouldNotSaveException(
                    __(
                        'Unable to save Retur with ID %1. Error: %2',
                        [$retur->getEntityId(), $e->getMessage()]
                    )
                );
            }
            throw new CouldNotSaveException(__('Unable to save new Retur. Error: %1', $e->getMessage()));
        }

        return $retur;
    }

    /**
     * @inheritdoc
     */
    public function getById($returId)
    {
        if (!isset($this->returs[$returId])) {
            $retur = $this->returFactory->create();
            $this->returResource->load($retur, $returId);
            if (!$retur->getEntityId()) {
                throw new NoSuchEntityException(__('Retur with specified ID "%1" not found.', $returId));
            }
            $this->returs[$returId] = $retur;
        }

        return $this->returs[$returId];
    }

    /**
     * @inheritdoc
     */
    public function delete(ReturInterface $retur)
    {
        try {
            $this->returResource->delete($retur);
            unset($this->returs[$retur->getEntityId()]);
        } catch (\Exception $e) {
            if ($retur->getEntityId()) {
                throw new CouldNotDeleteException(
                    __(
                        'Unable to remove Retur with ID %1. Error: %2',
                        [$retur->getEntityId(), $e->getMessage()]
                    )
                );
            }
            throw new CouldNotDeleteException(__('Unable to remove Retur. Error: %1', $e->getMessage()));
        }

        return true;
    }

    /**
     * @inheritdoc
     */
    public function deleteById($returId)
    {
        $returModel = $this->getById($returId);
        $this->delete($returModel);

        return true;
    }

    /**
     * @param int[] $returIds
     *
     * @return ReturInterface[]
     */
    public function getListByIds($returIds)
    {
        $idsToLoad = $result = [];
        foreach ($returIds as $returId) {
            if (isset($this->returs[$returId])) {
                $result[$returId] = $this->returs[$returId];
            } else {
                $idsToLoad[] = $returId;
            }
        }
        if (!empty($idsToLoad)) {
            $collection = $this->collectionFactory->create();
            $collection
                ->addFieldToFilter(ReturInterface::ENTITY_ID, ['in' => $idsToLoad]);

            foreach ($collection->getItems() as $retur) {
                $this->returs[$retur->getId()] = $retur;
                $result[$retur->getId()] = $retur;
            }
        }

        return $result;
    }
}
