<?php
namespace Grav\Plugin;

use Grav\Common\Page\Page;
use Grav\Common\Page\Pages;
use Grav\Common\Plugin;
use Grav\Common\Uri;
use Symfony\Component\EventDispatcher\Event;

/**
 * Features:
 * - /sync   Cheap git-sync (did not knew about it at the time)
 * - /polyglot/<page-path>
 * - /lessons/<lesson-slug>
 *
 * The way GRAV works to define new routes is to listen to the onPageNotFound event.
 * This is expected to evolve as GRAV integrates more and more with Symfony components.
 *
 * Class M3P2Plugin
 * @package Grav\Plugin
 */
class M3P2Plugin extends Plugin
{
    /**
     * @return array
     *
     * The getSubscribedEvents() gives the core a list of events
     *     that the plugin wants to listen to. The key of each
     *     array section is the event that the plugin listens to
     *     and the value (in the form of an array) contains the
     *     callable (or function) as well as the priority. The
     *     higher the number the higher the priority.
     */
    public static function getSubscribedEvents()
    {
        return [
            'onPluginsInitialized' => ['onPluginsInitialized', 0]
        ];
    }

    /**
     * Initialize the plugin
     */
    public function onPluginsInitialized()
    {
        // Don't proceed if we are in the admin plugin
        if ($this->isAdmin()) {
            return;
        }

        $uri = $this->grav['uri'];
        $current_route = $uri->path();

        // /sync
        $route_sync = $this->config->get('plugins.m3-p2.routes.sync');
        if ($route_sync && $route_sync == $current_route) {
            $this->enable([
                'onPageInitialized' => ['onSyncPageInitialized', 0]
            ]);
        }

        $this->enable([
            'onTwigInitialized' => ['setupWebIdeUrl', 0],
        ]);

//        $that_page_route = $uri->query('page');
//        if ($that_page_route) {
//            $this->enable([
//                'onPageNotFound' => ['setupQueryPage', 0],
//            ]);
//        }

        $priority = 1; // must be higher than the error plugin's

        $this->enable([
            'onPageNotFound' => ['perhapsDisplayPolyglotColumns', $priority],
        ]);

        $this->enable([
            'onPageNotFound' => ['perhapsDisplayLessonColumns', $priority],
        ]);

//        if ("" == $current_route) {
//            $this->enable([
//                'onPageInitialized' => ['onSyncPageInitialized', 0]
//            ]);
//        }

    }

    /**
     * Sync with the sources.
     */
    public function onSyncPageInitialized()
    {
        // shell cwd is project root

        $out = "Opening a fortune cookie…\n\n\n";
//        $out .= shell_exec("fortune | cowsay -e Oø -f dragon") . "\n";
        $out .= shell_exec("fortune") . "\n\n";

        $out .= "Trying to sync content with GitLab…\n\n\n";
        $out .= shell_exec("cd user/pages && git pull --rebase --autostash origin master 2>&1") . "\n";

        $out .= "Done.";

        die("<pre>".$out."</pre>");  // This is all I could find to write to the page.
    }

    public function setupWebIdeUrl()
    {
        $this->grav['twig']->twig()->addFilter(
            new \Twig_SimpleFilter('webide_url', [$this, 'getWebIdeUrlForPage'])
        );
        $this->grav['twig']->twig()->addFilter(
            new \Twig_SimpleFilter('translations', [$this, 'getTranslationsOfPage'])
        );
    }

//    public function setupQueryPage()
//    {
//        $that_page_route = $this->grav['uri']->query('page');
////        die($that_page_route);
//        var_dump($that_page_route);
//        $that_page = $this->grav['pages']->find($that_page_route);
//        var_dump($that_page);
//        $this->grav['twig']->twig()->addGlobal(
//            'that_page', $that_page
//        );
//    }

    public function getWebIdeUrlForPage(Page $page)
    {
        $url = "https://m3p2.ljbac.com/-/ide/project/m3p2/courses/edit/master/-/";  # todo: move to YAML config
        $url .= substr($page->filePathClean(), 11); // 11==strlen('/user/pages')

        return $url;
    }

//    public function getPage($route)
//    {
//        $page = null;
////        $translation_path = $page->path() . DS . $page_name_without_ext . '.' . $language . '.md';
//        if (file_exists($translation_path)) {
//            $page = new Page();
//            $page->init(new \SplFileInfo($page_path), $language . '.md');
//        }
//
//        return $page;
//    }

