<?php
namespace Buttonizer\Frontend\PageRules\Rule;

use Buttonizer\Frontend\Buttonizer;

/**
 * Class Schedule
 * This file is a part of Buttonizer
 * Please do not redistribute without any written commitment
 *
 * Copyrights 2019 www.buttonizer.pro
 */
class Rule
{
    private $calculated = false;
    private $isTriggered = false;
    private $data = [];

    // Data
    private $allConditionsMustBeTrue = true;

    // Amount of triggered rules
    private $triggeredRules = 0;
    private $amountOfRules = -1;

    /**
     * Schedule constructor.
     * @param $data
     */
    public function __construct($data = [])
    {
        $this->data = $data;
    }

    /**
     * Do we need to show this button?
     * Only execute when a button has been attached to this page rule
     *
     * @return bool
     */
    public function calculate()
    {
        // Cache the calculated
        if($this->calculated) {
            return $this->isTriggered;
        }

        $this->allConditionsMustBeTrue = ($this->data['type'] === 'and');
        $this->amountOfRules = isset($this->data['rules']) ? count($this->data['rules']) : 0;

        if($this->amountOfRules > 0) {
            $this->goThrough();
        }

        return $this->isTriggered;
    }

    /**
     * Rule matched, show!
     * @param $triggered
     * @return bool
     */
    private function result($triggered)
    {
        $this->calculated = true;
        $this->isTriggered = $triggered;
        return true;
    }

    private function goThrough()
    {
        foreach($this->data['rules'] as $ruleData)
        {
            // Ignore this rule as it has no value
            if(empty($ruleData['value'])) {
                $this->amountOfRules--; // It's not a valid rule
                continue;
            }

            // Page
            if($ruleData['type'] == 'page')
            {
                if(!in_array(Buttonizer::getPage(), $ruleData['value']))
                {
                    continue;
                }
            }

            // Page title
            else if($ruleData['type'] == 'page_title')
            {
                if(strpos(Buttonizer::getTitle(), strtolower($ruleData['value'])) === false) {
                    continue;
                }
            }

            // Blog
            else if($ruleData['type'] == 'blog' && !Buttonizer::isFrontPage())
            {
                if(!in_array(Buttonizer::getPage(), $ruleData['value'])) {
                    continue;
                }
            }

            // Blog
            else if($ruleData['type'] == 'blog_title' && !Buttonizer::isFrontPage())
            {
                if(strpos(Buttonizer::getTitle(), strtolower($ruleData['value'])) === false) {
                    continue;
                }
            }

            else if($ruleData['type'] == 'category' && !Buttonizer::isFrontPage())
            {
                $count = 0;

                $categories = Buttonizer::getCategories();

                for($i = 0; $i < count($categories); $i++) {
                    if(in_array($categories[$i], $ruleData['value'])) {
                        $count++;
                    }
                }

                if($count == 0) {
                    continue;
                }
            }

            else if($ruleData['type'] == 'url_contains')
            {
                if(!strpos(Buttonizer::getUrl(), $ruleData['value'])) {
                    continue;
                }
            }

            else if($ruleData['type'] == 'url_starts')
            {
                // Something with http, https?
                if(stripos($ruleData['value'], 'http') === false) {
                    $ruleData['value'] = (substr($ruleData['value'], 0, 1) !== '/' ? '/' : '') . $ruleData['value'];
                }

                // Based on a full url?
                $fullUrl = substr($ruleData['value'], 0, 1) !== '/';

                if($ruleData['value'] !== substr(Buttonizer::getUrl($fullUrl), 0, strlen($ruleData['value']))) {
                    continue;
                }
            }

            else if($ruleData['type'] == 'url_ends')
            {
                $ruleData['value'] = $ruleData['value'] . (substr($ruleData['value'], -1) !== '/' ? '/' : '');

                if($ruleData['value'] !== substr(Buttonizer::getUrl(), strlen(Buttonizer::getUrl()) - strlen($ruleData['value']))) {
                    continue;
                }
            }

            else if($ruleData['type'] == 'user_roles')
            {
                // If 1 of the selected user roles is one of current user's role, trigger
                if(empty(array_intersect(Buttonizer::getUserRoles(), $ruleData["value"]))){
                    continue;
                }
            }

            else{
                // UNKNOWN, just slam the door
                continue;
            }

            $this->triggeredRules++;
        }

        // Check triggered
        if($this->allConditionsMustBeTrue)
        {
            // YES! All rules are triggered :D
            if($this->triggeredRules === $this->amountOfRules)
            {
                $this->result(true);
            }else{
                // No, they are not... Not triggered!
                $this->result(false);
            }
        }
        else
        {
            // Is at least one rule triggered?
            if($this->triggeredRules >= 1) {
                $this->result(true);
            }else{ // Nooo.... Not triggered!
                $this->result(false);
            }
        }
    }
}