<?php

namespace Webien\Elementor\Extensions;

use Elementor\Element_Base;
use PHPHtmlParser\Dom;
use PHPHtmlParser\Dom\Node\HtmlNode;
use PHPHtmlParser\Options;

class SectionLinks
{
    function __construct()
    {
        $this->register_hooks();
    }

//-------------------------------------------------------------------//
// Hooks
//-------------------------------------------------------------------//

    private function register_hooks()
    {
        if (is_admin()) {
            add_action( 'elementor/element/before_section_end', [ $this, 'register_controls' ], 10, 2 );
        }

        add_action('elementor/frontend/column/before_render', [$this, 'before_render'], 20, 1); // Use lower prio to not disturb other hooks since we use buffer
        add_action('elementor/frontend/column/after_render', [$this, 'after_render'], 20, 1);

        add_action('elementor/frontend/section/before_render', [$this, 'before_render'], 20, 1);
        add_action('elementor/frontend/section/after_render', [$this, 'after_render'], 20, 1);

        add_action('elementor/frontend/container/before_render', [$this, 'before_render'], 20, 1);
        add_action('elementor/frontend/container/after_render', [$this, 'after_render'], 20, 1);

    }


    public static function before_render(Element_Base $element)
    {
        $settings = $element->get_settings();
        // If the setting for section link is set, buffer output and modify it on the after_render hook
        if(isset($settings['webien_section_link_enable']) && $settings['webien_section_link_enable'] === 'yes'){

            $wrapper = in_array(get_class($element), [
                'Elementor\Element_Section',
                'Elementor\Includes\Elements\Container'
            ]) ? '_wrapper' : '_inner_wrapper';

            $render_arr = [
                'class' => 'webien-section-link',
            ];

            $element->add_render_attribute($wrapper, $render_arr);


            // Start output buffer
            ob_start();
        }
    }


