<?php
/**
 * @author Amasty Team
 * @copyright Copyright (c) Amasty (https://www.amasty.com)
 * @package Free Gift Base for Magento 2
 */

namespace Amasty\Promo\Plugin\Tax\Model\Sales\Total\Quote;

use Amasty\Promo\Model\Config;
use Amasty\Promo\Model\Config\Source\GiftRepresentationMode;
use Magento\Quote\Model\Quote\Item\AbstractItem;
use Amasty\Promo\Model\Storage;
use Magento\Tax\Model\Sales\Total\Quote\CommonTaxCollector as TaxCollector;
use Magento\Tax\Model\Sales\Quote\ItemDetails;

/**
 * Tax apply for Promo Item
 */
class CommonTaxCollector
{
    /**
     * @var \Amasty\Promo\Helper\Item
     */
    private $helperItem;

    /**
     * @var \Amasty\Promo\Model\ResourceModel\Rule
     */
    private $ruleResource;

    /**
     * @var \Magento\Checkout\Model\Session
     */
    private $checkoutSession;

    /**
     * @var AbstractItem
     */
    private $item;

    /**
     * @var array
     */
    protected $appliedTax = [];

    /**
     * @var Config
     */
    private $configProvider;

    public function __construct(
        \Amasty\Promo\Helper\Item $helperItem,
        \Amasty\Promo\Model\ResourceModel\Rule $ruleResource,
        \Magento\Checkout\Model\Session $resourceSession,
        Config $configProvider
    ) {
        $this->checkoutSession = $resourceSession;
        $this->helperItem = $helperItem;
        $this->ruleResource = $ruleResource;
        $this->configProvider = $configProvider;
    }

    /**
     * @param TaxCollector $subject
     * @param \Magento\Tax\Api\Data\QuoteDetailsItemInterfaceFactory $itemDataObjectFactory
     * @param AbstractItem $item
     * @param $priceIncludesTax
     * @param $useBaseCurrency
     * @param null $parentCode
     * @return array
     */
    public function beforeMapItem(
        TaxCollector $subject,
        \Magento\Tax\Api\Data\QuoteDetailsItemInterfaceFactory $itemDataObjectFactory,
        AbstractItem $item,
        $priceIncludesTax,
        $useBaseCurrency,
        $parentCode = null
    ) {
        $this->item = $item;

        if ($this->isApplyTaxToFreeGift()) {
            $this->item->setNotUsePricePlugin(true);

            $this->item->setBasePrice($this->item->getProduct()->getPrice());
            $this->item->setPrice($this->item->getProduct()->getPrice());

            $this->item->setNotUsePricePlugin(false);

            $this->item->setCalculationPrice(null);
            $this->item->setBaseCalculationPrice(null);
            $this->item->setConvertedPrice(null);
        }

        return [$itemDataObjectFactory, $this->item, $priceIncludesTax, $useBaseCurrency, $parentCode];
    }

    /**
     * @param TaxCollector $subject
     * @param ItemDetails $result
     * @return mixed
     */
    public function afterMapItem(
        TaxCollector $subject,
        $result
    ) {
        // skip processing rule if Magento tax logic is set in Presentation mode
        if ($this->configProvider->getGiftRepresentationMode() === GiftRepresentationMode::SHOW_FULL_PRICE) {
            return $result;
        }
        if ($this->isApplyTaxToFreeGift()) {
            Storage::$cachedFreeGiftsWithTax[$result->getCode()] = $this->item->getSku();
        }

        return $result;
    }

    /**
     * @return bool
     */
    private function isApplyTaxToFreeGift()
    {
        $fullDiscountItems = $this->checkoutSession->getAmpromoFullDiscountItems();
        $itemSku = $this->helperItem->getItemSku($this->item);

        if (isset($fullDiscountItems[$itemSku]['rule_ids'])
            && $this->helperItem->isPromoItem($this->item)
        ) {
            if (!isset($this->appliedTax[$itemSku])) {
                $this->appliedTax[$itemSku] = $this->ruleResource->isApplyTax($fullDiscountItems[$itemSku]['rule_ids']);
            }

            return (bool)$this->appliedTax[$itemSku];
        }

        return false;
    }
}
