<?php
/**
 * Plugin Name: BW Animate Row
 * Plugin URI: https://bowdenworks.com
 * Description: Apply global scroll animations to Kadence rows and sections. Configure animation settings from Settings -> BW Animation Config.
 * Version: 1.0.0
 * Author: Bowden Works
 * Author URI: https://bowdenworks.com
 * License: GPL v2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain: bw-animate-row
 */

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

class BW_Animate_Row {

    /**
     * Plugin instance
     */
    private static $instance = null;

    /**
     * Default settings
     */
    private $defaults = array(
        'bw_animation_enabled'  => '1',
        'bw_animation_type'     => 'fade-up',
        'bw_animation_duration' => '1000',
        'bw_animation_easing'   => 'ease-in-out',
        'bw_animation_delay'    => '0',
        'bw_animation_offset'   => '100',
        'bw_animation_once'     => '1',
        'bw_target_rows'        => '1',
        'bw_target_columns'     => '1',
        'bw_target_sections'    => '1',
    );

    /**
     * Get instance
     */
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Constructor
     */
    private function __construct() {
        add_action('admin_menu', array($this, 'bw_add_settings_page'));
        add_action('admin_init', array($this, 'bw_register_settings'));
        add_action('wp_enqueue_scripts', array($this, 'bw_enqueue_scripts'));
        add_action('wp_footer', array($this, 'bw_output_animation_script'), 99);
    }

    /**
     * Add settings page under Settings menu
     */
    public function bw_add_settings_page() {
        add_options_page(
            __('BW Animation Config', 'bw-animate-row'),
            __('BW Animation Config', 'bw-animate-row'),
            'manage_options',
            'bw-animation-config',
            array($this, 'bw_render_settings_page')
        );
    }

    /**
     * Register settings
     */
    public function bw_register_settings() {
        // Register setting group
        register_setting('bw_animation_settings', 'bw_animation_enabled', array(
            'type' => 'string',
            'sanitize_callback' => 'sanitize_text_field',
            'default' => '1'
        ));
        register_setting('bw_animation_settings', 'bw_animation_type', array(
            'type' => 'string',
            'sanitize_callback' => 'sanitize_text_field',
            'default' => 'fade-up'
        ));
        register_setting('bw_animation_settings', 'bw_animation_duration', array(
            'type' => 'string',
            'sanitize_callback' => 'absint',
            'default' => '1000'
        ));
        register_setting('bw_animation_settings', 'bw_animation_easing', array(
            'type' => 'string',
            'sanitize_callback' => 'sanitize_text_field',
            'default' => 'ease-in-out'
        ));
        register_setting('bw_animation_settings', 'bw_animation_delay', array(
            'type' => 'string',
            'sanitize_callback' => 'absint',
            'default' => '0'
        ));
        register_setting('bw_animation_settings', 'bw_animation_offset', array(
            'type' => 'string',
            'sanitize_callback' => 'absint',
            'default' => '100'
        ));
        register_setting('bw_animation_settings', 'bw_animation_once', array(
            'type' => 'string',
            'sanitize_callback' => 'sanitize_text_field',
            'default' => '1'
        ));
        register_setting('bw_animation_settings', 'bw_target_rows', array(
            'type' => 'string',
            'sanitize_callback' => 'sanitize_text_field',
            'default' => '1'
        ));
        register_setting('bw_animation_settings', 'bw_target_columns', array(
            'type' => 'string',
            'sanitize_callback' => 'sanitize_text_field',
            'default' => '1'
        ));
        register_setting('bw_animation_settings', 'bw_target_sections', array(
            'type' => 'string',
            'sanitize_callback' => 'sanitize_text_field',
            'default' => '1'
        ));

        // Add settings section
        add_settings_section(
            'bw_animation_main_section',
            __('Global Animation Settings', 'bw-animate-row'),
            array($this, 'bw_section_description'),
            'bw-animation-config'
        );

        // Add settings fields
        add_settings_field(
            'bw_animation_enabled',
            __('Enable Animations', 'bw-animate-row'),
            array($this, 'bw_render_enabled_field'),
            'bw-animation-config',
            'bw_animation_main_section'
        );

        add_settings_field(
            'bw_animation_type',
            __('Animation Type', 'bw-animate-row'),
            array($this, 'bw_render_type_field'),
            'bw-animation-config',
            'bw_animation_main_section'
        );

        add_settings_field(
            'bw_animation_duration',
            __('Animation Duration (ms)', 'bw-animate-row'),
            array($this, 'bw_render_duration_field'),
            'bw-animation-config',
            'bw_animation_main_section'
        );

        add_settings_field(
            'bw_animation_easing',
            __('Animation Easing', 'bw-animate-row'),
            array($this, 'bw_render_easing_field'),
            'bw-animation-config',
            'bw_animation_main_section'
        );

        add_settings_field(
            'bw_animation_delay',
            __('Animation Delay (ms)', 'bw-animate-row'),
            array($this, 'bw_render_delay_field'),
            'bw-animation-config',
            'bw_animation_main_section'
        );

        add_settings_field(
            'bw_animation_offset',
            __('Trigger Offset (px)', 'bw-animate-row'),
            array($this, 'bw_render_offset_field'),
            'bw-animation-config',
            'bw_animation_main_section'
        );

        add_settings_field(
            'bw_animation_once',
            __('Animate Once', 'bw-animate-row'),
            array($this, 'bw_render_once_field'),
            'bw-animation-config',
            'bw_animation_main_section'
        );

        // Target elements section
        add_settings_section(
            'bw_animation_targets_section',
            __('Target Elements', 'bw-animate-row'),
            array($this, 'bw_targets_section_description'),
            'bw-animation-config'
        );

        add_settings_field(
            'bw_target_rows',
            __('Kadence Rows', 'bw-animate-row'),
            array($this, 'bw_render_target_rows_field'),
            'bw-animation-config',
            'bw_animation_targets_section'
        );

        add_settings_field(
            'bw_target_columns',
            __('Kadence Columns', 'bw-animate-row'),
            array($this, 'bw_render_target_columns_field'),
            'bw-animation-config',
            'bw_animation_targets_section'
        );

        add_settings_field(
            'bw_target_sections',
            __('Kadence Sections', 'bw-animate-row'),
            array($this, 'bw_render_target_sections_field'),
            'bw-animation-config',
            'bw_animation_targets_section'
        );
    }