    public static function after_render(Element_Base $element)
    {
        $settings = $element->get_settings();
        $elementId = $element->get_id();

        // If the setting for section link is set, buffer output and modify it on the after_render hook
        if(isset($settings['webien_section_link_enable']) && $settings['webien_section_link_enable'] === 'yes'){

            $content = ob_get_clean();

            $link = [
                'url' => '',
                'target' => '_self'
            ];

            // Check for dynamic value
            if(isset($settings['__dynamic__']['webien_section_link_url'])){


                $name = '/name="(.*?)"/m';
                $setting = '/settings="(.*?)"/m';

                // Get some matches from regex
                preg_match_all($name, $settings['__dynamic__']['webien_section_link_url'], $name_matches, PREG_SET_ORDER, 0);
                preg_match_all($setting, $settings['__dynamic__']['webien_section_link_url'], $setting_matches, PREG_SET_ORDER, 0);


                // Post url
                if($name_matches[0][1] === 'post-url') {
                    $link['url'] = get_permalink(get_the_ID());
                }

                if ($name_matches[0][1] === 'jet-term-field') {
                    if (!empty($setting_matches)) {
                        $obj = json_decode(urldecode($setting_matches[0][1]));

                        if (isset($obj->taxonomy)) {
                            $term = get_queried_object();

                            $termLink = get_term_link($term, $obj->taxonomy);

                            if (is_wp_error($termLink)) {
                                $link['url'] = get_home_url();
                            } else {
                                $link['url'] = $termLink;
                            }
                        }
                    }
                }

                // From ACF URL
                if($name_matches[0][1] === 'acf-url') {
                    if(!empty($setting_matches)) {
                        $obj = json_decode(urldecode($setting_matches[0][1]));
                        if (isset($obj->key)) {
                            $acf = explode(':', $obj->key);
                            if(isset($acf[1])){

                                $val = get_field($acf[1], get_the_ID());
                                // Sometimes this is just the ID number
                                if(is_numeric($val)){
                                    $link['url'] = get_permalink($val);
                                } else {
                                    $link['url'] = $val;
                                }
                            }
                        }
                    }
                }

                // From Custom field
                if($name_matches[0][1] === 'post-custom-field') {
                    if(!empty($setting_matches)){
                        $obj = json_decode(urldecode($setting_matches[0][1]));
                        if(isset($obj->custom_key)){
                            $key = $obj->custom_key;
                            $link['url'] = get_post_meta(get_the_ID(), $key, true);
                        }
                    }
                }
            } else {
                $link['url'] = $settings['webien_section_link_url']['url'] ?? '';
            }


            // If empty dont do anything..
            //var_dump($link);
            if(empty($link['url'])) {
                echo $content;
                return;
            }

            // Check that we have a string link and not an object/array
            if(!is_string($link['url'])){
                // Attachments object
                if(isset($link['url']['url'])){
                    $link['url'] = $link['url']['url'];
                } else {
                    $link['url'] = get_home_url();
                }
            }

            // Replace internal links with span instead
            $content = preg_replace('/<a/is', "<span", $content); // switch start tag
            $content = preg_replace('/href="\'?.*?"/is', "", $content); // remove href attribute
            $content = preg_replace('/<\/a>/is', "</span>", $content); // switch end tag


            // Get all previous attributes that needs to come along on in the new <a> tag
            $wrapper = in_array(get_class($element), [
                'Elementor\Element_Section',
                'Elementor\Includes\Elements\Container'
            ]) ? '_wrapper' : '_inner_wrapper';


            $oldAttributes = $element->get_render_attributes($wrapper);

            // Use html parser to add our links for better control
            // https://github.com/paquettg/php-html-parser
            $dom = new Dom;

            $dom->loadStr($content,
                (new Options())
                    ->setCleanupInput(false) // Disables all sort of script/markup cleanup operations
            );

            $type = $element->get_name();

            // Section/Column/Container ?
            $divIndex = in_array($type, ['section','container']) ? 0:1;

            // Switch tag to a
            $outer = $dom->find('div')[$divIndex];

            if(!$outer){
                return;
            }

            $outerClasses = $outer->getAttribute('class');

            // Filter for adding extra classes to wrapper
            $extraClasses = apply_filters('webien/plugin/section_extra_classes', ['webien-section-link'], $elementId);

            $outerClasses .= ' ' . implode(' ', $extraClasses);

            $outer->setTag('a');

            // Add all prior attributes again
            foreach ($oldAttributes as $key => $val){
                $val = is_array($val) ? implode(' ', $val) : $val;
                $outer->setAttribute($key, $val);

            }

            // Handle Class and href individually
            $outer->setAttribute('class', $outerClasses);
            $outer->setAttribute('href', $link['url']);

            if(isset($settings['webien_section_link_url']['is_external']) && $settings['webien_section_link_url']['is_external']){
                $outer->setAttribute('target', '_blank');
            }

            // Create a hook so that we can insert html from elsewhere if needed
            $externalContent = apply_filters( 'webien/plugin/section_extra_html', '', $elementId);
            if(!empty($externalContent)) {
                $outer->lastChild()->setText($externalContent);
            }

            echo $dom;
        }

    }


    public function register_controls($element, $section_id )
    {

        $sections = [
            'layout',
            'section_layout',
            'section_layout_container',
        ];

        $element_name = $element->get_name();

        if ( ! in_array( $section_id, $sections ) ) {
            return;
        }

        $element->add_control(
            'webien_section_link_enable',
            [
                'label'     => __( 'Sektionslänk' , 'webien' ),
                'type'      => \Elementor\Controls_Manager::SWITCHER,
                'description'   => __( '' ),
                'default'   => 'no',
                'separator' => 'before',
            ]
        );

        $element->add_control(
            'webien_section_link_url',
            [
                'label' => esc_html__( 'Länk', 'webien' ),
                'type' => \Elementor\Controls_Manager::URL,
                'placeholder' => esc_html__( 'https://din-lank.se', 'webien' ),
                'dynamic' => [
                    'active' => true,
                ],
                'condition' => [
                    'webien_section_link_enable' => 'yes',
                ],
            ]

        );

    }

}
