<?php

namespace FiloBlu\Storelocator\Model;


use FiloBlu\Core\Framework\Model\AbstractSqlRepository;
use FiloBlu\Storelocator\Api\Data\StoreInterface;
use Magento\Framework\Api\Search\SearchCriteriaInterfaceFactory;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Api\SearchResultsInterfaceFactory;
use Magento\Framework\App\ResourceConnection;

/**
 *
 */
class StoreRepository extends AbstractSqlRepository
{
    const TABLE_NAME = 'filoblu_storelocator_stores';
    /**
     * @var StoresFactory
     */
    private $storesFactory;
    /**
     * @var SearchCriteriaBuilder
     */
    private $searchCriteriaBuilder;

    /**
     * @param ResourceConnection $resourceConnection
     * @param SearchCriteriaBuilder $searchCriteriaBuilder
     * @param SearchCriteriaInterfaceFactory $searchCriteriaFactory
     * @param SearchResultsInterfaceFactory $searchResultsFactory
     * @param StoresFactory $storesFactory
     */
    public function __construct(
        ResourceConnection $resourceConnection,
        SearchCriteriaBuilder $searchCriteriaBuilder,
        SearchCriteriaInterfaceFactory $searchCriteriaFactory,
        SearchResultsInterfaceFactory $searchResultsFactory,
        StoresFactory $storesFactory
    ) {
        parent::__construct($resourceConnection, $searchCriteriaFactory, $searchResultsFactory);
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
        $this->storesFactory = $storesFactory;
    }

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

    /**
     * @return string
     */
    public function getIdFieldName(): string
    {
        return 'store_id';
    }

    /**
     * @param array $row
     * @return \FiloBlu\Storelocator\Api\Data\StoreInterface
     */
    public function fromRow(array $row)
    {
        return $this->storesFactory->create(['data' => $row]);
    }

    /**
     * @param string $storeCode
     * @return false|\FiloBlu\Storelocator\Api\Data\StoreInterface|\Magento\Framework\Api\ExtensibleDataInterface|null
     */
    public function getByStoreCode(string $storeCode)
    {
        $searchCriteria = $this->searchCriteriaBuilder
            ->addFilter('store_code', $storeCode)
            ->create();

        return current($this->getList($searchCriteria)->getItems()) ?: null;
    }

    /**
     * @param string $storeCode
     * @return int|null
     */
    public function getIdFromCode(string $storeCode)
    {
        $searchCriteria = $this->searchCriteriaBuilder
            ->addFilter('store_code', $storeCode)
            ->create();
        $store = current($this->getList($searchCriteria)->getItems());

        if(!$store){
            return null;
        }

        return $store->getId() ?? null;
    }

    /**
     * @param $id
     * @return null
     */
    public function getCodeById($id) {
        $searchCriteria = $this->searchCriteriaBuilder
            ->addFilter('store_id', $id)
            ->create();
        $store = current($this->getList($searchCriteria)->getItems());

        return $store->getStoreCode() ?? null;
    }

    /**
     * @param Stores $store
     * @return Stores
     */
    public function save(Stores $store): Stores
    {
        $connection = $this->resourceConnection->getConnection();
        $table = $connection->getTableName(self::TABLE_NAME);
        $storeId = $store->getId();
        $bindings = [
            StoreInterface::STORE_ID                          => $store->getStoreId(),
            StoreInterface::ENABLED                           => $store->getEnabled(),
            StoreInterface::TITLE                             => $store->getTitle(),
            StoreInterface::IMAGE                             => $store->getImage(),
            StoreInterface::LATITUDE                          => $store->getLatitude(),
            StoreInterface::LONGITUDE                         => $store->getLongitude(),
            StoreInterface::STORE_IDS                         => $store->getStoreIds(),
            StoreInterface::STREET                            => $store->getStreet(),
            StoreInterface::POSTCODE                          => $store->getPostcode(),
            StoreInterface::CITY                              => $store->getCity(),
            StoreInterface::COUNTRY                           => $store->getCountry(),
            StoreInterface::PHONE_1                           => $store->getPhone1(),
            StoreInterface::PHONE_2                           => $store->getPhone2(),
            StoreInterface::FAX                               => $store->getFax(),
            StoreInterface::EMAIL                             => $store->getEmail(),
            StoreInterface::WEBSITE_URL                       => $store->getWebsiteUrl(),
            StoreInterface::ADDITIONAL_TEXT                   => $store->getAdditionalText(),
            StoreInterface::MARKER_IMAGE                      => $store->getMarkerImage(),
            StoreInterface::GMB_CAT                           => $store->getGmbCat(),
            StoreInterface::GMB_LANGUAGE_CODE                 => $store->getGmbLanguageCode(),
            StoreInterface::GMB_LOCATION_NAME                 => $store->getGmbLocationName(),
            StoreInterface::REGION                            => $store->getRegion(),
            StoreInterface::REGION_ID                         => $store->getRegionId(),
            StoreInterface::IS_ENABLED_FOR_PICKUPINSTORE      => $store->getIsEnabledForPickupInStore(),
            StoreInterface::URL_KEY                           => $store->getUrlKey(),
            StoreInterface::STORE_CODE                        => $store->getStoreCode(),
            StoreInterface::IS_ENABLED_SHOP_DETAILS           => $store->getIsEnabledShopDetails(),
            StoreInterface::STORE_EXTERNAL_IFRAME_APPOINTMENT => $store->getStoreExternalIframeAppointment(),
            StoreInterface::ADDITIONAL_TEXT_2                 => $store->getAdditionalText2(),
            StoreInterface::STORE_FILENAME_PREFIX             => $store->getStoreFilenamePrefix(),
            StoreInterface::IS_ENABLED_FOR_RETURN_IN_STORE    => $store->getIsEnabledForReturnInStore(),
            StoreInterface::LAST_UPDATE                       => $store->getLastUpdate()
        ];

        $whereCondition = sprintf('%s = %s', Stores::STORE_ID, $storeId);

        if ($storeId && $connection->fetchOne(
                $connection
                    ->select()
                    ->from($table)
                    ->where($whereCondition)
            )) {
            $connection->update($table, $bindings, $whereCondition);

            return $store;
        }

        $connection->insert($table, $bindings);
        $store->setId($connection->lastInsertId($table));

        return $store;
    }
}
