<?php
namespace OFFLINE\SiteSearch\Classes\Providers;

use Cms\Classes\Controller;
use Illuminate\Database\Eloquent\Collection;
use OFFLINE\SiteSearch\Classes\Result;
use OFFLINE\SiteSearch\Models\Settings;
use OFFLINE\SnipcartShop\Models\GeneralSettings;
use OFFLINE\SnipcartShop\Models\Product;

/**
 * Searches the contents generated by the
 * OFFLINE.SnipcartShop plugin
 *
 * @package OFFLINE\SiteSearch\Classes\Providers
 */
class OfflineSnipcartShopResultsProvider extends ResultsProvider
{
    /**
     * Runs the search for this provider.
     *
     * @return ResultsProvider
     */
    public function search()
    {
        if ( ! $this->isInstalledAndEnabled()) {
            return $this;
        }

        foreach ($this->products() as $product) {
            // Make this result more relevant, if the query is found in the name
            $relevance   = mb_stripos($product->name, $this->query) === false ? 1 : 2;
            $description = $product->description_short ?: $product->description;

            $result        = new Result($this->query, $relevance);
            $result->title = $product->name;
            $result->text  = $description;
            $result->url   = $this->getUrl($product);
            $result->thumb = $product->image;
            $result->model = $product;
            $result->meta  = [
                'price' => $product->price,
            ];

            $this->addResult($result);
        }

        return $this;
    }

    /**
     * Get all products with matching title or content.
     *
     * @return Collection
     */
    protected function products()
    {
        return Product::published()->with(['main_image', 'images'])
                      ->where('name', 'like', "%{$this->query}%")
                      ->orWhere('description', 'like', "%{$this->query}%")
                      ->orWhere('description_short', 'like', "%{$this->query}%")
                      ->orWhere('meta_title', 'like', "%{$this->query}%")
                      ->orWhere('meta_description', 'like', "%{$this->query}%")
                      ->orderBy('updated_at', 'desc')
                      ->get();
    }

    /**
     * Checks if the OFFLINE.SnipcartShop Plugin is installed and
     * enabled in the config.
     *
     * @return bool
     */
    protected function isInstalledAndEnabled()
    {
        return $this->isPluginAvailable($this->identifier)
            && Settings::get('snipcartshop_products_enabled', true);
    }

    /**
     * Generates the url to a shop product.
     *
     * @param $product
     *
     * @return string
     */
    protected function getUrl($product)
    {
        $page = GeneralSettings::get('product_page');

        return (new Controller())->pageUrl($page, ['slug' => $product->slug]);
    }

    /**
     * Display name for this provider.
     *
     * @return mixed
     */
    public function displayName()
    {
        return Settings::get(
            'snipcartshop_products_label',
            trans('offline.sitesearch::lang.settings.snipcartshop_itemurl_badge')
        );
    }

    /**
     * Returns the plugin's identifier string.
     *
     * @return string
     */
    public function identifier()
    {
        return 'OFFLINE.SnipcartShop';
    }

}