    public function getTranslationsOfPage(Page $page)
    {
        $languages = $this->config->get('system.languages.supported');
//        die(print_r($languages));
        $route_suffix = $page->rawRoute();
        $translations = array();
        $current_language = $page->language();

        $page_name_without_ext = substr($page->name(), 0, -(strlen($page->extension())));
        foreach ($languages as $language) {
//            $route = '/' . $language . $route_suffix;
//            $route = $route_suffix;

            // Nope. language-selector does this the hard way, by instantiating Page objects
            //$translation = $page->find($route);

            // … so we're falling back on the old school too
            $translation_path = $page->path() . DS . $page_name_without_ext . '.' . $language . '.md';
            if ( ! file_exists($translation_path)) {
                continue;
            }
            $translation = new Page();
            $translation->init(new \SplFileInfo($translation_path), $language . '.md');

            if ($language == $current_language) {
                array_unshift($translations, $translation);
            } else {
                array_push($translations, $translation);
            }
        }

        return $translations;
    }

    public function perhapsDisplayPolyglotColumns(Event $event)
    {
        /** @var Uri $uri */
        $uri = $this->grav['uri'];
//        var_dump($uri); // best doc ftw

        if ("polyglot" != $uri->paths(0)) {
            return; // perhaps not
        }

        /** @var Pages $pages */
        $pages = $this->grav['pages'];

        $that_page_route = "/" . join("/", array_slice($uri->paths(), 1));

        $target_page = $pages->find($that_page_route, true);

        if ( ! $target_page) {
            return;
        }

        $this->grav['twig']->twig()->addGlobal('target_page', $target_page);
        $this->grav['twig']->twig()->addGlobal('disable_multilingual', true);

        $page = new Page;
        $page->init(new \SplFileInfo(__DIR__ . '/pages/polyglot-columns.md'));

        // here: perhaps add a title and other metadata

        $event->page = $page;
        $event->stopPropagation();
    }

    public function perhapsDisplayLessonColumns(Event $event)
    {
        /** @var Uri $uri */
        $uri = $this->grav['uri'];
//        var_dump($uri); // best doc ftw

        if ("lessons" != $uri->paths(0)) {
            return; // perhaps not
        }

        /** @var Pages $pages */
        $pages = $this->grav['pages'];

        if (count($uri->paths()) < 2) {
            // user is toying with URI, probably
            // idea: display an index of the lessons here todo
            return;
        }

        $lesson_slug = $uri->paths(1);

        // VERY inefficient : TODO: cache this
//        $target_pages = $pages->all()->filter(function ($p) use ($lesson_slug) {
        $target_pages = array_filter($pages->instances(), function (Page $p) use ($lesson_slug) {

            $page_config = $p->header();
            if ( ! isset($page_config->lessons) || empty($page_config->lessons)) {
                return false;
            }

            foreach ($page_config->lessons as $lesson) {
//                print("Checking lesson $lesson"."<br>\n");
//                if ($lesson_slug == $lesson) {
                if ($lesson_slug == $lesson['slug']) {
                    return true; // yay, this page is part of the lesson
                }
            }

            return false;
        });

        usort($target_pages, function (Page $a, Page $b) use ($lesson_slug) {
            $la = 0;
            $lb = 0;

            $ha = $a->header();
            $hb = $b->header();

            $fdp = function ($lesson) use ($lesson_slug) {
                return $lesson["slug"] == $lesson_slug;
            };

            // We're assuming the config exists (it should)
            $ma = array_filter($ha->lessons, $fdp)[0];
            $mb = array_filter($hb->lessons, $fdp)[0];

            if (isset($ma['order'])) {
                $la = floor($ma['order']);
            }
            if (isset($mb['order'])) {
                $lb = floor($mb['order']);
            }

            return $la - $lb;
        });

        if (empty($target_pages)) {
            return;
        }

        $this->grav['twig']->twig()->addGlobal('target_pages', $target_pages);
        $this->grav['twig']->twig()->addGlobal('disable_multilingual', true);

        $page = new Page;
        $page->init(new \SplFileInfo(__DIR__ . '/pages/lesson-columns.md'));

        // here: perhaps add a title and other metadata

        $event->page = $page;
        $event->stopPropagation();
    }
}
