<?php

namespace Calio\Extensions;

use Elementor\Controls_Manager;

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Adds lightweight sticky positioning controls to Elementor wrappers.
 */
class StickyContentExtension
{
    public function __construct()
    {
        add_action('elementor/element/common/section_effects/after_section_end', [$this, 'register_controls']);
        add_action('elementor/element/section/section_effects/after_section_end', [$this, 'register_controls']);
        add_action('elementor/element/column/section_effects/after_section_end', [$this, 'register_controls']);
        add_action('elementor/element/container/section_effects/after_section_end', [$this, 'register_controls']);

        add_action('elementor/frontend/widget/before_render', [$this, 'before_render']);
        add_action('elementor/frontend/section/before_render', [$this, 'before_render']);
        add_action('elementor/frontend/column/before_render', [$this, 'before_render']);
        add_action('elementor/frontend/container/before_render', [$this, 'before_render']);
    }

    /**
     * Registers sticky controls in the Advanced tab.
     *
     * @param object $element Elementor element instance.
     */
    public function register_controls($element): void
    {
        $element->start_controls_section(
            'calio_sticky_content',
            [
                'label' => esc_html__('Calio Sticky Content', 'calio-addon'),
                'tab' => Controls_Manager::TAB_ADVANCED,
            ]
        );

        $element->add_control(
            'calio_sticky_enable',
            [
                'label' => esc_html__('Enable Sticky Content', 'calio-addon'),
                'type' => Controls_Manager::SWITCHER,
                'return_value' => 'yes',
                'default' => '',
            ]
        );

        $element->add_control(
            'calio_sticky_notice',
            [
                'type' => Controls_Manager::RAW_HTML,
                'raw' => esc_html__('Sticky content works best when the parent wrapper has enough height and does not clip overflow.', 'calio-addon'),
                'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
                'condition' => ['calio_sticky_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_sticky_top_offset',
            [
                'label' => esc_html__('Top Offset', 'calio-addon'),
                'type' => Controls_Manager::SLIDER,
                'size_units' => ['px'],
                'default' => ['unit' => 'px', 'size' => 24],
                'range' => ['px' => ['min' => 0, 'max' => 240, 'step' => 2]],
                'condition' => ['calio_sticky_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_sticky_bottom_guard',
            [
                'label' => esc_html__('Bottom Guard', 'calio-addon'),
                'type' => Controls_Manager::SLIDER,
                'size_units' => ['px'],
                'default' => ['unit' => 'px', 'size' => 0],
                'range' => ['px' => ['min' => 0, 'max' => 240, 'step' => 2]],
                'condition' => ['calio_sticky_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_sticky_boundary_selector',
            [
                'label' => esc_html__('Boundary Selector', 'calio-addon'),
                'type' => Controls_Manager::TEXT,
                'placeholder' => '.site-main, .elementor-section',
                'description' => esc_html__('Optional ancestor or page selector that should act as the sticky boundary.', 'calio-addon'),
                'condition' => ['calio_sticky_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_sticky_stop_before_selector',
            [
                'label' => esc_html__('Stop Before Selector', 'calio-addon'),
                'type' => Controls_Manager::TEXT,
                'placeholder' => 'footer, .site-footer',
                'description' => esc_html__('Optional page selector that should be respected before the sticky surface reaches it.', 'calio-addon'),
                'condition' => ['calio_sticky_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_sticky_max_width',
            [
                'label' => esc_html__('Keep Natural Width', 'calio-addon'),
                'type' => Controls_Manager::SWITCHER,
                'return_value' => 'yes',
                'default' => 'yes',
                'condition' => ['calio_sticky_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_sticky_z_index',
            [
                'label' => esc_html__('Z-Index', 'calio-addon'),
                'type' => Controls_Manager::NUMBER,
                'default' => 5,
                'min' => 0,
                'max' => 999,
                'condition' => ['calio_sticky_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_sticky_shadow',
            [
                'label' => esc_html__('Sticky Shadow', 'calio-addon'),
                'type' => Controls_Manager::SWITCHER,
                'return_value' => 'yes',
                'default' => '',
                'condition' => ['calio_sticky_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_sticky_active_state',
            [
                'label' => esc_html__('Highlight When Sticky', 'calio-addon'),
                'type' => Controls_Manager::SWITCHER,
                'return_value' => 'yes',
                'default' => 'yes',
                'condition' => ['calio_sticky_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_sticky_active_bg',
            [
                'label' => esc_html__('Active Background', 'calio-addon'),
                'type' => Controls_Manager::COLOR,
                'condition' => [
                    'calio_sticky_enable' => 'yes',
                    'calio_sticky_active_state' => 'yes',
                ],
            ]
        );

        $element->add_control(
            'calio_sticky_active_border_color',
            [
                'label' => esc_html__('Active Border Color', 'calio-addon'),
                'type' => Controls_Manager::COLOR,
                'condition' => [
                    'calio_sticky_enable' => 'yes',
                    'calio_sticky_active_state' => 'yes',
                ],
            ]
        );

        $element->add_control(
            'calio_sticky_active_border_width',
            [
                'label' => esc_html__('Active Border Width', 'calio-addon'),
                'type' => Controls_Manager::SLIDER,
                'size_units' => ['px'],
                'default' => ['unit' => 'px', 'size' => 0],
                'range' => ['px' => ['min' => 0, 'max' => 6, 'step' => 1]],
                'condition' => [
                    'calio_sticky_enable' => 'yes',
                    'calio_sticky_active_state' => 'yes',
                ],
            ]
        );

        $element->add_control(
            'calio_sticky_active_shadow_color',
            [
                'label' => esc_html__('Active Shadow Color', 'calio-addon'),
                'type' => Controls_Manager::COLOR,
                'condition' => [
                    'calio_sticky_enable' => 'yes',
                    'calio_sticky_shadow' => 'yes',
                ],
            ]
        );

        $element->add_control(
            'calio_sticky_active_shadow_blur',
            [
                'label' => esc_html__('Active Shadow Blur', 'calio-addon'),
                'type' => Controls_Manager::SLIDER,
                'size_units' => ['px'],
                'default' => ['unit' => 'px', 'size' => 40],
                'range' => ['px' => ['min' => 0, 'max' => 80, 'step' => 2]],
                'condition' => [
                    'calio_sticky_enable' => 'yes',
                    'calio_sticky_shadow' => 'yes',
                ],
            ]
        );

        $element->add_control(
            'calio_sticky_active_lift',
            [
                'label' => esc_html__('Active Lift', 'calio-addon'),
                'type' => Controls_Manager::SLIDER,
                'size_units' => ['px'],
                'default' => ['unit' => 'px', 'size' => 2],
                'range' => ['px' => ['min' => 0, 'max' => 16, 'step' => 1]],
                'condition' => [
                    'calio_sticky_enable' => 'yes',
                    'calio_sticky_active_state' => 'yes',
                ],
            ]
        );

        $element->add_control(
            'calio_sticky_overflow_safe',
            [
                'label' => esc_html__('Disable Inside Overflow Parents', 'calio-addon'),
                'type' => Controls_Manager::SWITCHER,
                'return_value' => 'yes',
                'default' => 'yes',
                'condition' => ['calio_sticky_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_sticky_android',
            [
                'label' => esc_html__('Enable On Android', 'calio-addon'),
                'type' => Controls_Manager::SWITCHER,
                'return_value' => 'yes',
                'default' => '',
                'condition' => ['calio_sticky_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_sticky_ios',
            [
                'label' => esc_html__('Enable On iOS', 'calio-addon'),
                'type' => Controls_Manager::SWITCHER,
                'return_value' => 'yes',
                'default' => '',
                'condition' => ['calio_sticky_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_sticky_tablet',
            [
                'label' => esc_html__('Enable On Tablet', 'calio-addon'),
                'type' => Controls_Manager::SWITCHER,
                'return_value' => 'yes',
                'default' => '',
                'condition' => ['calio_sticky_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_sticky_desktop',
            [
                'label' => esc_html__('Enable On Desktop', 'calio-addon'),
                'type' => Controls_Manager::SWITCHER,
                'return_value' => 'yes',
                'default' => 'yes',
                'condition' => ['calio_sticky_enable' => 'yes'],
            ]
        );

        $element->end_controls_section();
    }

    /**
     * Adds sticky runtime attributes on render.
     *
     * @param object $element Elementor element instance.
     */
    public function before_render($element): void
    {
        $settings = $element->get_settings_for_display();
        if (($settings['calio_sticky_enable'] ?? '') !== 'yes') {
            return;
        }

        $top_offset = isset($settings['calio_sticky_top_offset']['size']) ? (int) $settings['calio_sticky_top_offset']['size'] : 24;
        $bottom_guard = isset($settings['calio_sticky_bottom_guard']['size']) ? (int) $settings['calio_sticky_bottom_guard']['size'] : 0;
        $z_index = isset($settings['calio_sticky_z_index']) ? (int) $settings['calio_sticky_z_index'] : 5;
        $shadow_blur = isset($settings['calio_sticky_active_shadow_blur']['size']) ? (int) $settings['calio_sticky_active_shadow_blur']['size'] : 40;
        $border_width = isset($settings['calio_sticky_active_border_width']['size']) ? (int) $settings['calio_sticky_active_border_width']['size'] : 0;
        $lift = isset($settings['calio_sticky_active_lift']['size']) ? (int) $settings['calio_sticky_active_lift']['size'] : 2;
        $active_bg = $this->sanitize_optional_hex_color((string) ($settings['calio_sticky_active_bg'] ?? ''));
        $active_border_color = $this->sanitize_optional_hex_color((string) ($settings['calio_sticky_active_border_color'] ?? ''));
        $active_shadow_color = $this->sanitize_optional_hex_color((string) ($settings['calio_sticky_active_shadow_color'] ?? ''));
        $inline_styles = [
            '--calio-sticky-active-border-width: ' . max(0, min(6, $border_width)) . 'px;',
            '--calio-sticky-active-lift: ' . max(0, min(16, $lift)) . 'px;',
            '--calio-sticky-shadow-blur: ' . max(0, min(80, $shadow_blur)) . 'px;',
            '--calio-sticky-bottom-guard: ' . max(0, min(240, $bottom_guard)) . 'px;',
        ];

        if ($active_bg !== '') {
            $inline_styles[] = '--calio-sticky-active-bg: ' . $active_bg . ';';
        }

        if ($active_border_color !== '') {
            $inline_styles[] = '--calio-sticky-active-border-color: ' . $active_border_color . ';';
        }

        if ($active_shadow_color !== '') {
            $inline_styles[] = '--calio-sticky-shadow-color: ' . $active_shadow_color . ';';
        }

        $element->add_render_attribute(
            '_wrapper',
            [
                'data-calio-sticky-content' => 'yes',
                'data-calio-sticky-top' => (string) max(0, min(240, $top_offset)),
                'data-calio-sticky-width' => (($settings['calio_sticky_max_width'] ?? 'yes') === 'yes') ? 'natural' : 'stretch',
                'data-calio-sticky-z' => (string) max(0, min(999, $z_index)),
                'data-calio-sticky-shadow' => (($settings['calio_sticky_shadow'] ?? '') === 'yes') ? 'yes' : 'no',
                'data-calio-sticky-active-state' => (($settings['calio_sticky_active_state'] ?? 'yes') === 'yes') ? 'yes' : 'no',
                'data-calio-sticky-overflow-safe' => (($settings['calio_sticky_overflow_safe'] ?? 'yes') === 'yes') ? 'yes' : 'no',
                'data-calio-sticky-boundary' => sanitize_text_field((string) ($settings['calio_sticky_boundary_selector'] ?? '')),
                'data-calio-sticky-stop-before' => sanitize_text_field((string) ($settings['calio_sticky_stop_before_selector'] ?? '')),
                'data-calio-sticky-android' => (($settings['calio_sticky_android'] ?? '') === 'yes') ? 'yes' : 'no',
                'data-calio-sticky-ios' => (($settings['calio_sticky_ios'] ?? '') === 'yes') ? 'yes' : 'no',
                'data-calio-sticky-tablet' => (($settings['calio_sticky_tablet'] ?? '') === 'yes') ? 'yes' : 'no',
                'data-calio-sticky-desktop' => (($settings['calio_sticky_desktop'] ?? 'yes') === 'yes') ? 'yes' : 'no',
                'style' => implode(' ', $inline_styles),
            ]
        );
    }

    private function sanitize_optional_hex_color(string $color): string
    {
        $color = sanitize_hex_color($color);

        return $color ? $color : '';
    }
}
