<?php
/**
 * @package   Essentials YOOtheme Pro 2.2.16 build 0813.1608
 * @author    ZOOlanders https://www.zoolanders.com
 * @copyright Copyright (C) Joolanders, SL
 * @license   http://www.gnu.org/licenses/gpl.html GNU/GPL
 */

namespace ZOOlanders\YOOessentials\Source;

use YOOtheme\Str;

class QueryArgsTransform
{
    private string $prefix;

    private array $args;

    public function __construct(string $prefix, array $args = ['filters', 'ordering'])
    {
        $this->prefix = $prefix;
        $this->args = $args;
    }

    /**
     * Render callback.
     *
     * @param object $node
     * @param array $params
     */
    public function __invoke($node, array $params = [])
    {
        if ($params['context'] !== 'render') {
            return;
        }

        // resolve node query args
        $this->resolveQueryArgs($node->source->query ?? null);

        // resolve props query args
        $this->resolvePropsArgs((array) ($node->source_extended->props ?? []));
    }

    protected function resolvePropsArgs(array $props)
    {
        foreach ($props ?? [] as $prop) {
            if (isset($prop->composed->sources)) {
                foreach ($prop->composed->sources as $composedProp) {
                    $this->resolveQueryArgs($composedProp->query ?? null);
                }

                continue;
            }

            $this->resolveQueryArgs($prop->query ?? null);
        }
    }

    public function resolveQueryArgs(?object $query)
    {
        $queryName = $query->name ?? '';

        if (!Str::startsWith($queryName, $this->prefix)) {
            return;
        }

        foreach ($this->args as $arg) {
            foreach ($query->arguments->{$arg} ?? [] as &$condition) {
                $metaProperties = array_filter(array_keys(get_object_vars($condition->props)), fn (string $property) => stripos($property, '_') === 0);
                foreach ($metaProperties as $property) {
                    unset($condition->props->{$property});
                }

                if (isset($condition->source_extended)) {
                    $condition->source = json_encode($condition->source_extended);
                    unset($condition->source_extended);
                }
            }
        }
    }
}
