<?php

namespace YOOtheme\Demo\Routes;

use Joomla\CMS\Factory;
use YOOtheme\Builder;
use YOOtheme\Config;
use YOOtheme\Event;
use YOOtheme\Http\Request;
use YOOtheme\Metadata;
use YOOtheme\Url;
use YOOtheme\View;
use YOOtheme\Demo\Helper;
use function YOOtheme\app;

class Screenshot
{
    public static function match(Request $request)
    {
        return $request->getQueryParam('screenshot');
    }

    public static function handle($demo)
    {
        $dispatcher = Factory::getApplication()->getDispatcher();

        $dispatcher->addListener('onLoad404', function ($event) use ($demo) {
            $demoUrl = Url::base() . "/{$demo['dir']}/../..";
            $outputs = [
                "<script src=\"{$demoUrl}/scripts/screenshot/assets/uikit.js\"></script>",
                "<link href=\"{$demoUrl}/scripts/screenshot/assets/custom.css\" rel=\"stylesheet\">",
            ];

            $event->getArgument(0)->offsetSet('head', implode("\n", $outputs));
        });

        // prevent 404 error on favicon request
        $dispatcher->addListener('onAfterDispatch', function () {
            Factory::getApplication()
                ->getDocument()
                ->addHeadLink('data:', 'icon', 'rel', ['sizes' => 'any']);
        });

        Event::on(
            'theme.head',
            function () use ($demo) {
                $metadata = app(Metadata::class);
                $metadata->set('script:screenshot-uikit', [
                    'src' => "{$demo['dir']}/../../scripts/screenshot/assets/uikit.js",
                ]);
                $metadata->set('style:screenshot-style', [
                    'href' => "{$demo['dir']}/../../scripts/screenshot/assets/custom.css",
                ]);

                $config = app(Config::class);
                $config->set(
                    '~theme.body_class',
                    array_merge($config('~theme.body_class', []), [
                        "screenshot-theme-{$demo['theme']}",
                        "screenshot-style-{$demo['style']}",
                        'screenshot-page-' . str_replace(' ', '-', strtolower($demo['page'])),
                    ])
                );
            },
            -50
        );

        app()->extend(View::class, function (View $view) {
            $view->addLoader(function ($name, $parameters, callable $next) {
                return str_replace('autoplay=1', 'autoplay=0', $next($name, $parameters));
            }, '*/builder/elements/layout/templates/template.php');

            $view->addLoader(function ($name, $parameters, callable $next) {
                $parameters['options']['lazyload'] = false;
                return $next($name, $parameters);
            }, '*/builder/elements/map/templates/template.php');

            $view['html']->addComponent('video', function ($element, array $params = []) {
                if (isset($element->attrs['autoplay'])) {
                    $element->attrs['autoplay'] = false;
                    unset($element->attrs['preload']);
                }
                foreach (['uk-video', 'uk-cover'] as $attr) {
                    if (!empty($element->attrs[$attr])) {
                        $element->attrs[$attr] = 'automute: true;autoplay: false';
                        unset($element->attrs['preload']);
                    }
                }
            });

            $view['html']->addComponent('iframe', function ($element, array $params = []) {
                foreach (['uk-video', 'uk-cover'] as $attr) {
                    if (!empty($element->attrs[$attr])) {
                        $element->attrs[$attr] = 'automute: true;autoplay: false';
                    }
                }
            });
        });

        // Override element props
        if (!empty($demo['screenshot_overrides']['elements'])) {
            $elements = $demo['screenshot_overrides']['elements'];

            app()->extend(Builder::class, function ($builder) use ($elements) {
                $builder->addTransform(
                    'render',
                    function ($node) use ($elements) {
                        foreach ($elements as $element) {
                            if (Helper::matchNode($element['match'], $node)) {
                                $node->props = $element['props'] + $node->props;
                            }
                        }
                    },
                    0
                );
            });
        }

        app()->extend(Builder::class, function (Builder $builder) {
            $builder->addTransform(
                'prerender',
                function ($node, $params) use ($builder) {
                    if (
                        !empty($node->source->query->arguments->order) &&
                        in_array($node->source->query->arguments->order, ['hits', 'rand'])
                    ) {
                        $node->source->query->arguments->order = 'publish_up';
                    }

                    // related articles ordered by hits/random need to be ordered by publish date
                    if (
                        !empty($node->source->query->field->arguments->order) &&
                        in_array($node->source->query->field->arguments->order, ['hits', 'rand'])
                    ) {
                        $node->source->query->field->arguments->order = 'publish_up';
                    }

                    foreach (
                        [
                            'video_lazyload',
                            'video_autoplay',
                            'slideshow_autoplay',
                            'slider_autoplay',
                        ]
                        as $prop
                    ) {
                        if (!empty($node->props[$prop])) {
                            $node->props[$prop] = false;
                        }
                    }
                },
                version_compare(app(Config::class)('theme.version'), '3.1', '<') ? 2 : 0
            );
        });
    }
}
