<?php

namespace Calio\Extensions;

use Elementor\Controls_Manager;

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

/**
 * Adds a scroll-driven text fill effect to Elementor elements through Advanced controls.
 */
class ScrollFillEffectExtension
{
    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 effect controls under Elementor's motion/effects area.
     *
     * @param object $element Elementor element instance.
     */
    public function register_controls($element): void
    {
        $element->start_controls_section(
            'calio_scroll_fill_effect',
            [
                'label' => esc_html__('Calio Scroll Fill', 'calio-addon'),
                'tab' => Controls_Manager::TAB_ADVANCED,
            ]
        );

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

        $element->add_control(
            'calio_scroll_fill_target_preset',
            [
                'label' => esc_html__('Target Preset', 'calio-addon'),
                'type' => Controls_Manager::SELECT,
                'default' => 'heading',
                'options' => [
                    'heading' => esc_html__('Headings', 'calio-addon'),
                    'text' => esc_html__('Text Blocks', 'calio-addon'),
                    'links' => esc_html__('Links', 'calio-addon'),
                    'custom' => esc_html__('Custom Selector', 'calio-addon'),
                ],
                'condition' => ['calio_scroll_fill_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_scroll_fill_target_mode',
            [
                'label' => esc_html__('Fill Targeting', 'calio-addon'),
                'type' => Controls_Manager::SELECT,
                'default' => 'element',
                'options' => [
                    'element' => esc_html__('Whole Element', 'calio-addon'),
                    'words' => esc_html__('Split Words', 'calio-addon'),
                    'lines' => esc_html__('Split Lines', 'calio-addon'),
                ],
                'condition' => ['calio_scroll_fill_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_scroll_fill_selector',
            [
                'label' => esc_html__('Target Selector', 'calio-addon'),
                'type' => Controls_Manager::TEXT,
                'default' => 'h1, h2, h3, h4, h5, h6, p, span, a',
                'placeholder' => 'h2, p',
                'condition' => ['calio_scroll_fill_enable' => 'yes', 'calio_scroll_fill_target_preset' => 'custom'],
            ]
        );

        $element->add_control(
            'calio_scroll_fill_skin',
            [
                'label' => esc_html__('Fill Skin', 'calio-addon'),
                'type' => Controls_Manager::SELECT,
                'default' => 'solid',
                'options' => [
                    'solid' => esc_html__('Solid', 'calio-addon'),
                    'gradient' => esc_html__('Gradient', 'calio-addon'),
                    'glow' => esc_html__('Glow', 'calio-addon'),
                ],
                'condition' => ['calio_scroll_fill_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_scroll_fill_gradient_preset',
            [
                'label' => esc_html__('Gradient Preset', 'calio-addon'),
                'type' => Controls_Manager::SELECT,
                'default' => 'ocean',
                'options' => [
                    'ocean' => esc_html__('Ocean', 'calio-addon'),
                    'sunset' => esc_html__('Sunset', 'calio-addon'),
                    'mint' => esc_html__('Mint', 'calio-addon'),
                    'custom' => esc_html__('Custom Colors', 'calio-addon'),
                ],
                'condition' => ['calio_scroll_fill_enable' => 'yes', 'calio_scroll_fill_skin' => 'gradient'],
            ]
        );

        $element->add_control(
            'calio_scroll_fill_base_color',
            [
                'label' => esc_html__('Base Color', 'calio-addon'),
                'type' => Controls_Manager::COLOR,
                'default' => '#94a3b8',
                'condition' => ['calio_scroll_fill_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_scroll_fill_fill_color',
            [
                'label' => esc_html__('Fill Color', 'calio-addon'),
                'type' => Controls_Manager::COLOR,
                'default' => '#0f172a',
                'condition' => ['calio_scroll_fill_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_scroll_fill_fill_color_secondary',
            [
                'label' => esc_html__('Secondary Fill Color', 'calio-addon'),
                'type' => Controls_Manager::COLOR,
                'default' => '#38bdf8',
                'condition' => ['calio_scroll_fill_enable' => 'yes', 'calio_scroll_fill_skin' => 'gradient', 'calio_scroll_fill_gradient_preset' => 'custom'],
            ]
        );

        $element->add_control(
            'calio_scroll_fill_direction',
            [
                'label' => esc_html__('Direction', 'calio-addon'),
                'type' => Controls_Manager::SELECT,
                'default' => 'ltr',
                'options' => [
                    'ltr' => esc_html__('Left to Right', 'calio-addon'),
                    'rtl' => esc_html__('Right to Left', 'calio-addon'),
                ],
                'condition' => ['calio_scroll_fill_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_scroll_fill_start',
            [
                'label' => esc_html__('Start Offset', 'calio-addon'),
                'type' => Controls_Manager::SLIDER,
                'size_units' => ['%'],
                'default' => ['unit' => '%', 'size' => 85],
                'range' => ['%' => ['min' => 0, 'max' => 100]],
                'condition' => ['calio_scroll_fill_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_scroll_fill_end',
            [
                'label' => esc_html__('End Offset', 'calio-addon'),
                'type' => Controls_Manager::SLIDER,
                'size_units' => ['%'],
                'default' => ['unit' => '%', 'size' => 20],
                'range' => ['%' => ['min' => 0, 'max' => 100]],
                'condition' => ['calio_scroll_fill_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_scroll_fill_easing',
            [
                'label' => esc_html__('Progress Curve', 'calio-addon'),
                'type' => Controls_Manager::SELECT,
                'default' => 'ease-out',
                'options' => [
                    'linear' => esc_html__('Linear', 'calio-addon'),
                    'ease-in' => esc_html__('Ease In', 'calio-addon'),
                    'ease-out' => esc_html__('Ease Out', 'calio-addon'),
                    'ease-in-out' => esc_html__('Ease In Out', 'calio-addon'),
                ],
                'condition' => ['calio_scroll_fill_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_scroll_fill_timing_preset',
            [
                'label' => esc_html__('Timing Preset', 'calio-addon'),
                'type' => Controls_Manager::SELECT,
                'default' => 'balanced',
                'options' => [
                    'subtle' => esc_html__('Subtle', 'calio-addon'),
                    'balanced' => esc_html__('Balanced', 'calio-addon'),
                    'dramatic' => esc_html__('Dramatic', 'calio-addon'),
                    'custom' => esc_html__('Custom', 'calio-addon'),
                ],
                'condition' => ['calio_scroll_fill_enable' => 'yes'],
            ]
        );

        $element->add_control(
            'calio_scroll_fill_stagger',
            [
                'label' => esc_html__('Stagger', 'calio-addon'),
                'type' => Controls_Manager::SLIDER,
                'size_units' => ['%'],
                'default' => ['unit' => '%', 'size' => 0],
                'range' => ['%' => ['min' => 0, 'max' => 12, 'step' => 1]],
                'condition' => ['calio_scroll_fill_enable' => 'yes', 'calio_scroll_fill_timing_preset' => 'custom'],
            ]
        );

        $element->add_control(
            'calio_scroll_fill_once',
            [
                'label' => esc_html__('Complete Once', 'calio-addon'),
                'type' => Controls_Manager::SWITCHER,
                'return_value' => 'yes',
                'default' => '',
                'condition' => ['calio_scroll_fill_enable' => 'yes'],
            ]
        );

        $element->end_controls_section();
    }

    /**
     * Adds runtime data attributes for the frontend scroll-fill script.
     *
     * @param object $element Elementor element instance.
     */
    public function before_render($element): void
    {
        $settings = $element->get_settings_for_display();
        if (($settings['calio_scroll_fill_enable'] ?? '') !== 'yes') {
            return;
        }

        $start = isset($settings['calio_scroll_fill_start']['size']) ? (float) $settings['calio_scroll_fill_start']['size'] : 85.0;
        $end = isset($settings['calio_scroll_fill_end']['size']) ? (float) $settings['calio_scroll_fill_end']['size'] : 20.0;
        $target_preset = $this->allowlisted_value((string) ($settings['calio_scroll_fill_target_preset'] ?? 'heading'), ['heading', 'text', 'links', 'custom'], 'heading');
        $target_mode = $this->allowlisted_value((string) ($settings['calio_scroll_fill_target_mode'] ?? 'element'), ['element', 'words', 'lines'], 'element');
        $direction = $this->allowlisted_value((string) ($settings['calio_scroll_fill_direction'] ?? 'ltr'), ['ltr', 'rtl'], 'ltr');
        $easing = $this->allowlisted_value((string) ($settings['calio_scroll_fill_easing'] ?? 'ease-out'), ['linear', 'ease-in', 'ease-out', 'ease-in-out'], 'ease-out');
        $timing_preset = $this->allowlisted_value((string) ($settings['calio_scroll_fill_timing_preset'] ?? 'balanced'), ['subtle', 'balanced', 'dramatic', 'custom'], 'balanced');
        $skin = $this->allowlisted_value((string) ($settings['calio_scroll_fill_skin'] ?? 'solid'), ['solid', 'gradient', 'glow'], 'solid');
        $gradient_preset = $this->allowlisted_value((string) ($settings['calio_scroll_fill_gradient_preset'] ?? 'ocean'), ['ocean', 'sunset', 'mint', 'custom'], 'ocean');
        $selector = sanitize_text_field((string) ($settings['calio_scroll_fill_selector'] ?? 'h1, h2, h3, h4, h5, h6, p, span, a'));
        $base_color = $this->sanitize_css_color((string) ($settings['calio_scroll_fill_base_color'] ?? '#94a3b8'), '#94a3b8');
        $fill_color = $this->sanitize_css_color((string) ($settings['calio_scroll_fill_fill_color'] ?? '#0f172a'), '#0f172a');
        $secondary_color = $this->sanitize_css_color((string) ($settings['calio_scroll_fill_fill_color_secondary'] ?? '#38bdf8'), '#38bdf8');

        $element->add_render_attribute(
            '_wrapper',
            [
                'data-calio-scroll-fill' => 'yes',
                'data-calio-scroll-fill-target-preset' => $target_preset,
                'data-calio-scroll-fill-target-mode' => $target_mode,
                'data-calio-scroll-fill-selector' => $selector,
                'data-calio-scroll-fill-direction' => $direction,
                'data-calio-scroll-fill-start' => (string) max(0, min(100, $start)),
                'data-calio-scroll-fill-end' => (string) max(0, min(100, $end)),
                'data-calio-scroll-fill-easing' => $easing,
                'data-calio-scroll-fill-timing-preset' => $timing_preset,
                'data-calio-scroll-fill-stagger' => (string) max(0, min(12, isset($settings['calio_scroll_fill_stagger']['size']) ? (float) $settings['calio_scroll_fill_stagger']['size'] : 0)),
                'data-calio-scroll-fill-skin' => $skin,
                'data-calio-scroll-fill-gradient-preset' => $gradient_preset,
                'data-calio-scroll-fill-once' => (($settings['calio_scroll_fill_once'] ?? '') === 'yes') ? 'yes' : 'no',
                'style' => '--calio-scroll-fill-base:' . $base_color . ';--calio-scroll-fill-fill:' . $fill_color . ';--calio-scroll-fill-fill-secondary:' . $secondary_color . ';',
            ]
        );
    }

    /**
     * Keeps data attributes aligned with declared Elementor select options.
     *
     * @param string   $value    Submitted control value.
     * @param string[] $allowed  Allowed values.
     * @param string   $fallback Fallback value.
     */
    private function allowlisted_value(string $value, array $allowed, string $fallback): string
    {
        $value = sanitize_key($value);

        return in_array($value, $allowed, true) ? $value : $fallback;
    }

    private function sanitize_css_color(string $color, string $fallback): string
    {
        $sanitized = sanitize_hex_color($color);

        return $sanitized ? $sanitized : $fallback;
    }
}
