<?php

namespace CouponsPlus\App\Coupon\Attributes;

use CouponsPlus\App\Coupon\Attributes\Abilities\AttributeData;
use CouponsPlus\App\Coupon\Attributes\Abilities\MatchableAttribute;
use CouponsPlus\app\coupon\attributes\abilities\AttributeValueData;
use CouponsPlus\app\coupon\attributes\abilities\AttributeMatcherInterface;

class AttributeMatcher implements AttributeMatcherInterface
{

    /**
     * @var MatchableAttribute
     */
    protected $attributeToMatch;

    public function __construct(MatchableAttribute $attributeToMatch)
    {
        $this->attributeToMatch = $attributeToMatch;
    }

    public function matches(AttributeValueData $attributeValue): bool
    {
        //lets first make sure the attribute name we are trying to match is the same type as the one we are trying to match
        if ($this->attributeToMatch->getData()->getKey()->isNot($attributeValue->getAttribute()->getKey())) {
            return false;
        }

        switch ($this->attributeToMatch->getType()->get()) {
            case 'any':
                return true;
            case 'allowed':
                return $this->matchOnly($attributeValue);
            case 'excluded':
                return $this->matchAnyExcept($attributeValue);
        }
        return false;
    }

    protected function matchOnly(AttributeValueData $valueToCheck): bool
    {
        return $this->hasValue($valueToCheck);
    }

    protected function matchAnyExcept(AttributeValueData $valueToCheck): bool
    {
        return !$this->hasValue($valueToCheck);
    }

    /**
     * @param AttributeValueData $valueToCheck
     * @return bool
     */
    protected function hasValue(AttributeValueData $valueToCheck): bool
    {
        return (bool) $this->attributeToMatch->getData()->getValues()->find(
            function (AttributeValueData $value) use ($valueToCheck) {
                return $value->getId() === $valueToCheck->getId();
            }
        );
    }
}