<?php
/**
 * @author Amasty Team
 * @copyright Copyright (c) 2021 Amasty (https://www.amasty.com)
 * @package Amasty_ReviewersDiscounts
 */


declare(strict_types=1);

namespace Amasty\ReviewersDiscounts\Model\ResourceModel;

use Magento\Framework\DB\Select;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;

class Review extends AbstractDb
{
    /**
     * @var string
     */
    private $reviewTable;

    /**
     * @var string
     */
    private $reviewDetailTable;

    /**
     * @inheritDoc
     */
    protected function _construct()
    {
        $this->reviewTable = $this->getTable('review');
        $this->reviewDetailTable = $this->getTable('review_detail');
    }

    /**
     * Retrieves total reviews for customer
     *
     * @param int $customerId
     * @param bool $approvedOnly
     *
     * @return int
     */
    public function getTotalReviews($customerId, $approvedOnly = true)
    {
        $select = $this->getReviewSelect($approvedOnly)->columns([
            'review_count' => new \Zend_Db_Expr('COUNT(*)')
        ]);

        return $this->getConnection()->fetchOne($select, $this->getBindArray($customerId, $approvedOnly));
    }

    /**
     * Retrieves reviewed product ids for customer
     *
     * @param int $customerId
     * @param bool $approvedOnly
     *
     * @return array
     */
    public function getReviewedProducts($customerId, $approvedOnly = true)
    {
        $select = $this->getReviewSelect($approvedOnly)->join(
            ['product_table' => $this->getTable('catalog_product_entity')],
            'product_table.entity_id = review.entity_pk_value',
            ['product_table.sku']
        );

        return $this->getConnection()->fetchCol($select, $this->getBindArray($customerId, $approvedOnly));
    }

    /**
     * @param int $customerId
     * @param bool $approvedOnly
     *
     * @return array
     */
    private function getBindArray($customerId, $approvedOnly)
    {
        $bind = [':customer_id' => $customerId];
        if ($approvedOnly) {
            $bind[':status_id'] = \Magento\Review\Model\Review::STATUS_APPROVED;
        }

        return $bind;
    }

    /**
     * Generate select based on customer id & status
     *
     * @param bool $approvedOnly
     *
     * @return Select
     */
    private function getReviewSelect($approvedOnly)
    {
        $select = $this->getConnection()->select()->from(
            ['review' => $this->reviewTable],
            []
        )->join(
            ['detail' => $this->reviewDetailTable],
            'review.review_id=detail.review_id AND detail.customer_id = :customer_id',
            []
        );

        if ($approvedOnly) {
            $select->where('review.status_id = :status_id');
        }

        return $select;
    }
}
