<?php

namespace FiloBlu\Refilo\Model\Redirects\Repository;

use FiloBlu\Refilo\Model\Redirects\AbstractSqlRepository;
use FiloBlu\Refilo\Model\Redirects\Interfaces\RedirectInterface;
use FiloBlu\Refilo\Model\Redirects\Interfaces\RedirectInterfaceFactory;
use FiloBlu\Refilo\Model\Redirects\Interfaces\RedirectsRepositoryInterface;
use Magento\Framework\Api\Search\SearchCriteriaInterfaceFactory;
use Magento\Framework\Api\SearchResultsInterfaceFactory;
use Magento\Framework\App\ResourceConnection;
use RuntimeException;

class RedirectsRepository extends AbstractSqlRepository implements RedirectsRepositoryInterface
{

    /** @var string */
    const TABLE = 'filoblu_refilo_redirect';
    /**
     * @var RedirectInterfaceFactory
     */
    protected $redirectFactory;

    public function __construct(
        RedirectInterfaceFactory $redirectFactory,
        ResourceConnection $resourceConnection,
        SearchCriteriaInterfaceFactory $searchCriteriaFactory,
        SearchResultsInterfaceFactory $searchResultsFactory
    ) {
        parent::__construct($resourceConnection, $searchCriteriaFactory, $searchResultsFactory);
        $this->redirectFactory = $redirectFactory;
    }

    /**
     * @inheritDoc
     */
    public function save(RedirectInterface $redirect)
    {
        $connection = $this->resourceConnection->getConnection();
        $table = $connection->getTableName(self::TABLE);

        $redirectId = $redirect->getId();

        if ($redirectId === null && ctype_space($redirectId)) {
            throw new RuntimeException('Could not save event configuration with empty event code');
        }

        $bindings = [
            RedirectInterface::HOST => $redirect->getHost(),
            RedirectInterface::REQUEST_URL => $redirect->getRequestURL(),
            RedirectInterface::TARGET_URL => $redirect->getTargetUrl(),
            RedirectInterface::REDIRECT_CODE => $redirect->getRedirectCode()
        ];

        if ($redirect->getId()) {
            $connection->update($table, $bindings, $connection->quoteInto(
                sprintf('%s = ?', RedirectInterface::ID),
                $redirect->getId()
            ));
        } else {
            $connection->insert($table, $bindings);
            $redirect->setId($connection->lastInsertId($table));
        }

        return $redirect;
    }

    /**
     * @inheritDoc
     */
    public function delete(RedirectInterface $redirect)
    {
        if (!($id = $redirect->getId())) {
            return;
        }

        $this->deleteById($id);
    }

    /**
     * @inheritDoc
     */
    public function getTable(): string
    {
        return self::TABLE;
    }

    /**
     * @inheritDoc
     */
    public function getIdFieldName(): string
    {
        return RedirectInterface::ID;
    }

    /**
     * @inheritDoc
     */
    public function fromRow(array $row)
    {
        /** @var RedirectInterfaceFactory $redirect */
        $redirect = $this->redirectFactory->create();

        return $redirect
            ->setHost($row[RedirectInterface::HOST] ?? '')
            ->setRequestUrl($row[RedirectInterface::REQUEST_URL] ?? '')
            ->setTargetUrl($row[RedirectInterface::TARGET_URL] ?? '')
            ->setRedirectCode($row[RedirectInterface::REDIRECT_CODE] ?? '');
    }
}
