<?php

namespace Engine\Modules\Layouts;

use Elementor\Plugin;
use Elementor\Controls_Stack;
use Elementor\Utils;

class Engine_Import
{
    private $post_id;

    private $layout_type;

    private $predefined_name;

    public function __construct($post_id, $layout_type, $predefined_name)
    {
        $this->post_id = $post_id;
        $this->layout_type = $layout_type;
        $this->predefined_name = $predefined_name;

        $this->run_elementor();
    }

    private function run_elementor()
    {
        add_filter('elementor/files/allow_unfiltered_upload', '__return_true');

        $data = json_decode($this->get_data(), true);

        $data = $this->replace_elements_ids( $data );
        $data = $this->process_export_import_content( $data, 'on_import' );

        $document = Plugin::$instance->documents->get($this->post_id);

        if ($document) {
            $data = $document->get_elements_raw_data($data, true);
        }

        update_post_meta($this->post_id, '_elementor_data', wp_slash(wp_json_encode($data)));
        update_post_meta($this->post_id, '_elementor_edit_mode', 'builder');
        update_post_meta($this->post_id, '_elementor_template_layout_type', 'wp-post');
        update_post_meta($this->post_id, '_elementor_version', '3.6.6');
    }

    protected function replace_elements_ids($content)
    {
        return Plugin::$instance->db->iterate_data($content, function ($element) {
            $element['id'] = Utils::generate_random_string();

            return $element;
        });
    }

    protected function process_export_import_content($content, $method)
    {
        return Plugin::$instance->db->iterate_data(
            $content, function ($element_data) use ($method) {
            $element = Plugin::$instance->elements_manager->create_element_instance($element_data);

            // If the widget/element isn't exist, like a plugin that creates a widget but deactivated
            if (!$element) {
                return null;
            }

            return $this->process_element_export_import_content($element, $method);
        }
        );
    }

    protected function process_element_export_import_content(Controls_Stack $element, $method)
    {
        $element_data = $element->get_data();

        if (method_exists($element, $method)) {
            // TODO: Use the internal element data without parameters.
            $element_data = $element->{$method}($element_data);
        }

        foreach ($element->get_controls() as $control) {
            $control_class = Plugin::$instance->controls_manager->get_control($control['type']);

            // If the control isn't exist, like a plugin that creates the control but deactivated.
            if (!$control_class) {
                return $element_data;
            }

            if (method_exists($control_class, $method)) {
                $element_data['settings'][$control['name']] = $control_class->{$method}($element->get_settings($control['name']), $control);
            }

            // On Export, check if the control has an argument 'export' => false.
            if ('on_export' === $method && isset($control['export']) && false === $control['export']) {
                unset($element_data['settings'][$control['name']]);
            }
        }

        return $element_data;
    }

    public function get_data()
    {
        ob_start();
        include_once STAD_Demo_DIR . '/inc/engine/demo/' . $this->layout_type . '/' . $this->predefined_name . '/data.json';
        return ob_get_clean();
    }
}