    /**
     * Section description
     */
    public function bw_section_description() {
        echo '<p>' . esc_html__('Configure global animation settings for Kadence rows and sections. These settings will apply to all targeted elements that don\'t have their own animation configured.', 'bw-animate-row') . '</p>';
    }

    /**
     * Targets section description
     */
    public function bw_targets_section_description() {
        echo '<p>' . esc_html__('Select which Kadence elements should receive the global animation.', 'bw-animate-row') . '</p>';
    }

    /**
     * Get option with default
     */
    private function bw_get_option($key) {
        $value = get_option($key);
        if ($value === false && isset($this->defaults[$key])) {
            return $this->defaults[$key];
        }
        return $value;
    }

    /**
     * Render enabled field
     */
    public function bw_render_enabled_field() {
        $value = $this->bw_get_option('bw_animation_enabled');
        echo '<label><input type="checkbox" name="bw_animation_enabled" value="1" ' . checked($value, '1', false) . ' /> ' . esc_html__('Enable global animations', 'bw-animate-row') . '</label>';
    }

    /**
     * Render animation type field
     */
    public function bw_render_type_field() {
        $value = $this->bw_get_option('bw_animation_type');
        $types = array(
            'fade' => 'Fade',
            'fade-up' => 'Fade Up',
            'fade-down' => 'Fade Down',
            'fade-left' => 'Fade Left',
            'fade-right' => 'Fade Right',
            'fade-up-right' => 'Fade Up Right',
            'fade-up-left' => 'Fade Up Left',
            'fade-down-right' => 'Fade Down Right',
            'fade-down-left' => 'Fade Down Left',
            'flip-up' => 'Flip Up',
            'flip-down' => 'Flip Down',
            'flip-left' => 'Flip Left',
            'flip-right' => 'Flip Right',
            'slide-up' => 'Slide Up',
            'slide-down' => 'Slide Down',
            'slide-left' => 'Slide Left',
            'slide-right' => 'Slide Right',
            'zoom-in' => 'Zoom In',
            'zoom-in-up' => 'Zoom In Up',
            'zoom-in-down' => 'Zoom In Down',
            'zoom-in-left' => 'Zoom In Left',
            'zoom-in-right' => 'Zoom In Right',
            'zoom-out' => 'Zoom Out',
            'zoom-out-up' => 'Zoom Out Up',
            'zoom-out-down' => 'Zoom Out Down',
            'zoom-out-left' => 'Zoom Out Left',
            'zoom-out-right' => 'Zoom Out Right',
        );

        echo '<select name="bw_animation_type">';
        foreach ($types as $key => $label) {
            echo '<option value="' . esc_attr($key) . '" ' . selected($value, $key, false) . '>' . esc_html($label) . '</option>';
        }
        echo '</select>';
    }

    /**
     * Render duration field
     */
    public function bw_render_duration_field() {
        $value = $this->bw_get_option('bw_animation_duration');
        echo '<input type="number" name="bw_animation_duration" value="' . esc_attr($value) . '" min="0" max="5000" step="50" /> <span class="description">' . esc_html__('Animation duration in milliseconds (e.g., 1000 = 1 second)', 'bw-animate-row') . '</span>';
    }

