<?php

namespace Dotdigitalgroup\Email\Plugin;

use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\SalesRule\Api\CouponRepositoryInterface;
use Magento\SalesRule\Model\Coupon;
use Magento\SalesRule\Model\Utility;
use Magento\SalesRule\Model\Rule;
use Magento\Quote\Model\Quote\Address;

class CouponExpiredPlugin
{
    /**
     * @var CouponRepositoryInterface
     */
    private $couponRepository;

    /**
     * @var SearchCriteriaBuilder
     */
    private $criteriaBuilder;

    /**
     * @var TimezoneInterface
     */
    private $timezone;

    /**
     * @param CouponRepositoryInterface $couponRepository
     * @param SearchCriteriaBuilder $criteriaBuilder
     * @param TimezoneInterface $timezone
     */
    public function __construct(
        CouponRepositoryInterface $couponRepository,
        SearchCriteriaBuilder $criteriaBuilder,
        TimezoneInterface $timezone
    ) {
        $this->couponRepository = $couponRepository;
        $this->criteriaBuilder = $criteriaBuilder;
        $this->timezone = $timezone;
    }

    /**
     * Check whether a coupon code was generated by Dotdigital, and if it has expired
     *
     * @param Utility $utility
     * @param bool $result
     * @param Rule $rule
     * @param Address $address
     * @return bool
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function afterCanProcessRule(Utility $utility, bool $result, Rule $rule, Address $address)
    {
        if ($result
            && $rule->getCouponType() == Rule::COUPON_TYPE_SPECIFIC
            && (bool) $rule->getUseAutoGeneration()
            && !$rule->getToDate()
            && $couponCode = $address->getQuote()->getCouponCode()
        ) {
            $couponSearchResult = $this->couponRepository
                ->getList($this->criteriaBuilder->addFilter('code', $couponCode)->create())
                ->getItems();

            if (empty($couponSearchResult)) {
                return $result;
            }

            /** @var Coupon $coupon */
            $coupon = reset($couponSearchResult);
            if (!(bool) $coupon->getGeneratedByDotmailer()) {
                // not a dotdigital coupon
                return $result;
            }

            if ($ddgExtensionAttributes = $coupon->getExtensionAttributes()->getDdgExtensionAttributes()) {
                $expiresAt = $ddgExtensionAttributes->getExpiresAt();
                if ($expiresAt && $this->timezone->date($expiresAt) < $this->timezone->date()) {
                    // individual coupon has expired
                    $rule->setIsValidForAddress($address, false);
                    return false;
                }
            }
        }

        return $result;
    }
}
