<?php
/**
 * @author  Magediary
 * @package Magediary_ProductQuestion
 */

namespace Magediary\ProductQuestion\Observer;

use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Catalog\Model\Product as CatalogProduct;

class ModelSaveAfter
{
    /**
     * Catalog product model
     *
     * @var \Magento\Catalog\Api\ProductRepositoryInterface
     */
    protected $productRepository;

    /**
     * @var \Magento\Framework\Event\ManagerInterface
     */
    protected $_eventManager;

    /**
     * @var Resource
     * .
     */
    private $resource;

    /**
     * @var \Magento\Framework\DB\Adapter\AdapterInterface
     */
    private $connection;

    /**
     * Email model
     *
     * @var \Magediary\ProductQuestion\Model\Email\MailQuestionInterface
     */
    protected $mailQuestion;

    /**
     * @var \Magediary\ProductQuestion\Model\Email\MailAnswerInterface
     */
    protected $mailAnswer;

    /**
     * @var \Magediary\ProductQuestion\Api\AnswerRepositoryInterface
     */
    protected $answerRepository;

    /**
     * @param \Magento\Framework\App\ResourceConnection $resource
     * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
     * @param \Magento\Framework\Event\ManagerInterface $eventManager
     * @param \Magediary\ProductQuestion\Model\Email\MailQuestionInterface $mailQuestion
     * @param \Magediary\ProductQuestion\Model\Email\MailAnswerInterface $mailAnswer
     * @param \Magediary\ProductQuestion\Api\AnswerRepositoryInterface $answerRepository
     */
    public function __construct(
        \Magento\Framework\App\ResourceConnection $resource,
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
        \Magento\Framework\Event\ManagerInterface $eventManager,
        \Magediary\ProductQuestion\Model\Email\MailQuestionInterface $mailQuestion,
        \Magediary\ProductQuestion\Model\Email\MailAnswerInterface $mailAnswer,
        \Magediary\ProductQuestion\Api\AnswerRepositoryInterface $answerRepository
    ) {
        $this->resource = $resource;
        $this->connection = $resource->getConnection();
        $this->productRepository = $productRepository;
        $this->_eventManager = $eventManager;
        $this->mailQuestion = $mailQuestion;
        $this->mailAnswer = $mailAnswer;
        $this->answerRepository = $answerRepository;
    }

    /**
     * Load product model with data by passed id.
     *
     * Return false if product was not loaded or has incorrect status.
     *
     * @param int $productId
     * @return bool|CatalogProduct
     */
    protected function loadProduct($productId)
    {
        if (!$productId) {
            return false;
        }

        try {
            $product = $this->productRepository->getById($productId);
        } catch (NoSuchEntityException $noEntityException) {
            return false;
        }

        return $product;
    }

    /**
     * Return validated table name
     *
     * @param string|string[] $table
     * @return string
     */
    private function getTable($table)
    {
        return $this->resource->getTableName($table);
    }

    /**
     * Get ids to which specified item is assigned
     *
     * @param  int $questionId
     * @return array
     */
    protected function _lookupIds($questionId)
    {
        $tableName = $this->getTable('magediary_question_product');

        $select = $this->connection->select()->from(
            $tableName,
            'product_id'
        )->where(
            'question_id = ?',
            (int)$questionId
        );

        return $this->connection->fetchCol($select);
    }

    /**
     * Refresh product(s) cache assigned to the question
     *
     * @param int $questionId
     * @return void
     */
    public function refreshProductCache($questionId)
    {
        $products = $this->_lookupIds($questionId);
        if (count($products)) {
            foreach ($products as $productId) {
                $this->refreshCache($productId);
            }
        }
    }

    /**
     * Refresh product cache by id
     *
     * @param int $productId
     * @return void
     */
    public function refreshCache($productId)
    {
        $product = $this->loadProduct($productId);
        if ($product) {
            $this->_eventManager->dispatch('clean_cache_by_tags', ['object' => $product]);
        }
    }
}