    /**
     * Render easing field
     */
    public function bw_render_easing_field() {
        $value = $this->bw_get_option('bw_animation_easing');
        $easings = array(
            'linear' => 'Linear',
            'ease' => 'Ease',
            'ease-in' => 'Ease In',
            'ease-out' => 'Ease Out',
            'ease-in-out' => 'Ease In Out',
            'ease-in-back' => 'Ease In Back',
            'ease-out-back' => 'Ease Out Back',
            'ease-in-out-back' => 'Ease In Out Back',
            'ease-in-sine' => 'Ease In Sine',
            'ease-out-sine' => 'Ease Out Sine',
            'ease-in-out-sine' => 'Ease In Out Sine',
            'ease-in-quad' => 'Ease In Quad',
            'ease-out-quad' => 'Ease Out Quad',
            'ease-in-out-quad' => 'Ease In Out Quad',
            'ease-in-cubic' => 'Ease In Cubic',
            'ease-out-cubic' => 'Ease Out Cubic',
            'ease-in-out-cubic' => 'Ease In Out Cubic',
        );

        echo '<select name="bw_animation_easing">';
        foreach ($easings as $key => $label) {
            echo '<option value="' . esc_attr($key) . '" ' . selected($value, $key, false) . '>' . esc_html($label) . '</option>';
        }
        echo '</select>';
    }

    /**
     * Render delay field
     */
    public function bw_render_delay_field() {
        $value = $this->bw_get_option('bw_animation_delay');
        echo '<input type="number" name="bw_animation_delay" value="' . esc_attr($value) . '" min="0" max="3000" step="50" /> <span class="description">' . esc_html__('Delay before animation starts (ms)', 'bw-animate-row') . '</span>';
    }

    /**
     * Render offset field
     */
    public function bw_render_offset_field() {
        $value = $this->bw_get_option('bw_animation_offset');
        echo '<input type="number" name="bw_animation_offset" value="' . esc_attr($value) . '" min="0" max="500" step="10" /> <span class="description">' . esc_html__('Offset from viewport bottom to trigger animation', 'bw-animate-row') . '</span>';
    }

    /**
     * Render once field
     */
    public function bw_render_once_field() {
        $value = $this->bw_get_option('bw_animation_once');
        echo '<label><input type="checkbox" name="bw_animation_once" value="1" ' . checked($value, '1', false) . ' /> ' . esc_html__('Only animate elements once (won\'t re-animate when scrolling back)', 'bw-animate-row') . '</label>';
    }

    /**
     * Render target rows field
     */
    public function bw_render_target_rows_field() {
        $value = $this->bw_get_option('bw_target_rows');
        echo '<label><input type="checkbox" name="bw_target_rows" value="1" ' . checked($value, '1', false) . ' /> ' . esc_html__('Apply animation to Kadence Row Layout blocks', 'bw-animate-row') . '</label>';
    }

    /**
     * Render target columns field
     */
    public function bw_render_target_columns_field() {
        $value = $this->bw_get_option('bw_target_columns');
        echo '<label><input type="checkbox" name="bw_target_columns" value="1" ' . checked($value, '1', false) . ' /> ' . esc_html__('Apply animation to Kadence Column blocks (top-level only)', 'bw-animate-row') . '</label>';
    }

    /**
     * Render target sections field
     */
    public function bw_render_target_sections_field() {
        $value = $this->bw_get_option('bw_target_sections');
        echo '<label><input type="checkbox" name="bw_target_sections" value="1" ' . checked($value, '1', false) . ' /> ' . esc_html__('Apply animation to Kadence Section blocks', 'bw-animate-row') . '</label>';
    }

    /**
     * Render settings page
     */
    public function bw_render_settings_page() {
        if (!current_user_can('manage_options')) {
            return;
        }
        ?>
        <div class="wrap">
            <h1><?php echo esc_html(get_admin_page_title()); ?></h1>

            <form action="options.php" method="post">
                <?php
                settings_fields('bw_animation_settings');
                do_settings_sections('bw-animation-config');
                submit_button(__('Save Settings', 'bw-animate-row'));
                ?>
            </form>

            <hr />

            <h2><?php esc_html_e('Preview', 'bw-animate-row'); ?></h2>
            <p><?php esc_html_e('Save settings and visit your site to see the animations in action.', 'bw-animate-row'); ?></p>

            <h2><?php esc_html_e('How It Works', 'bw-animate-row'); ?></h2>
            <ul style="list-style: disc; padding-left: 20px;">
                <li><?php esc_html_e('This plugin uses the AOS (Animate On Scroll) library to add scroll-triggered animations.', 'bw-animate-row'); ?></li>
                <li><?php esc_html_e('Animations are applied to Kadence blocks that don\'t already have their own animation configured.', 'bw-animate-row'); ?></li>
                <li><?php esc_html_e('Elements with existing data-aos attributes will keep their original animation.', 'bw-animate-row'); ?></li>
            </ul>
        </div>
        <?php
    }

