<?php
/**
 * Badges resource model
 *
 * @module Autogedal_Badges
 * @author Malith Priyashan
 * @package Autogedal\Badges\Model\ResourceModel
 * @licence OSL 3.0
 */

namespace Autogedal\Badges\Model\ResourceModel;

use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
use Magento\Framework\Model\ResourceModel\Db\Context;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Stdlib\DateTime\DateTime;
use Magento\Framework\Model\AbstractModel;
use Magento\Framework\DB\Select;
use Autogedal\Badges\Model\Badge as BadgeModel;

/**
 * Class Badge
 */
class Badge extends AbstractDb
{
    /**
     * @var DateTime
     */
    protected $_date;

    /**
     * Construct
     *
     * @param DateTime $date
     * @param Context $context
     * @param string|null $resourcePrefix
     */
    public function __construct(
        DateTime $date,
        Context $context,
        $resourcePrefix = null
    ) {
        $this->_date = $date;

        parent::__construct($context, $resourcePrefix);
    }

    /**
     * Initialize resource model
     *
     * @return void
     */
    protected function _construct()
    {
        $this->_init('autogedal_badges_badge', 'badge_id');
    }

    /**
     * Process Badge data before saving
     *
     * @param AbstractModel $object
     *
     * @return AbstractDb
     *
     * @throws LocalizedException
     */
    protected function _beforeSave(AbstractModel $object)
    {
        if (!$this->isValidBadgeUrlKey($object)) {
            throw new LocalizedException(
                __('The Badge URL key contains capital letters or disallowed symbols.')
            );
        }

        if ($this->isNumericBadgeUrlKey($object)) {
            throw new LocalizedException(
                __('The Badge URL key cannot be made of only numbers.')
            );
        }

        if ($object->isObjectNew() && !$object->hasCreationTime()) {
            $object->setCreationTime($this->_date->gmtDate());
        }

        $object->setUpdateTime($this->_date->gmtDate());

        return parent::_beforeSave($object);
    }

    /**
     * Load an object using 'url_key' field if there's no field specified and value is not numeric
     *
     * @param AbstractModel $object
     * @param mixed $value
     * @param string $field
     *
     * @return AbstractDb
     */
    public function load(AbstractModel $object, $value, $field = null)
    {
        if (!is_numeric($value) && is_null($field)) {
            $field = 'url_key';
        }

        return parent::load($object, $value, $field);
    }

    /**
     * Retrieve select object for load object data
     *
     * @param string $field
     * @param mixed $value
     * @param BadgeModel $object
     *
     * @return \Zend_Db_Select
     */
    protected function _getLoadSelect($field, $value, $object)
    {
        $select = parent::_getLoadSelect($field, $value, $object);

        if ($object->getStoreId()) {
            $select->where(
                'is_active = ?',
                1
            )->limit(
                1
            );
        }

        return $select;
    }

    /**
     * Retrieve load select with filter by url_key and activity
     *
     * @param string $url_key
     * @param int $isActive
     *
     * @return Select
     */
    protected function _getLoadByUrlKeySelect($url_key, $isActive = null)
    {
        $select = $this->getConnection()->select()->from(
            ['bp' => $this->getMainTable()]
        )->where(
            'bp.url_key = ?',
            $url_key
        );

        if (!is_null($isActive)) {
            $select->where('bp.is_active = ?', $isActive);
        }

        return $select;
    }

    /**
     * Check whether Badge url key is numeric
     *
     * @param \Magento\Framework\Model\AbstractModel $object
     *
     * @return bool
     */
    protected function isNumericBadgeUrlKey(AbstractModel $object)
    {
        return preg_match('/^[0-9]+$/', $object->getData('url_key'));
    }

    /**
     * Check whether badge url key is valid
     *
     * @param AbstractModel $object
     *
     * @return bool
     */
    protected function isValidBadgeUrlKey(AbstractModel $object)
    {
        return preg_match('/^[a-z0-9][a-z0-9_\/-]+(\.[a-z0-9_-]+)?$/', $object->getData('url_key'));
    }

    /**
     * Check if badge url key exists
     * return badge_id if badge exists
     *
     * @param string $url_key
     *
     * @return int
     */
    public function checkUrlKey($url_key)
    {
        $select = $this->_getLoadByUrlKeySelect($url_key, 1);
        $select->reset(\Zend_Db_Select::COLUMNS)->columns('bp.badge_id')->limit(1);

        return $this->getConnection()->fetchOne($select);
    }
}
