<?php

namespace Autogedal\CategoryReviews\ViewModel;

use Magento\Catalog\Model\Layer\Resolver;
use Autogedal\CategoryReviews\Helper\Data;
use Magento\Framework\Pricing\Helper\Data as PriceHelper;
use Autogedal\CategoryReviews\Model\CategoryReviewsBackendLogic;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\App\CacheInterface;
use Magento\Framework\App\ResourceConnection;

class CustomHelper implements \Magento\Framework\View\Element\Block\ArgumentInterface
{
    protected $resource;
    protected $storeManager;
    protected $categoryReviewsBackendLogic;
    protected $priceHelper;
    protected $cache;
    
    /**
     * @var  Layer
     */
    protected $layer;
    
    /**
     * @var Resolver
     */
    private $layerResolver;

    public function __construct(
        Resolver $layerResolver,
        PriceHelper $priceHelper,
        CategoryReviewsBackendLogic $categoryReviewsBackendLogic,
        StoreManagerInterface $storeManager,
        CacheInterface $cache,
        ResourceConnection $resource
    ) {
        $this->resource = $resource;
        $this->priceHelper = $priceHelper;
        $this->layerResolver = $layerResolver;
        $this->categoryReviewsBackendLogic = $categoryReviewsBackendLogic;
        $this->storeManager = $storeManager;
        $this->cache = $cache;
    }

    public function getCategoryReviewData($categoryId, $storeId = null)
    {
        if ($storeId === null) {
            $storeId = $this->storeManager->getStore()->getId();
        }

        $cacheKey = Data::CACHE_TAG . '_' . $categoryId . '_' . $storeId;
        
        $cachedData = $this->cache->load($cacheKey);
        if ($cachedData) {
            return json_decode($cachedData, true);
        }

        $connection = $this->resource->getConnection();
        $tableName = $this->resource->getTableName('category_reviews_aggregate');
        
        $select = $connection->select()
            ->from($tableName)
            ->where('category_id = ?', $categoryId)
            ->where('store_id = ?', $storeId);

        $data = $connection->fetchRow($select);

        if ($data) {
            $this->cache->save(
                json_encode($data),
                $cacheKey,
                [Data::CACHE_TAG],
                Data::CACHE_LIFETIME
            );
        }

        return $data ?: null;
    }

    /**
     * @return \Magento\Catalog\Model\Category
     */
    public function getCurrentCategory()
    {
        $currentCategory = $this->getLayer()->getCurrentCategory();
        if ($currentCategory && $currentCategory->getParentCategory()->getLevel() > 1) {
            return $currentCategory->getParentCategory();
        }
        return $currentCategory;
    }

    /**
     * @return Layer
     */
    private function getLayer()
    {
        if (!$this->layer) {
            $this->layer = $this->layerResolver->get();
        }
        return $this->layer;
    }
    
    /**
     * Get rating summary
     *
     * @return float
     */
    public function getRatingSummary()
    {
        $currentCategoryId = $this->getCurrentCategory()->getId();
        $reviewsData = $this->getCategoryReviewData($currentCategoryId);

        if ($reviewsData && isset($reviewsData['avg_rating'])) {
            return $reviewsData['avg_rating'];
        }
        return 0;
    }

    /**
     * Get count of reviews
     *
     * @return int
     */
    public function getReviewsCount()
    {
        $currentCategoryId = $this->getCurrentCategory()->getId();
        $reviewsData = $this->getCategoryReviewData($currentCategoryId);

        if ($reviewsData && isset($reviewsData['review_count'])) {
            return $reviewsData['review_count'];
        }
        return 0;
    }

    public function getCategoryPriceStatsFromOpenSearch()
    {
        return $this->categoryReviewsBackendLogic->getCategoryPriceStatsFromOpenSearch($this->getCurrentCategory());
    }

    public function getFormatedPrice($price)
    {
        $roundedPrice = round($price, 2);
        return $this->priceHelper->currency($roundedPrice, false, false);
    }
}