    /**
     * Enqueue AOS library
     */
    public function bw_enqueue_scripts() {
        $enabled = $this->bw_get_option('bw_animation_enabled');

        if ($enabled !== '1') {
            return;
        }

        // Enqueue AOS CSS
        wp_enqueue_style(
            'bw-aos',
            'https://unpkg.com/aos@2.3.4/dist/aos.css',
            array(),
            '2.3.4'
        );

        // Enqueue AOS JS
        wp_enqueue_script(
            'bw-aos',
            'https://unpkg.com/aos@2.3.4/dist/aos.js',
            array(),
            '2.3.4',
            true
        );
    }

    /**
     * Output animation initialization script
     */
    public function bw_output_animation_script() {
        $enabled = $this->bw_get_option('bw_animation_enabled');

        if ($enabled !== '1') {
            return;
        }

        $animation_type = $this->bw_get_option('bw_animation_type');
        $duration = $this->bw_get_option('bw_animation_duration');
        $easing = $this->bw_get_option('bw_animation_easing');
        $delay = $this->bw_get_option('bw_animation_delay');
        $offset = $this->bw_get_option('bw_animation_offset');
        $once = $this->bw_get_option('bw_animation_once') === '1';

        $target_rows = $this->bw_get_option('bw_target_rows') === '1';
        $target_columns = $this->bw_get_option('bw_target_columns') === '1';
        $target_sections = $this->bw_get_option('bw_target_sections') === '1';

        // Build selectors array
        $selectors = array();
        if ($target_rows) {
            $selectors[] = '.wp-block-kadence-rowlayout';
        }
        if ($target_columns) {
            // Target direct child columns of row layouts only (not nested)
            $selectors[] = '.wp-block-kadence-rowlayout > .kt-row-layout-inner > .wp-block-kadence-column';
        }
        if ($target_sections) {
            $selectors[] = '.wp-block-kadence-section';
        }

        if (empty($selectors)) {
            return;
        }

        $selector_string = implode(', ', $selectors);
        ?>
        <script type="text/javascript">
        (function() {
            'use strict';

            var bwAnimationConfig = {
                type: <?php echo wp_json_encode($animation_type); ?>,
                duration: <?php echo intval($duration); ?>,
                easing: <?php echo wp_json_encode($easing); ?>,
                delay: <?php echo intval($delay); ?>,
                offset: <?php echo intval($offset); ?>,
                once: <?php echo $once ? 'true' : 'false'; ?>
            };

            function bwApplyAnimations() {
                var elements = document.querySelectorAll(<?php echo wp_json_encode($selector_string); ?>);

                elements.forEach(function(el) {
                    // Skip if already has AOS animation
                    if (el.hasAttribute('data-aos')) {
                        return;
                    }

                    // Skip nested columns (check if parent is also a column)
                    if (el.classList.contains('wp-block-kadence-column')) {
                        var parent = el.closest('.wp-block-kadence-column');
                        if (parent && parent !== el) {
                            return; // This is a nested column, skip it
                        }
                    }

                    // Apply animation attributes
                    el.setAttribute('data-aos', bwAnimationConfig.type);
                    el.setAttribute('data-aos-duration', bwAnimationConfig.duration);
                    el.setAttribute('data-aos-easing', bwAnimationConfig.easing);

                    if (bwAnimationConfig.delay > 0) {
                        el.setAttribute('data-aos-delay', bwAnimationConfig.delay);
                    }

                    if (bwAnimationConfig.once) {
                        el.setAttribute('data-aos-once', 'true');
                    }
                });
            }

            // Apply animations when DOM is ready
            if (document.readyState === 'loading') {
                document.addEventListener('DOMContentLoaded', function() {
                    bwApplyAnimations();
                    // Initialize AOS
                    if (typeof AOS !== 'undefined') {
                        AOS.init({
                            offset: bwAnimationConfig.offset,
                            once: bwAnimationConfig.once
                        });
                    }
                });
            } else {
                bwApplyAnimations();
                // Initialize AOS
                if (typeof AOS !== 'undefined') {
                    AOS.init({
                        offset: bwAnimationConfig.offset,
                        once: bwAnimationConfig.once
                    });
                }
            }
        })();
        </script>
        <?php
    }
}

// Initialize the plugin
BW_Animate_Row::get_instance();
