<?php

namespace ElementPack\Modules\SoundEffects;

use Elementor\Controls_Manager;
use ElementPack\Base\Element_Pack_Module_Base;
use Elementor\Modules\DynamicTags\Module as TagsModule;
use ElementPack\Modules\SoundEffects\Atomic\Support as Atomic_Support;
use ElementPack\Modules\SoundEffects\Normalizers\Settings_Normalizer;

if (!defined('ABSPATH')) {
    exit;
} // Exit if accessed directly

class Module extends Element_Pack_Module_Base {
    private $atomic_support = null;
    private $settings_normalizer = null;

    public function __construct() {
        parent::__construct();
        $this->add_actions();
    }

    public function get_name() {
        return 'bdt-sound-effects';
    }

    public function register_section($element) {
        $pro_lock = bdt_get_widget_badge( str_replace( 'bdt-', '', $this->get_name() ) );
        $element->start_controls_section(
            'section_element_pack_sound_effects_controls',
            [
                'tab'   => Controls_Manager::TAB_CONTENT,
                'label' => BDTEP_CP . esc_html__('Sound Effects', 'bdthemes-element-pack') . $pro_lock,
            ]
        );
        $element->end_controls_section();
    }


    public function register_controls($widget, $args) {

        $widget->add_control(
            'ep_sound_effects_active',
            [
                'label'              => esc_html__('Sound Effects', 'bdthemes-element-pack'),
                'type'               => Controls_Manager::SWITCHER,
                'render_type'        => 'template',
                'frontend_available' => true,
            ]
        );

        $widget->add_control(
            'ep_sound_effects_select_type',
            [
                'label'              => esc_html__('Element Type', 'bdthemes-element-pack'),
                'type'               => Controls_Manager::SELECT,
                'options'            => [
                    'widget'     => esc_html__('Widget', 'bdthemes-element-pack'),
                    'anchor_tag' => esc_html__('Widget > Inner Anchor Tags', 'bdthemes-element-pack'),
                    'custom'     => esc_html__('Widget > Custom Selector', 'bdthemes-element-pack'),
                ],
                'default'            => 'widget',
                'render_type'        => 'template',
                'frontend_available' => true,
                'condition'          => [
                    'ep_sound_effects_active' => 'yes',
                ],
            ]
        );

        $widget->add_control(
            'ep_sound_effects_element_selector',
            [
                'label'              => esc_html__('Element Selector', 'bdthemes-element-pack'),
                'type'               => Controls_Manager::TEXT,
                'dynamic'            => [ 'active' => true ],
                'default'            => 'my-header',
                'description'        => esc_html__("By clicking this scroll button, to which section in your page you want to go? Just write that's section ID here such 'my-header'.", 'bdthemes-element-pack'),
                'frontend_available' => true,
                'condition'          => [
                    'ep_sound_effects_active'      => 'yes',
                    'ep_sound_effects_select_type' => 'custom',
                ],
            ]
        );

        $widget->add_control(
            'ep_sound_effects_event',
            [
                'label'              => esc_html__('Event', 'bdthemes-element-pack'),
                'type'               => Controls_Manager::SELECT,
                'options'            => [
                    'hover' => esc_html__('Hover', 'bdthemes-element-pack'),
                    'click' => esc_html__('Click', 'bdthemes-element-pack'),
                ],
                'default'            => 'click',
                'render_type'        => 'template',
                'frontend_available' => true,
                'condition'          => [
                    'ep_sound_effects_active' => 'yes',
                ],
            ]
        );

        $widget->add_control(
            'ep_sound_effects_source',
            [
                'label'              => esc_html__('Source', 'bdthemes-element-pack'),
                'type'               => Controls_Manager::SELECT,
                'default'            => 'bubble',
                'options'            => [
                    'bubble'       => esc_html__('Bubble', 'bdthemes-element-pack'),
                    'button-click' => esc_html__('Button Click', 'bdthemes-element-pack'),
                    'mouse-click'  => esc_html__('Mouse Click', 'bdthemes-element-pack'),
                    'mountain'     => esc_html__('Bell Ring', 'bdthemes-element-pack'),
                    'hosted_url'   => esc_html__('Local Audio (.ogg only)', 'bdthemes-element-pack'),
                ],
                'frontend_available' => true,
                'condition'          => [
                    'ep_sound_effects_active' => 'yes',
                ],
            ]
        );

        $widget->add_control(
            'ep_sound_effects_source_local_link',
            [
                'type'               => Controls_Manager::HIDDEN,
                'default'            => BDTEP_ASSETS_URL . 'sounds/',
                'frontend_available' => true,
                'condition'          => [
                    'ep_sound_effects_active' => 'yes',
                ],
            ]
        );

        $widget->add_control(
            'ep_sound_effects_hosted_url',
            [
                'label'              => esc_html__('Local Audio', 'bdthemes-element-pack'),
                'type'               => Controls_Manager::MEDIA,
                'dynamic'            => [
                    'active'     => true,
                    'categories' => [
                        TagsModule::POST_META_CATEGORY,
                        TagsModule::MEDIA_CATEGORY,
                    ],
                ],
                'media_type'         => 'audio/ogg',
                'default'            => [
                    'url' => BDTEP_ASSETS_URL . 'sounds/mouse-double-click.ogg',
                ],
                'frontend_available' => true,
                'description'        => 'Right now you can use only OGG sound file.',
                'condition'          => [
                    'ep_sound_effects_active' => 'yes',
                    'ep_sound_effects_source' => 'hosted_url'
                ]
            ]
        );

        $widget->add_control(
            'ep_sound_effects_hosted_url_mp3',
            [
                'label'              => esc_html__('Local Audio MP3 (Fallback)', 'bdthemes-element-pack') . BDTEP_NC,
                'type'               => Controls_Manager::MEDIA,
                'dynamic'            => [
                    'active'     => true,
                    'categories' => [
                        TagsModule::POST_META_CATEGORY,
                        TagsModule::MEDIA_CATEGORY,
                    ],
                ],
                'media_type'         => 'audio',
                'frontend_available' => true,
                'description'        => 'Please upload MP3 file for fallback.',
                'condition'          => [
                    'ep_sound_effects_active' => 'yes',
                    'ep_sound_effects_source' => 'hosted_url'
                ]
            ]
        );
    }

