<?php

namespace Widgets;

use Twig_Environment;
use Widgets\Jquery\Jmask\Jmask;
use \Widgets\TemplateInterface;

abstract class Widget
{

    /**
     * @var TemplateInterface
     */
    protected $template;

    /**
     * @var \Twig_Environment
     */
    protected $twig;

    protected $baseVersionLibrary;

    /**
     * Widget constructor.
     * @param TemplateInterface $template
     * @param \Twig_Environment $twig
     */
    function __construct(TemplateInterface $template, \Twig\Environment $twig)
    {
        $this->template = $template;
        $this->twig = $twig;
    }

    /**
     * @return array
     */
    protected abstract function stableVersions(): array;

    /**
     * @param string $verJQeury
     * @return Jmask
     */
    public function setVerJQeury(string $verJQeury)
    {
        if (!$this->validateVersions($verJQeury)) {
            throw new \Exception(sprintf("version `%s` not valid for ".static::class, $verJQeury));
        }

        $this->baseVersionLibrary = $verJQeury;

        return $this;
    }

    /**
     * @param string $version
     * @return bool
     */
    protected function validateVersions(string $version): bool
    {
        $versions = $this->stableVersions();
        return in_array($version,$versions);
    }

    /**
     * @return bool
     */
    public function ajax_query(): bool
    {
        if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && !empty($_SERVER['HTTP_X_REQUESTED_WITH']) &&
            strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
            return TRUE;
        } else {
            return FALSE;
        }

    }


    /**
     * @return array
     */
    abstract function getJsLinks(): array;

    /**
     * @return array
     */
    abstract function getCssLinks(): array;


    /**
     * @param string $view
     * @return string
     * @throws \ReflectionException
     * @throws \Twig\Error\LoaderError
     * @throws \Twig\Error\RuntimeError
     * @throws \Twig\Error\SyntaxError
     */
    function render(string $view = 'default')
    {

        $this->loadResourse();

        $ref = new \ReflectionClass($this);
        $tpl = (new \SplFileInfo($ref->getFileName()))->getPath();

        $this->twig->getLoader()->prependPath($tpl);

        $html = $this->twig->render($view . '.twig', $this->getParams());

        if (preg_match('~(<script type\=\"text\/javascript\">.*?<\/script>)~is', $html, $m)) {
            $html = str_replace($m[1], '', $html);
            $this->template->addScript($m[1]);
        }

        return $html;
    }

    /**
     * Загрузка ресурсов
     */
    private function loadResourse(): void
    {

        foreach ($this->getJsLinks() as $link){
            $currentFind = $templateFind =  null;
            //current find
            $fileName = preg_replace('~.*\/(.*?)$~','$1',$link);
            $currentFind = in_array($fileName,$this->stableVersions());

            //template find
            foreach ($this->template->getScripts() as $templateLink){
                $fileNameWiget = preg_replace('~.*\/(.*?)$~','$1',$templateLink);

                $templateFind = in_array($fileNameWiget,$this->stableVersions());
                break;
            }

            //уже есть в шаблоне
            if($currentFind===true && $templateFind===true){
                continue;
            }
            $this->template->addScriptLink($link);
        }


        $this->template->addStyleLinks($this->getCssLinks());
    }

    /**
     * @return string
     */
    protected function getUrlAjax(): string
    {
        return '/' . uri_string();
    }

    /**
     * @return array
     * @throws \ReflectionException
     */
    protected function getParams(): array
    {

        $class = new \ReflectionClass(get_class($this));

        $data = [];

        foreach ($class->getProperties(\ReflectionProperty::IS_PROTECTED) as $prop) {
            $data[$prop->name] = $this->{$prop->name};
        }

        return $data;
    }
}