    /**
     * Sound effects boot on elementor/frontend/init — load after elementor-frontend.
     */
    public function ensure_frontend_script_deps() {
        $scripts = wp_scripts();

        if ( empty( $scripts->registered['ep-sound-effects'] ) ) {
            return;
        }

        $deps = $scripts->registered['ep-sound-effects']->deps;

        foreach ( [ 'elementor-frontend', 'elementor-frontend-modules' ] as $handle ) {
            if ( wp_script_is( $handle, 'registered' ) && ! in_array( $handle, $deps, true ) ) {
                $deps[] = $handle;
            }
        }

        $scripts->registered['ep-sound-effects']->deps = $deps;
    }

    public function should_script_enqueue($widget) {
        if ( $this->get_settings_normalizer()->normalize( $widget ) ) {
            $this->ensure_frontend_script_deps();
            wp_enqueue_script('ep-sound-effects');
        }
    }

    public function register_atomic_schema( $schema ) {
        return $this->get_atomic_support()->register_schema( $schema );
    }

    public function register_atomic_controls( $controls, $element ) {
        $schema = method_exists( $element, 'get_props_schema' ) ? $element::get_props_schema() : [];

        if ( ! isset( $schema[ Atomic_Support::ACTIVE_KEY ] ) ) {
            return $controls;
        }

        return $this->get_atomic_support()->register_controls( $controls );
    }

    public function render_atomic_sound_effects_wrapper_attr( $widget ) {
        if ( ! method_exists( $widget, 'get_atomic_settings' ) ) {
            return;
        }

        $settings = $this->get_settings_normalizer()->normalize( $widget );

        if ( ! $settings ) {
            return;
        }

        $widget->add_render_attribute( '_wrapper', 'data-ep-sound-effects', wp_json_encode( $settings ) );
    }

    public function inject_atomic_sound_effects_data( $widget_content, $widget ) {
        if ( ! method_exists( $widget, 'get_atomic_settings' ) ) {
            return $widget_content;
        }

        $settings = $this->get_settings_normalizer()->normalize( $widget );

        if ( ! $settings || ! is_string( $widget_content ) || '' === $widget_content ) {
            return $widget_content;
        }

        if ( false !== strpos( $widget_content, 'data-ep-sound-effects=' ) ) {
            return $widget_content;
        }

        $encoded_settings = wp_json_encode( $settings );

        if ( class_exists( '\WP_HTML_Tag_Processor' ) ) {
            $processor = new \WP_HTML_Tag_Processor( $widget_content );

            if ( $processor->next_tag() ) {
                $processor->set_attribute( 'data-ep-sound-effects', $encoded_settings );

                return $processor->get_updated_html();
            }
        }

        return preg_replace(
            '/<([a-zA-Z][^\\s>]*)([^>]*)>/',
            '<$1$2 data-ep-sound-effects="' . $encoded_settings . '">',
            $widget_content,
            1
        ) ?: $widget_content;
    }

    public function maybe_register_atomic_hooks() {
        if ( ! class_exists( '\Elementor\Plugin' ) ) {
            return;
        }

        if ( has_filter( 'elementor/atomic-widgets/props-schema', [ $this, 'register_atomic_schema' ] ) ) {
            return;
        }

        add_filter( 'elementor/atomic-widgets/props-schema', [ $this, 'register_atomic_schema' ], 20 );
        add_filter( 'elementor/atomic-widgets/controls', [ $this, 'register_atomic_controls' ], 30, 2 );
    }

    private function get_atomic_support() {
        if ( null === $this->atomic_support ) {
            $this->atomic_support = new Atomic_Support();
        }

        return $this->atomic_support;
    }

    private function get_settings_normalizer() {
        if ( null === $this->settings_normalizer ) {
            $this->settings_normalizer = new Settings_Normalizer();
        }

        return $this->settings_normalizer;
    }

    protected function add_actions() {
        add_action('elementor/element/common/_section_style/after_section_end', [$this, 'register_section']);
        add_action('elementor/element/common/section_element_pack_sound_effects_controls/before_section_end', [$this, 'register_controls'], 10, 2);

        // render scripts
        add_action( 'elementor/frontend/before_render', [ $this, 'should_script_enqueue' ] );
        add_action( 'elementor/frontend/before_render', [ $this, 'render_atomic_sound_effects_wrapper_attr' ], 15 );
        add_filter( 'elementor/widget/render_content', [ $this, 'inject_atomic_sound_effects_data' ], 10, 2 );
        add_action( 'elementor/frontend/after_register_scripts', [ $this, 'ensure_frontend_script_deps' ] );

        if ( did_action( 'elementor/init' ) ) {
            $this->maybe_register_atomic_hooks();
        } else {
            add_action( 'elementor/init', [ $this, 'maybe_register_atomic_hooks' ] );
        }
    }
}
